news 2026/10/20 7:13:48

CTFHub SSRF通关教程:从内网探测到gopher协议绕过实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CTFHub SSRF通关教程:从内网探测到gopher协议绕过实战

最近带着几个新人把 CTFHub 技能树 Web 篇里的 SSRF 关卡从头到尾刷了一遍,一边打一边记录,回来整理成这篇通关教程。SSRF(Server-Side Request Forgery,服务端请求伪造)这个漏洞在 CTF 里出镜率非常高,CTFHub 技能树里专门给它排了一条从入门到进阶的关卡链,从最朴素的直接访问内网地址,一直到改协议头、变换进制绕过、配合重定向抓内网资源,层层递进。

这篇教程不打算只给答案,我会把每一关背后的原理讲明白,再附上我实际通关时用到的请求包、payload 和踩过的坑。适合刚接触 Web 安全的读者照着一步步操作,也适合刷完题但没想透“为什么要这么绕”的同学回头补原理。全程在 CTFHub 的靶场环境里进行,不需要自己搭环境,打开浏览器就能开始。

1. SSRF 到底是个什么东西:一次服务端请求引发的连锁反应

1.1 从正常功能到漏洞:请求从来没说过只准发给外部

很多初学者第一次看到 SSRF 这个名词,会本能地觉得“这跟 XSS、SQL 注入一样,是不是往参数里塞一段特殊字符就能拿 flag”。方向算对了一半,但 SSRF 的触发逻辑和前端漏洞完全不同。XSS 是把恶意脚本塞进页面让浏览器执行,SQL 注入是把 SQL 片段拼进查询让数据库执行,而 SSRF 的本质是服务端代码接收了你提供的“目标地址”,然后替你去访问这个地址。

举个例子,很多网站有“头像抓取”功能:你提交一个图片 URL,服务器后台用 curl 之类的方法把图片下载下来存到本地。写程序的工程师为了让代码灵活一点,直接把 URL 参数透传给了 curl,于是你传https://example.com/1.jpg,服务器就去访问https://example.com/1.jpg。问题来了,服务器自己所在的网络中,除了公网,往往还有一块不被外部访问的内网区域,这块区域里可能跑着数据库、缓存服务、内部管理后台、运维接口。如果你把 URL 从https://example.com/1.jpg改成http://127.0.0.1/admin,服务器就会带着它自己的身份和网络权限,去访问本机或内网里的管理后台。

CTF 里经常用一句话概括这种利用方式:攻击者没办法直接访问内网,但服务端可以。攻击者要做的,就是想办法让服务端替自己访问。CTFHub 技能树的 SSRF 关卡,整体就是围绕“怎么让服务端把请求发到不该发的地方”设计的,每一关都在逼你突破一类限制。

1.2 触发 SSRF 的常见函数与协议面

要判断一个接口是否存在 SSRF,首先要看服务端用什么函数发起了请求。PHP 环境是 CTF 中最常见的,这里列三个出现频率最高的函数族:

  • curl_exec():最灵活,支持 http、https、file、dict、gopher、ftp 等多种协议,CTF 里绝大多数高阶玩法(尤其是 gopher 打内网服务)都依赖它。
  • file_get_contents():默认支持 http,也支持 file 协议直接读本地文件,如果代码里没做协议限制,一个file:///etc/passwd就能把服务器上的文件内容拉出来。
  • fsockopen():偏向底层,适合构造原始 TCP 数据包,在需要手动组装请求的场景里有用。

协议面决定了你能让服务端“访问什么类型的目标”。http://只能访问 Web 服务,file://能读文件,gopher://能像一个原始 TCP 客户端一样向任意端口发送自定义数据。CTFHub 的关卡里,前面几题你只会用到 http,后面就开始考察协议切换和请求构造能力了。

提示:看到 URL 参数名像url=、target=、path=、dest=、addr=的接口,都可以下意识在脑子里给这个接口打一个“可能 SSRF”的标签,然后拿http://127.0.0.1/去试。CTF 里这种参数命名习惯非常多。

2. CTFHub 技能树里 SSRF 关卡的整体设计逻辑

2.1 题目编排:每道题差的不只是过滤规则

CTFHub 的 SSRF 关卡不是简单地在同一个漏洞点上换几个过滤函数,它有一套递进逻辑:先让你理解“什么是内网地址”,再让你面对“过滤器把内网地址拦了”的困境,接着给你一个只能走特定协议的苛刻环境。我把它理解成一堂设计过的安全实验课,而不是一道一道孤立的考题。

第一类关卡是没有任何过滤的,直接让你把 URL 指向内网地址拿 flag;第二类开始出现字符串黑名单,常见的过滤手段是把127.0.0.1、localhost这些关键词直接替换或拦截;第三类加入了协议白名单,只允许 http 或 https,这时候你想用file://读文件就会被挡;第四类把解析差异和重定向结合起来考,需要你利用 URL 解析器与请求库之间的理解差异来绕过;最后一类是高阶玩法,配合 gopher 协议去访问内网的 Redis、FastCGI 等服务。每一关对应一类真实场景,刷完基本就把常见的绕过滤手段摸熟了。

从出题人的角度想,这个顺序设计得非常合理:如果一上来就考 gopher 协议打 Redis,新手一定一脸懵,因为很难理解“服务端帮我发一串自定义 TCP 数据”这件事能造成什么后果。但如果你已经经历了前面几关,理解了服务端是“带着自己的身份去请求”,再看到 gopher,就很自然地联想到“我能不能让服务端冒充内网客户端去和 Redis 说话”。

2.2 考点分类:直接访问、进制绕过、重定向、协议限制

把 CTFHub 的 SSRF 关卡拆开看,核心考点可以归纳成四类。

第一类是基础访问型。题目代码只做了最基本的 URL 获取,连过滤都没有,你只需要把请求目标改成内网地址。考察点是对 SSRF 概念的理解。

第二类是字符串绕过型。过滤规则往往是preg_replace('/127\.0\.0\.1/', 'localhost', $url)或直接strpos检查目标地址里是否包含内网字样。应对方法是把 IP 换成等价变体:十进制整数形式、十六进制形式、八进制形式,或者利用 URL 解析器对主机名的宽容处理,比如127.1这种省略写法。

第三类是重定向与解析差异型。过滤规则拦的是“最终请求的目标”,但服务端拿到 URL 后会先做一层跳转,在跳转过程中可能绕过检查。利用方式是自己搭建一个返回 302 跳转的地址,跳转到内网地址。解析差异则利用 PHP 的parse_url与 curl 对同一个 URL 的不同理解,经典例子是http://example.com@127.0.0.1,有些解析器会以为主机名是example.com,但 curl 实际请求的是127.0.0.1。

第四类是协议限制与数据构造型。这类题目限制了只能使用http://,但你可能需要访问的不是 Web 端口,这时候要用gopher://构造原始请求,或者利用dict://探测端口和发送简单命令。

2.3 通关准备:一个趁手的抓包工具能帮你省下一半时间

CTFHub 的靶场直接在浏览器里交互就能做,但建议别只靠浏览器。我刷这组题时全程开着抓包代理工具,浏览器只负责发请求,工具负责看请求详情、改包重发,这个习惯在调试 gopher payload 时帮了大忙。你不需要装多复杂的工具,社区里最常见的抓包工具就足够,关键是熟悉“拦截请求—修改内容—重放”这条流程。

另外一个建议是准备一个能快速算进制转换的终端。后面有一类题要把127.0.0.1转成各种进制表示,虽然在线转换网站也能算,但命令行里一条printf解决效率更高,而且不会因为网页弹窗打断思路。我习惯用 Python 交互式环境,int('0x7f000001', 16)这类计算随时能写。

3. 逐关拆解:从直接打内网到 gopher 协议构造

3.1 第一类关卡:无过滤直接访问内网地址

这一关打开之后,页面会有一个输入框,让你填 URL,提交后服务端就把这个 URL 的内容返回给你。没有过滤,没有协议限制,唯一的目的就是让你建立 Web 请求的映射关系:在浏览器输入http://127.0.0.1/返回的是本机 curl 访问的结果,而不是你浏览器访问的结果。

请求 Payload 直接填http://127.0.0.1/flag.php(具体文件名看题目标签和提示,通常关卡的提示会直接说明内网服务路径,如果没说,可以先用http://127.0.0.1/探一下根路径,看返回内容是什么)。也可以填http://127.0.0.1:80/,80 端口一般就是本机 Web 服务。这个关卡里,返回内容中直接包含 flag,不需要额外操作。

注意:如果填127.0.0.1没反应,可以先检查是不是把 URL 写成了https://。CTFHub 的靶场基本都走 http,https 的请求会在 SSL 握手阶段失败,返回空内容。另一个排查点是确认服务端是否要求带端口,有些关卡的内网服务起在某个特定端口,比如http://127.0.0.1:8080/。

3.2 进制与省略写法绕过:把 127.0.0.1 变成各种“马甲”

第二类关卡开始有过滤了,常见的是把127.0.0.1这个字符串直接替换为空,或者检测到就返回 ”forbidden”。这时候要思考一个问题:过滤器过滤的是字符串,而 curl 请求时解析的是地址。字符串层面的拦截,完全可以用地址层面的等价变体来绕过。

127.0.0.1的等价变体有这么几类:

表示方式写法示例说明
十进制整数http://2130706433/把 IP 四段按 256 进制合并成一个整数
十六进制整数http://0x7f000001/同上,用 16 进制表示那个整数
单个八进制数http://0177.0.0.1/每段可用八进制表示,127的八进制是0177
混合写法http://127.1/、http://0x7f.1/IP 地址段可以省略为 8 位和 16 位形式
点分十进制变体http://0177.0.0.1/四段进制混用,通常也能通

我实际通关时用的最多的组合是http://2130706433/和http://127.1/。前者是把127.0.0.1当成一个 32 位无符号整数:127 是前 8 位,0 是后 24 位,计算结果就是127 * 256^3 + 0 * 256^2 + 0 * 256 + 1 = 2130706433。后者127.1利用了 URL 解析器的宽容规则,第一段正常,第二段被当作 16 位整数,1就代表0.1,最终解析为127.0.0.1。

这类关卡的过滤器如果只过滤了127.0.0.1这个字符串,你用一个进制变体直接就能过。如果过滤器把0x7f、2130706433这些也拉黑了,那就顺着上面的表往下试,通常总有一个不在黑名单里。CTF 的出题人一般只会写几行简单的正则,不会把整个 IP 变体体系全防住,这也是为什么这类题在实战里非常有代表性——很多真实系统的过滤规则同样只挡了最明显的写法。

补充一个我自己常用的 Python 换算小工具:

ip = "127.0.0.1" parts = list(map(int, ip.split("."))) decimal = parts[0] * 16777216 + parts[1] * 65536 + parts[2] * 256 + parts[3] print(decimal) # 2130706433 print(hex(decimal)) # 0x7f000001 print(".".join(oct(x).replace("0o", "0") for x in parts)) # 0177.0.0.1

3.3 URL 解析差异:@符号、短域名与重定向机制

第三类关卡明显感觉出题人开始“不讲武德”了,因为过滤器不再只查 IP 字符串,而是直接把127.0.0.1、localhost、2130706433、0x7f全塞进了黑名单。这时候再单纯换进制写法就不好使了,得换思路。这一类关卡的共同点是考你URL 的组成部分在哪个环节被解释。

第一个关键点是@符号。一个 URL 形如http://user:pass@host:port/path,@前面是用户名和密码,@后面才是真正的主机名。有些过滤器用正则去匹配://后面的一整段,然后检查里面有没有黑名单 IP,但它忽略了@符号的存在。http://example.com@127.0.0.1/这个 URL,正则可能以为主机名是example.com,但 curl 实际把@前面的部分当作认证信息丢弃了,真正去连的是127.0.0.1。

第二个关键点是重定向。过滤器校验的 URL 与最终实际访问的 URL 可以不是同一个,因为一次 HTTP 请求里,服务端可以返回 302 状态码,并在Location头指定浏览器或 curl 的下一个访问地址。很多过滤逻辑只检查了用户提交的原始 URL,没有跟踪重定向链。实现方式是先找一个能正常通过校验的地址,比如http://example.com/,然后在某台服务器上部署一个返回 302 的脚本,Location: http://127.0.0.1/。curl 遇到 302 默认会跟随跳转,过滤检查却只发生在请求发出之前。

第三个关键点是短域名。有些外部域名服务允许把127.0.0.1映射成短域名,比如形如http://xxx的域名,解析后就指向本机。过滤器看到的是一个普通域名,curl 解析后却拿到了内网 IP。

CTFHub 这类关卡中,@和重定向机制比较常见。我当时通关用的 payload 是http://example.com@127.0.0.1/,如果题目过滤得严,再换 302 重定向的方案。重定向方案的具体做法后面第 4.2 节我会重点复盘,因为那里有一个非常典型的坑。

3.4 协议限制下的再突破:file 协议读文件与 http 协议打内网

到了协议限制型关卡,题目代码明确写了只允许 http 和 https,其他协议一律拒绝。表面上看,这条路已经被堵死了,因为你没法再用file:///etc/passwd直接读文件。但仔细观察出题逻辑会发现,协议限制只是缩小了你的武器库,没有缩小内网服务暴露的攻击面。既然只允许 http,那就用 http 去访问内网里跑着的 Web 服务。

CTFHub 平台上这类关卡通常有一个隐藏的内网服务在某个端口监听,比如 8080、8000、8888 甚至随机端口。通关思路是:先用 http 协议做一个内网端口探测。如果你能拿到响应状态码或响应时间差异,就能判断哪些端口开放。举个例子,填http://127.0.0.1:80/和http://127.0.0.1:8080/,如果一个返回正常页面一个连接失败,端口开放情况就出来了。除了逐端口试,也可以扫一段内网 IP 范围,比如http://127.0.0.1:65535/明显不对,但http://172.17.0.2:8080/这种常见 Docker 内网地址值得试一轮。

有些关卡在 http 协议下塞了一个限制:不允许访问外网地址,只能访问内网。这反而简化了判断——你只需要在给定的 IP 段里找 Web 服务。我刷题时习惯先试127.0.0.1,再试172.17.0.1和172.17.0.2这几个容器网络里最常见的地址,大部分靶场的内网服务都会落在这些网段里。找到内网 Web 服务后,再用同样的 URL 参数访问它的具体路径,flag 通常就藏在页面上或者某个文件路径里。

如果此时真的需要读取服务器上的本地文件,而协议被卡死在了 http,还有一个思路:通过内网 Web 服务的任意文件读取漏洞来间接读文件,比如目标内网服务本身就有?file=../../etc/passwd这种接口。这类二次利用在 CTF 里并不少见,因为出题人布置的内网服务很少是“孤岛”,往往复用了真实服务里常见的功能缺陷。

3.5 gopher 的终极玩法:从打 Web 端口到打 Redis 端口

gopher 协议的用途可以类比成“用一条 URL 就拼出一个原始 TCP 请求”。普通 http 协议只能发 HTTP 格式的数据,gopher 协议则允许你指定目标 IP、端口、以及要发送的原始字节流。这意味着,只要内网里任何一个服务接受 TCP 明文数据,你就能用它来通信。在 CTF 的 SSRF 题目里,最常见的两个目标是 Redis 和 FastCGI。

以 Redis 为例,假设内网 IP 是127.0.0.1,端口 6379 跑着未授权访问的 Redis 服务。常规 HTTP 协议拿它没办法,因为你没法在 HTTP 请求里塞进 Redis 的 RESP 协议命令。但 gopher 请求长这样:

gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a...

_后面的部分就是要发送的原始 TCP 数据。这里有个关键细节:所有换行符必须 URL 编码成%0d%0a。Redis 的协议是行基协议,每条命令以\r\n结尾,如果你在 URL 里直接写了换行符,传输过程中会被剥落或截断,命令根本执行不了。我在这个编码细节上卡了半小时,后来把 FLUSHALL、SET、CONFIG SET 一整条命令链都编码之后,才成功写入了 WebShell。

FastCGI 也是类似思路,gopher 构造 FastCGI 的二进制数据包,打到内网 PHP-FPM 端口,从而执行任意 PHP 代码。这类更进阶的利用在 CTFHub 技能树里不是所有版本都有,但思路值得理解:服务端能访问什么协议,你就能用什么协议,最终目的都是让服务端替你在内网里执行一段数据。

构造 gopher payload 的时候,我强烈建议用脚本生成而不是手写编码后的字符串,否则一旦命令长了很容易漏一个%0d%0a。下面这个 Python 片段可以把 Redis 命令列表直接转成 gopher 的 payload:

import urllib.parse def redis_gopher(commands): payload = "" for cmd in commands: payload += f"*{len(cmd)}\r\n" for arg in cmd: payload += f"${len(arg)}\r\n{arg}\r\n" return "gopher://127.0.0.1:6379/_" + urllib.parse.quote(payload) commands = [["info"], ["config", "set", "dir", "/var/www/html"]] print(redis_gopher(commands))

4. 实战复盘:我踩过的三个典型坑

4.1 file 协议读文件的路径问题

有一类题目没限制协议,第一反应自然是直接用file:///etc/passwd读文件,但我在 CTFHub 上第一次试的时候返回了空页面。原因排查后发现,靶场环境运行在容器里,默认工作目录和文件系统结构与标准 Linux 不一定一致,而且有些题目把 flag 放在了 Web 目录下,跟/etc/passwd八竿子打不着。

正确操作是先用file:///etc/passwd确认文件读取能力是否存在,如果返回了正常的root:x:0:0:root:/root:...开头内容,说明 file 协议是通的;然后根据题目提示找 flag 的具体路径。常见路径有/flag、/flag.txt、/var/www/html/flag.php、/var/www/flag。如果你发现file:///etc/passwd读不出来,先确认请求的目标主机是不是127.0.0.1,不要漏掉 URL 里的主机名部分,完整写法是file://127.0.0.1/etc/passwd,直接把路径放在file://后面在某些环境下会被当成相对路径处理。

提示:用 file 协议读文件时,如果页面返回空白,先把响应头打开看状态码。200 返回空白可能只是文件内容里有特殊字符被前端隐藏了,右键查看源代码往往就能看到 flag;502 或 403 才是真正的路径或权限问题。

4.2 重定向方案在这个平台上为什么不生效

我在第 3.3 节提到重定向绕过过滤是个好思路,但实操时发现一个容易翻车的点:如果你直接把重定向目标指向http://127.0.0.1/,很多版本的 curl 默认会带上CURLOPT_FOLLOWLOCATION跟随跳转,可目标 URL 中的 IP 如果被某种协议层策略拦截(比如服务端对最终解析 IP 有限制),还是会失败。另一个更隐蔽的坑是:服务端代码如果用了parse_url验证原始 URL 的 host 是否合法,那么你提供的重定向服务域名必须能正常解析,否则请求根本发不出去。

我在本地验证环境里测试了一套可行的方案:在某台公网服务器的 Web 目录放一个r.php,内容就一行:

<?php header("Location: http://127.0.0.1/flag.php");

然后把关卡 URL 填成http://我的服务器域名/r.php。这样过滤规则看到的是一个普通域名,通过校验;curl 请求时拿到 302 后自动跟到内网地址,flag 内容就返回了。CTFHub 的靶场如果限制了你访问公网域名,这个方案会失效,那就只能换回进制绕过或@符号绕过。说明一下:这里的“服务器”泛指你能够控制的一个 URL 响应源,技术上也可以用各种免费托管服务的动态接口实现,不一定要真的购买一台云主机。

4.3 gopher 构造请求时的 URL 编码细节

gopher 协议最大的坑就是编码。我在刷 Redis 相关关卡时,第一次生成 payload 后在本地用curl "gopher://..."测试,发现 Redis 完全没有反应,命令没有执行。检查之后发现问题出在一个细节上:gopher 的 URL 里,_后面的部分会被当作请求数据,而这个数据块里面的所有\r\n必须编码成%0d%0a,但这是针对传给 HTTP 代理或者直接通过 curl 访问的情况。在 CTF 场景里,服务端用 curl 拿到了这条 gopher URL 后,会先 URL 解码,再把内容通过 TCP 发出去。如果你把整段 payload 再手动编码一次,就会导致服务端解码后发给 Redis 的数据是双重编码的乱码。

换句话说,直接把原始 Redis 协议数据做一次 URL 编码,是安全的;人工在网页上复制粘贴时不小心把已经编码的%再转成%25,是事故。解决办法是全程用脚本生成 payload,不要手动改。我后来写了一个小工具函数,先构造出完整的 Redis 请求文本,再统一 quote,保证只编码一次。

另外,gopher 的协议头后面通常用一个_来占位,这个_本身没有任何含义,只是防止 URL 里协议名和路径之间出现空段。你也可以换成任意字符,但_是社区约定俗成的写法,避免混淆。

4.4 一条完整的通关思路复盘:从无过滤到 gopher

把前面几关串起来,我总结出了一个适用于大部分 SSRF 关卡的排查顺序,照着这个顺序做,基本不会漏掉突破口。

先看题目代码或提示,确认有没有协议限制。没有协议限制,优先尝试file:///etc/passwd确认文件读取,再用http://127.0.0.1/探测内网 Web 服务;有协议限制,先把进制变体、@符号、重定向这些绕过手段按顺序试一遍。若所有绕过手段都失效,且题目提示里有“内网服务”字样,就用 http 协议做端口探测和目录探测。最后,如果明确要求“访问 Redis 的 6379 端口”或“使用 gopher 协议”,再进入数据构造阶段,用脚本生成 payload,打完收工。

这套顺序的好处是每一步都在增加信息量:文件读取能告诉你服务器文件系统结构,内网探测能告诉你网段和端口分布,gopher 能让你在拿到基线信息后精准打击特定服务。刷题不是目的,搞清楚每一步为什么这么试,才是这套技能树真正想训练的东西。

5. 常见问题速查与避坑清单

5.1 报错类型与排查思路汇总

我把刷题过程中遇到过的几类现象和对应排查方法整理成了速查表,方便大家对照操作。

现象可能原因排查操作
返回空白页面协议被限制 / 路径不对 / 内容被前端隐藏右键查看源代码,检查响应头状态码
返回 “forbidden” 或过滤提示触发了关键词黑名单换进制变体、@写法、重定向方案
URL 提交后没有任何请求发出协议校验不通过,不合法协议被拦截查看代码提示中的协议白名单
端口探测时所有端口都超时内网 IP 判断错误 / 防火墙封锁先试127.0.0.1,再试172.17.0.1~172.17.0.5网段
gopher 请求发出去但服务无响应编码错误 / Redis 命令格式错误用脚本生成 payload,检查%0d%0a数量
302 重定向到内网仍返回空白目标路径不存在 / 请求被内网其他策略拦截先测http://127.0.0.1/确认连通性,再测具体路径

5.2 新手最容易忽略的五个细节

先说第一个:URL 参数里的 IP 地址不等于最终请求的 IP。过滤规则检查的是字符串,curl 解析的是 DNS 和 IP 地址,这两层之间永远存在绕过的空间。第二个是不要忽略端口的存在,很多关卡的内网服务就在某个隐蔽端口上,先用http://内网IP:端口/去测,比你盲目录爆破有效得多。第三个是协议限制不只是 http/https 两种,gopher、dict、file 各自能到达不同的协议空间,必要的时候全部试一遍。

第四个细节是关于@符号和 URL 编码的:某些过滤规则会先urldecode再检查,如果你把%40当作@传进去,可能在解码之后反而触发了检测。最好直接传原始字符,不要自己二次编码。最后一个也是最重要的:所有操作在靶场或授权环境里进行,学习漏洞利用不是为了打真实系统,而是为了理解边界条件。CTF 的价值在于通过模拟题建立对漏洞的直觉,这种直觉在做代码审计和漏洞挖掘时非常有用。

5.3 学习拓展:从 CTFHub 通关到发现真实业务里的 SSRF

刷完 CTFHub 这套题之后,我建议你再做两件事来巩固:第一,把 SSRF 从“利用”角度翻到“防御”角度,想一想如果让你设计一个 URL 参数接口,要怎么避免被这样绕过——限制协议、做 DNS 解析验证、禁用重定向、封锁内网 IP 段、最小化服务端网络权限,每一条能不能在 CTFHub 的题目里找到对应的绕过方式,反过来理解会更深刻。第二,尝试把 PHP 代码审计里的 SSRF 漏洞场景拿到本地环境里复现一遍,改几行过滤规则,观察哪个绕过手段失效、哪个依然有效,这样你能真正掌握“过滤的本质是对字符串的判断,而请求的本质是对地址的解析”这句话。

我自己刷这套题最大的体会是:SSRF 的难度不在于记住多少条 payload,而在于理解“服务端发起请求”这个行为的完整链路——用户输入、代码拼接、解析器理解、库函数执行、协议层请求、内网路由,每一个环节都有可能被利用,也有对应的防御手段。把这条链路想通了,CTFHub 技能树里这些关卡就不再是一道道孤立的谜题,而是一幅完整的 Web 安全地图。

最后分享一个实用的小技巧:做题时始终开着抓包代理工具,并且把每一道题的请求包、响应包、payload 都记录到一个本地笔记里。我刷完这套题后回头翻笔记,发现很多当时卡住的点,在笔记里都有一两句“为什么会这样”的记录,这比刷题本身更有积累价值。希望这篇 CTFHub SSRF 通关教程能让你少走一些弯路,也欢迎按这套思路去技能树里逐个验证。

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

从数据到决策:金融AI应用平台架构设计与落地实践

金融业这几年最热的词里&#xff0c;一定少不了"智能决策"。各家机构都在讲数字化转型&#xff0c;但真正把AI落到业务里的&#xff0c;靠的还是能跑起来的应用平台。悦数AI应用平台这个项目&#xff0c;核心就是回答一个问题&#xff1a;当一家银行或券商想让AI驱动…

作者头像 李华
网站建设 2026/10/20 7:13:02

RevitLookup 2020安装配置全攻略:版本匹配、addin文件与故障排查

简介&#xff1a;RevitLookup 2020是一套面向Revit二次开发人员的插件工具包&#xff0c;能以树形结构展示当前选中元素的类别、参数、几何与内部引用数据&#xff0c;让开发者无需频繁编写调试代码即可直观理解Revit对象关系&#xff0c;适合项目调试和对象模型学习。压缩包共…

作者头像 李华
网站建设 2026/10/20 7:13:01

五大AI图像生成模型深度横评:从选型到组合工作流实战

1. 先看整体格局&#xff1a;五个模型各打各的牌&#xff0c;别用一套标准评价它们2024到2025年这一波AI图像生成模型的迭代速度&#xff0c;比前两年明显加快。FLUX.2、Seedream&#xff08;即梦&#xff09;、Z-image、Qwen-Image、GLM-Image这五个名字&#xff0c;不管你是做…

作者头像 李华
网站建设 2026/10/20 7:12:48

前缀表达式求值:从右往左扫描的栈式算法详解

这是一道很经典的数据结构题目&#xff0c;很多朋友在学栈和递归的时候都会遇到。我当年第一次做这题也卡了一阵子&#xff0c;倒不是代码写不出来&#xff0c;而是方向搞反了&#xff0c;一直在想怎么从左往右处理。后来想通前缀表达式的本质之后&#xff0c;代码其实就几行。…

作者头像 李华
网站建设 2026/10/20 7:12:47

RKNN端侧部署实战:从模型转换到NPU优化的完整指南

做端侧AI部署的人&#xff0c;应该都有过这种体验&#xff1a;模型在电脑上跑得好好的&#xff0c;一放到开发板上就拉胯。要么推理速度慢到没法看&#xff0c;要么内存直接爆掉&#xff0c;要么压根编译不过去。我自己第一次把模型的权重搬到嵌入式设备时&#xff0c;也踩了整…

作者头像 李华