[HarekazeCTF2019]encode_and_encode 1
[HarekazeCTF2019]encode_and_encode
1
1.php对请求体body的两种处理逻辑:
逻辑 A:自动解析到 $_POST
当 PHP 接收到 POST 请求时,它会先查看 Header 中的 Content-Type:
- 如果
Content-Type是application/x-www-form-urlencoded(普通表单)或multipart/form-data(带文件的表单)。 - PHP 解释器会自动触发解析引擎。
- 它会将 Body 里的字符串按照
key=value的格式拆解,并填充到全局数组$_POST中。 - 限制:如果格式不是上述两种(例如是
application/json),PHP 的解析引擎就不会动作,$_POST就会保持为空。
逻辑 B:原始读取到 php://input
php://input 是一个只读的流(Stream),它直接指向 HTTP 请求的 Body 原始区域:
- 它不经过 PHP 的“解析引擎”,因此不需要关心
Content-Type。 - 它直接访问内存中存放 Body 字节流的地址。
- 结果:无论你发的是什么(JSON、XML、甚至是乱码),只要它在 Body 里,
file_get_contents('php://input')就能抓到一模一样的原始字符串。
2.字符的两种表达等价性
在 JSON 规范(RFC 8259)中,字符可以有两种表示方式:
- 字面值:直接输入
a。 - 转义序列:输入
\u0061。
(\u0061 属于 Unicode 编码,更具体地说,它是 Unicode 字符的十六进制转义表示法。)
在 JSON 解析引擎 的逻辑里,这两者是完全等价的。\u 后面的四位十六进制数对应 Unicode 编码表中的位置,61(十六进制)在十进制中是 97,即字母 a。
题目叫做 Encode & Encode,猜测跟编码有关
点击Source Code,查看http://15fa3901-c00c-427e-be0d-b813ff0bd2d3.node5.buuoj.cn:81/query.php?source
得到源码
1 | <?php |
1.绕过exit()
url中去掉source
2.绕过正则
传入json格式的page值本应为 php://filter/convert.base64-encode?resource=/flag
这里把输出内容变成了64编码已经绕过了后面的$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{<censored>}', $content);
只需要绕过前面伪协议和flag就行
这里考虑Unicode 编码绕过
具体地说, 用Unicode 字符的十六进制转义表示法绕过
看一下运行顺序:
1 | 1.Unicode还原成正常字符 |
那么只要把php://filter/convert.base64-encode?resource=/flag的php和flag用unicode编码就行
https://www.tandaima.com/unicode.html
1 | \u0070\u0068\u0070://filter/convert.base64-encode?resource=/\u0066\u006c\u0061\u0067 |

解码得到flag

