SSRF漏洞的攻击与防御

SSRF的成因看具体的后端实现TCP请求的库:
比如curl、php里的file_get_contents、fsockopen、Java里的openStream,HttpClient类,URLConnection等
https://drops.org.cn/PENETRATION/SSRF-Gopher-Attack-NoteBook.html
发起请求的库不同,决定了可以发起什么样类型的请求。

orange发现的Github Enterprise的SSRF到RCE

试用地址:
https://enterprise.github.com/trial

利用在linux下0代表localhost的特性,

http://0/

攻击本地的Elasticsearch服务,关闭导致其拒绝服务。

curl http://0:9200/_shutdown/

在这里插入图片描述

然后找到了一个8000端口的Graphite服务,有一个直接信任用户提供的url然后访问的特性,利用这一点将之前的POST的SSRF转换成了GET型的SSRF。
然后又通过审计Graphite的代码发现其使用了httplib.HTTPConnection来获取web资源,然后找到了这个功能的CR-LF注入。

然后现在的poc长这样:

http://0:8000/composer/send_email?
to=orange@nogg&
url=http://127.0.0.1:12345/%0D%0Ai_am_payload%0D%0AFoo:

然后实际发起的TCP请求是这样的:

GET /
i_am_payload
Foo: HTTP/1.1
Host: 127.0.0.1:12345
Accept-Encoding: identity

通过这个CR-LF注入,我们可以在普通的HTTP协议中走私其他TCP请求了!

最后利用了Memcached协议注入了一个序列化后的对象,等待Memcached进行反序列化执行任意命令!
总结来说就是:
在这里插入图片描述
在poc的url里体现就是:
在这里插入图片描述
Github的防御措施。这里的几个步骤都有防御,但是我学习到的是通过iptables防火墙过滤掉某种webhook的UA:

User-Agent: GitHub-Hookshot

演示视频:
https://www.youtube.com/watch?v=GoO7_lCOfic

利用gopher发起任意TCP请求(依赖curl)

gopher://127.0.0.1:70/_ + TCP/IP数据

默认是70端口,可以指定为其他端口
在这里插入图片描述
在这里插入图片描述

可以攻击Redis、抓包改包之后可以攻击mysql。

利用GoPher协议进行内网Redis和mysql的未授权操作(在服务端设置了未授权访问的情况下)

在这里插入图片描述

SSRF可以结合DNS重绑定
http://www.bendawang.site/2017/05/31/%E5%85%B3%E4%BA%8EDNS-rebinding%E7%9A%84%E6%80%BB%E7%BB%93/

对Redis进行DoS:

curl -v gopher://127.0.0.1:6379/_FLUSHALL --max-time 1

通过向Redis持续发送flushall命令,让它不能存储数据。

利用Gopher进行SSRF的局限性以及利用方式:
主要是利用发一次任意基于TCP协议的请求,进行利用,不能交互。
依赖后端实现TCP请求的库;
可能不支持302跳转;
可能不支持URLencode;

在这里插入图片描述

参考:

https://maxchadwick.xyz/blog/ssrf-exploits-against-redis
https://xz.aliyun.com/t/5844
https://drops.org.cn/PENETRATION/SSRF-Gopher-Attack-NoteBook.html
https://blog.szfszf.top/tech/%E5%88%A9%E7%94%A8gopher%E5%8D%8F%E8%AE%AE%E6%94%BB%E5%87%BB%E7%94%9F%E6%88%90gopher%E5%8D%8F%E8%AE%AEpayload/
https://k-ring.github.io/2019/05/31/%E5%AF%B9%E4%B8%87%E9%87%91%E6%B2%B9gopher%E5%8D%8F%E8%AE%AE%E7%9A%84%E7%90%86%E8%A7%A3%E4%B8%8E%E5%BA%94%E7%94%A8/
https://blog.chaitin.cn/gopher-attack-surfaces/
https://en.wikipedia.org/wiki/Gopher_(protocol)

攻防

使用java.net.URI#getHost,getPort等方法拿到实际要访问的host和port,若是内网IP或者域名,则禁止访问。
在这里插入图片描述

参考:

  • https://www.leavesongs.com/PYTHON/defend-ssrf-vulnerable-in-python.html
  • https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf

在这里插入图片描述
利用短网站服务等的302/301跳转。
在这里插入图片描述

解决方案:

  • 设置allow_redirects=False,不允许目标进行跳转
  • 每跳转一次,就检查一次新的Host是否是内网IP,直到抵达最后的网址

第一种情况明显是会影响业务的,只是规避问题而未解决问题。当业务上需要目标URL能够跳转的情况下,只能使用第二种方法了。

所以,归纳一下,完美解决SSRF漏洞的过程如下:

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

通过网路层面的ACL,目标服务器仅能访问白名单中的主机,以及常用特定端口80,443.

SSRF的绕过技巧

参考:
https://portswigger.net/web-security/ssrf

  • 攻击网络上其他主机或端口的(burp intruder扫描各种IP和port)
  • 基于黑名单的:使用特殊IP格式(127.1,spoofed.burpcollaborator.net等解析到127的域名)
  • 基于白名单的:使用#和@(及其两次编码形式)https://expected-host@evil-host,https://evil-host#expected-host
  • 字符串大小写/编码两次
  • 通过open redirection绕过SSRF防御

基于黑名单的绕过demo:
在这里插入图片描述
在这里插入图片描述

基于白名单的绕过demo:
在这里插入图片描述

结合open redirection(302跳转)
比如在“下一个产品”这种页面
在这里插入图片描述
找到path这样的参数,存在302跳转(open redirection)
在这里插入图片描述

整个过程:
先找到stockApi这个传url参数的地方,但是发现不能指定其他IP或域名:
于是只能从本身应用找,能不能找到一个302跳转(open redirection),
在这里插入图片描述

这样就可以把本该在客户端重定向的请求,转换成在服务端重定向的请求了。
在这里插入图片描述

注意一定要url编码这个参数,保证这个参数是stockApi字段的值,避免引起歧义:
image.png

SSRF利用工具

https://github.com/samhaxr/XXRF-Shots

SSRF 漏洞原理与实际案例介绍

对于 SSRF 的审计可以从 http 请求函数入手,这里提供一些审计函数,如下:

HttpClient.execute
HttpClient.executeMethod
HttpURLConnection.connect
HttpURLConnection.getInputStream
URL.openStream
HttpServletRequest
getParameter
URL
HttpClient
Request
HttpURLConnection
URLConnection
okhttp
BasicHttpEntityEnclosingRequest
DefaultBHttpClientConnection
BasicHttpRequest
URI

参考:
https://xz.aliyun.com/t/7186#toc-12

发布了601 篇原创文章 · 获赞 101 · 访问量 100万+

猜你喜欢

转载自blog.csdn.net/caiqiiqi/article/details/102570918