GHCTF 2025ez_readfile
image.png

这是一道php强类型比较的题目
需要使用对用payloud
a=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%24%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%82%7D%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%84%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEcC%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%BC%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%99%B59%F9%FF%C2
&b=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%A4%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%02%7E%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%04%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEc%C3%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%3C%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%9959%F9%FF%C2

关于门槛3的绕过
门槛三:is_string($a) && is_string($b)
在 PHP 中,通过 POST 或 GET 传输的普通参数,默认都会被解析为字符串(String)。

即使你传输的是 a=1,在 PHP 后端通过 $_POST['a'] 获取到的值其实是 字符串 "1",而不是整数 1

1. 为什么它是字符串?

HTTP 协议本身是基于文本的。当你发送一个 POST 请求时,Body 部分通常是像 a=1&b=2 这样的字符串。PHP 在解析这些数据并填充到 $_POST 全局数组时,会自动把这些值处理成字符串。

我们可以用 var_dump() 来证明这一点:

PHP

// 假设你发送了 POST 数据: a=1
var_dump($_POST['a']); 

// 结果输出:
// string(1) "1"  <-- 注意这里显示的是 string

总结

  • 传输 a=1$_POST['a']字符串 "1"
  • 传输 a=abc$_POST['a']字符串 "abc"
  • 传输 a[]=$_POST['a']数组 []

payloud的由来

从字面上看,psycho%0A 确实没有极其深奥的“密码学含义”,但它在 CTF 和安全研究中扮演了一个标志性的角色

我们可以从以下两个层面来拆解它的含义:

1. 字面意思

  • psycho:英文单词,意为“疯子”或“精神病患者”。
  • %0A:这是 URL 编码后的 换行符 (\n)

之所以加上换行符,通常是为了让 Payload 在某些输出环境下(比如直接打印在网页上)能另起一行,显得整齐一点,或者为了凑齐 MD5 算法要求的字节数。


2. 功能含义:它是“前缀 (Prefix)”

这才是它出现在这里的真正原因。

MD5 碰撞工具(最著名的是 Fastcoll)允许用户指定一个任意内容的开头。工具会根据你给出的开头,在后面通过复杂的数学计算生成“碰撞块”。

  • 它的含义是“自定义”:最早制作这组 Payload 的人(可能是某个安全研究员或 CTF 出题人)随手写了一个 psycho。由于这组 Payload 效果非常稳定且流传极广,它就成了一个“经典款”,被全世界的 CTF 选手复制粘贴。
  • 证明能力:它证明了 MD5 碰撞可以从任何人类可读的字符串开始。你可以把它改成 hello%0Aadmin%0A,只要你用工具重新算一遍,依然能生成一组碰撞。

这份payloud url编码的原因

1. 存在“不可见”的二进制字节

这串 Payload 的核心不是 psycho,而是后面那些 %00, %AD, %AF

  • 键盘打不出来:比如 %00(空字节/Null Byte)或 %AD,它们在标准 ASCII 码表里没有对应的可显示字符。你无法直接在输入框里通过敲键盘输入它们。
  • 会被拦截或截断:很多系统(包括浏览器和 Web 服务器)在处理原始字符串时,一旦遇到真正的“空字节”(0x00),会认为字符串在这里就结束了。如果不编码,后面的关键数据就全丢了。

2. 避免破坏 HTTP 的“语法”

发送的数据是通过 application/x-www-form-urlencoded 格式传输的。这个格式有自己的语法:

  • & 连接不同参数(如 a=...&b=...)。
  • = 连接键和值。

如果你的强碰撞 Payload 中恰好有一个字节的二进制值等同于 & (0x26) 或 = (0x3D),服务器就会误解你的意思。

  • URL 编码的作用:它把所有可能产生歧义的字节都变成了 %xx 这种安全的形式,确保服务器能原封不动地拿到原始二进制数据。

3. 字符集与传输的稳定性

不同的设备和浏览器对“乱码”(非 ASCII 字符)的处理方式不同:

  • 有的会尝试用 UTF-8 解码。
  • 有的会尝试用 GBK 解码。

由于 MD5 强碰撞对数据的精确度要求到了“位”(bit)的级别,哪怕传输过程中错了一个 bit,MD5 值就会天差地别。使用 URL 编码可以保证数据在从“你的电脑”到“服务器 PHP 引擎”的这段旅途中,不被任何中间环节(浏览器、代理、中间件)修改。


对比图表:编码 vs 不编码

维度直接传输原始字节 (Raw)使用 URL 编码 (%xx)
可读性看上去是乱码,甚至看不见是一串可见的 ASCII 字符
安全性容易被 %00 截断,或被 & 分割非常稳定,不会破坏请求结构
精确性极易在编码转换中损坏100% 还原原始二进制
PHP 接收$_POST 可能解析错误$_POST 自动解码,拿到精确值
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇