未命名

PHP 代码审计题解题思路

PHP 代码审计题解题思路

代码结构分析

这道题是一个多层条件绕过的CTF题目,需要依次绕过三层条件才能获取 $flag

┌─────────────────────────────────────────┐ │           第一层:变量 a 的校验           │ ├─────────────────────────────────────────┤ │           第二层:b1/b2 MD5绕过          │ ├─────────────────────────────────────────┤ │           第三层:c1/c2 MD5绕过          │ ├─────────────────────────────────────────┤ │                 拿到 flag               │ └─────────────────────────────────────────┘

第一层:$_POST['a'] 的绕过

原始条件:

!preg_match('/[0-9]/', $_POST['a']) && intval($_POST['a'])

要求:

  1. a 中不能包含数字 0-9

  2. intval(a) 必须为真(非零)

绕过方法:使用小数

a = 0.1
  • 没有数字字符 → preg_match 不匹配

  • intval("0.1")0(PHP会截断小数点前的部分)

第二层:b1/b2 MD5 强等于绕过

原始条件:

$_POST['b1'] != $_POST['b2'] && md5($_POST['b1']) === md5($_POST['b2'])

要求:

两个不同的字符串,它们的 MD5 值必须完全相等(强类型比较)

绕过方法:利用 MD5 碰撞(0e开头的字符串)

b1 = 240610708
b2 = QNKCDZO
字符串MD5 值
2406107080e462097431906509019562988736854
QNKCDZO0e830400451993494058024219903391
  • 都以 0e 开头 → PHP 视为科学计数法 0 × 10^n = 0

  • 0 === 0严格比较通过

  • 且两个原字符串不相等

第三层:c1/c2 MD5 弱等于绕过

原始条件:

$_POST['c1'] != $_POST['c2'] 
&& is_string($_POST['c1']) && is_string($_POST['c2'])
&& md5($_POST['c1']) == md5($_POST['c2'])

要求:

两个不同的字符串,MD5 值弱相等即可

绕过方法:使用字符串形式 0e 开头的 MD5

c1 = 0e215962017
c2 = 0e2912424762227764
字符串MD5 值
0e2159620170e934533575974867840142512....
0e29124247622277640e077632083503616920639....
  • PHP 的 == 比较会自动将 0e数字 转换为 0

  • 两个 MD5 值都被转为 0 == 0通过

最终 Payload

参数
a0.1
b1240610708
b2QNKCDZO
c10e215962017
c20e2912424762227764

请求方式: POST 请求

核心考点总结

层级考点PHP 特性
第一层正则绕过 + intval 特性小数点不影响 intval();正则 /\d/ 只匹配数字
第二层MD5 强类型比较=== 会比较类型,0e...0e... 都转为 float 0 才相等
第三层MD5 弱类型比较== 会类型转换,0e数字 自动转为科学计数法 0