news 2026/9/5 7:20:44

SSRF 从入门到实战:原理、危害与基础利用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SSRF 从入门到实战:原理、危害与基础利用

本文为个人学习研究笔记,内容仅用于 SSRF 漏洞原理、复现环境搭建及安全防御技术研讨,所有实验均在自建、拥有完全授权的测试环境中完成。根据《网络安全法》,未经授权测试、攻击他人系统属于违法犯罪行为。禁止复制 本文Payload 对外部站点进行测试,违规使用造成的一切后果由使用者自行负责。


0. 先看一个"奇怪"的现象

假设你访问一个正常的网页快照服务,它长这样:

你输入一个网址 ──→ 服务器帮你抓取这个网址的内容 ──→ 返回给你

现在你在输入框里填了一个不是网址的东西,而是服务器自己内部的地址:

http://127.0.0.1:18080/admin

结果服务器居然老老实实地把"内部管理后台"的页面内容抓回来、返回给你了:

【服务端抓取结果】 <h1>内部管理后台</h1> <p>欢迎回来,管理员。</p> <p>当前登录身份:<b>root</b></p> <p>内部 API 密钥:<code>flag{SSRF_内网探测_成功_0x7f000001}</code></p>

这里就出现了一个值得你停下来想 30 秒的问题:

这个"内部管理后台",本来应该只有服务器自己(或者内网里的人)才能访问,凭什么你一个外部的普通用户,随便提交一个 URL 就能看到它的内容?

答案就是本篇文章要讲的主角:SSRF(Server-Side Request Forgery,服务端请求伪造)


1. SSRF 到底是什么意思

1.1 一个类比

把"服务器"想象成银行柜台的柜员,把"你"想象成站在柜台外的客户

  • 柜台的营业大厅是"外网",谁都能进;

  • 柜台后面的金库是"内网",只有柜员(服务器自己)能进去。

正常业务里,你会说:"柜员,帮我把这张支票兑现。"柜员自己去金库取钱,然后把钱给你。

SSRF 就是:你对柜员说:"柜员,帮我跑一趟金库,把里面那个保险箱里的东西念给我听。"

柜员没有多想,真的进去把保险箱打开,把内容念给你听了。

关键点在于:不是你直接闯进了金库,而是你借了柜员(服务器)的身份和权限,让柜员替你进金库办事。这中间没有任何"撬锁",因为柜员本来就有金库钥匙。

1.2 正式一点的定义

SSRF 是指:攻击者让服务器对攻击者指定的目标发起请求,而这个目标本来是攻击者无法直接访问的(通常是内网地址、或服务器本机)。

一句话版本:服务器被你当成了"代理",帮你访问它才能访问的地方。

1.3 为什么服务器会这么"听话"?

因为很多正常的业务功能,天然就需要"服务器替用户去访问某个 URL",比如:

业务功能服务器需要做的事真实案例场景
网页快照抓取用户给的 URL 内容搜索引擎快照、链接预览
图片代理下载远程图片再展示很多网站为了避免图片防盗链、做缩略图
文件导入从 URL 导入文件(如"通过链接导入 Markdown")在线文档、笔记类产品
远程监控/体检服务器去 ping/检查某个地址站长工具、拨测系统
回调通知服务器主动请求用户填的回调地址支付回调、Webhook

这些功能有一个共同点:服务器必须信任用户提供的 URL,并去请求它。一旦开发者没有限制"这个 URL 可以指向哪里",SSRF 就诞生了。

你可能会想:这不就是把用户输入当 URL 去请求吗,为什么这么常见?因为大多数开发者只想到"用户会给我一个正常的网址",没想到"用户会给我一个内网地址或本机地址"。这属于典型的"信任了不该信任的输入"。


2. 为什么 SSRF 危险?

很多初学者觉得:"不就是让服务器访问一下内网吗,能怎样?"

答案是:能怎样,取决于内网里有什么。下面按危害从低到高排:

2.1 探测内网存活与端口(信息收集)

攻击者可以让服务器去访问http://10.0.0.1http://10.0.0.2……根据返回结果的时间差异、报错内容,判断内网有哪些主机、开了哪些端口、跑着什么服务。这是后续攻击的"地图"。

2.2 读取本机或内网的敏感信息

  • file:///etc/passwd读取服务器本地文件(如果协议没被禁用)

  • 访问内网的监控、后台、数据库管理界面(如 Redis、MySQL 管理台、Docker API 等)

2.3 打内网中"不设防"的服务(高危)

很多内网服务默认只监听 127.0.0.1,且没有密码,因为它们以为"只有本机程序能连我"。典型代表:

  • Redis(默认无密码,可通过 SSRF 的 gopher 协议直接下发命令 → 写 webshell → 拿下服务器)

  • Docker API/var/run/docker.sock

  • 云元数据服务(AWS/阿里云/腾讯云的169.254.169.254,能拿到服务器的临时凭据)

这里有一个反直觉的点,值得记住:内网服务"不设防"恰恰是因为它认为攻击者够不着它。而 SSRF 的价值,就是把"够不着"变成"够得着"。

2.4 攻击云厂商元数据接口(真实高频漏洞)

在公有云上,每台虚拟机都能通过一个魔法 IP169.254.169.254访问到"元数据服务",里面有这台机器的IAM 临时密钥、SSH 公钥、内网 IP等。如果云上某个应用存在 SSRF,攻击者常常直接:

http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>

拿到临时密钥,进而接管云资源。这是国内外各大 SRC(漏洞众测平台)里 SSRF 最常见、最值钱的利用方式。


3. 靶场

它由三部分组成:

角色说明监听地址
漏洞靶机一个"网页快照/图片代理"服务,存在 SSRF0.0.0.0:8080(对外)
内网管理后台持有敏感 flag 的内部服务,只监听 127.0.0.1127.0.0.1:18080
内网 Redis无密码的内网数据库,只监听 127.0.0.1127.0.0.1:6379

关键设定:内网服务和 Redis 都只绑定在 127.0.0.1 上,外部用户直接访问是访问不到的(在真实环境里,它们处于防火墙后的内网)。我们就是要通过漏洞靶机这个"柜员",去够到它们。

3.1 漏洞靶机代码(vuln.php

<?php // 场景1:无任何过滤的抓取(最基础的 SSRF) if (isset($_GET['fetch'])) { $url = $_GET['fetch']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随跳转(伏笔:后面绕过用) $res = curl_exec($ch); curl_close($ch); echo "【服务端抓取结果】\n" . $res; exit; } ?>

这段代码非常"典型":用户输入的$url直接被塞进了curl_setopt(..., CURLOPT_URL, $url),没有任何校验。这就是 SSRF 的根源。

3.2 内网管理后台代码(internal_admin.py

import http.server, socketserver ​ FLAG = "flag{SSRF_内网探测_成功_0x7f000001}" ​ class AdminHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): if self.path == '/admin': body = f"<h1>内部管理后台</h1>...内部 API 密钥:{FLAG}...".encode('utf-8') self.send_response(200) # ... 返回 HTML # ... ​ # 关键:只绑定 127.0.0.1,模拟"仅内网可访问" socketserver.TCPServer(("127.0.0.1", 18080), AdminHandler).serve_forever()

注意最后一行:服务只绑定在127.0.0.1。这意味着在真实网络里,外部用户连 18080 端口都连不上。

3.3 启动靶场

# 1. 启动内网管理后台(只监听 127.0.0.1:18080) python3 internal_admin.py & ​ # 2. 启动无密码 Redis(只监听 127.0.0.1:6379) redis-server --port 6379 --bind 127.0.0.1 --protected-mode no & ​ # 3. 启动漏洞靶机(监听所有网卡 0.0.0.0:8080) php -S 0.0.0.0:8080 vuln.php

验证一下:直接curl http://127.0.0.1:18080/admin能访问,但从"外部网络"是访问不到的——这就是 SSRF 要跨越的那道墙。


4. 第一次利用:最基础的 SSRF

4.1 正常用法 vs 攻击用法

靶机首页提供了一个表单,输入 URL。正常用户会输入http://example.com。而攻击者输入的是内网地址

curl "http://127.0.0.1:8080/vuln.php?fetch=http://127.0.0.1:18080/admin"

返回:

【服务端抓取结果】 ​ <h1>内部管理后台</h1> <p>欢迎回来,管理员。</p> <p>当前登录身份:<b>root</b></p> <p>内部 API 密钥:<code>flag{SSRF_内网探测_成功_0x7f000001}</code></p>

拿到 flag 了。

4.2 这背后发生了什么?(请求链路)

你 (外部用户) │ 发送:fetch=http://127.0.0.1:18080/admin ▼ 漏洞靶机 (192.168.x.x:8080) ← 你的请求只到了这一层 │ 靶机自己去请求:http://127.0.0.1:18080/admin ▼ 内网管理后台 (127.0.0.1:18080) ← 这一层,你本来够不到 │ 返回:内部 API 密钥 flag{...} ▼ 漏洞靶机 → 把结果原样返回给你

关键理解:请求是靶机发出的,不是你的浏览器发出的。所以"谁能访问 127.0.0.1:18080"这个问题上,用的是靶机的身份——靶机当然能访问它自己的 127.0.0.1。

你可能的疑问:127.0.0.1 不是我自己电脑吗?为什么写 127.0.0.1 是访问服务器?这里要分清"这段 URL 是谁去解析的"。127.0.0.1这个地址,在靶机的视角里,指的就是靶机自己。因为最终是靶机去curl这个 URL,所以127.0.0.1就是"靶机本机"。你的浏览器从没直接请求过 127.0.0.1,它只是把字符串127.0.0.1传给了靶机。


5. SSRF 常用协议(由易到难逐个看)

SSRF 的威力很大程度上来自"服务器不止能发 HTTP 请求,还能用别的协议"。我们先认识三个,够用。

5.1 http:// 和 https://(最常用)

就是普通的网页请求,能访问内网任意 HTTP 服务。上面第 4 节用的就是它。

5.2 file://(读本地文件,最直观)

如果开发者的过滤只拦了内网 IP,没拦协议,攻击者可以:

curl "http://127.0.0.1:8080/vuln.php?fetch=file:///etc/passwd"

真实返回:

【服务端抓取结果】 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin ...

file:///etc/passwd让服务器把自己本地文件读出来返回给你。危害不言而喻。

你可能的疑问:为什么是三个斜杠file:///file://后面跟的是文件路径。Unix 的绝对路径本身就是以/开头,所以file://+/etc/passwd=file:///etc/passwd。中间的//是协议分隔符,最后那个/是路径开头的斜杠。

5.3 gopher://(最厉害,能"投喂"任意 TCP 数据)

这是 SSRF 进阶的核心,也是下篇的重点。这里先给你一个直觉:

  • http://只能发"符合 HTTP 格式"的请求;

  • gopher://能让你直接往目标端口塞任意字节_后面跟的字节会被原样发过去)。

这意味着:只要内网服务是"发文本/字节就能控制"的协议(比如 Redis、MySQL 的文本协议),gopher 就能直接跟它"对话"。这是 SSRF 从"读数据"升级到"执行命令/写文件"的关键一步。


6. 小结(上篇)

到这里你应该已经掌握:

  1. SSRF 是什么:让服务器替你访问它才能访问的地方(内网/本机/云元数据)。

  2. 为什么会有:业务需要服务器请求用户提供的 URL,而开发者没限制目标。

  3. 危害:探测内网 → 读敏感信息 → 打无密码内网服务 → 拿云凭据。

  4. 第一次利用fetch=http://127.0.0.1:18080/admin拿到了内网后台的 flag。

  5. 三种协议http(访问网页)、file(读文件)、gopher(投喂任意 TCP 数据)。

下篇预告:真实的漏洞往往不会这么"裸",开发者会加各种过滤(黑名单、白名单、限制协议)。下篇我们讲:

  • 如何绕过127.0.0.1黑名单(十六进制、十进制、八进制、302 跳转……)

  • 如何用gopher://真实打穿无密码 Redis,写入 webshell 实现 RCE

  • 完整的攻击链演示 + 防御建议

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 7:19:00

采购智能体能做什么?企业招投标AI应用场景详解

一个招标项目启动后&#xff0c;采购人的忙碌往往才刚刚开始。 业务部门发来采购需求&#xff0c;技术参数需要进一步梳理&#xff1b;参考历史项目搭好招标文件框架后&#xff0c;还要反复调整资格条件、商务条款和评分标准。文件写完了不能直接发布&#xff0c;还得逐条检查&…

作者头像 李华
网站建设 2026/9/5 7:18:35

航模图纸库深度解析:从文件管理到实机制作的全流程指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 7:16:05

AI科研绘图工具哪个最好用?

现在几乎所有课题组都在用 AI 生成科研示意图、通路图、技术路线图&#xff0c;但不少科研人踩了大坑&#xff1a;AI 出图看着好看&#xff0c;投稿之后直接被编辑打回。图像放大就模糊失真、底层藏有隐形溯源标记、版权归属说不清&#xff0c;生成的位图无法分层编辑&#xff…

作者头像 李华
网站建设 2026/9/5 7:16:03

WebGIS开发入门 | 从 Web 开发到地图开发,差别在哪儿?

01 、WebGIS 开发VS Web 开发的区别WebGIS 开发本身也是一个 Web 开发的过程&#xff0c;它同样会有三端&#xff0c;主要就是一个前后端交互&#xff0c;中间还有服务器层。简单来说&#xff0c;可以分成这三层&#xff1a;前端&#xff08;客户端 UI 层&#xff09;&#xff…

作者头像 李华
网站建设 2026/9/5 7:10:58

MCP 2026-07-28规范解析:无状态架构的AI工具集成实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 7:10:03

电机拖动负载特性详解:恒转矩、恒功率、通风机类与选型要点

电机拖动必看&#xff1a;三种经典生产机械负载特性&#xff0c;搞懂它选型才不会翻车 干电机拖动这一行的朋友应该都有体会&#xff0c;很多现场问题——电机过热、启动困难、运行效率低、选型偏大或偏小——追根溯源&#xff0c;往往不是电机本身的质量问题&#xff0c;而是…

作者头像 李华