
题目源码
php
<?php
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){
if(isset($_POST['b1'])&&$_POST['b2']){
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){
echo $flag;
}else{
echo "yee";
}
}else{
echo "nop";
}
}else{
echo "go on";
}
}else{
echo "let's get some php";
}
?>
核心思路
这道题通过三层条件验证,利用PHP在处理不同类型数据时的特性来绕过限制:
-
第一层:利用数组绕过正则和intval检查
-
第二层:利用数组使md5()返回NULL,通过严格比较
-
第三层:利用MD5弱比较碰撞(0e开头字符串)
逐层分析
第一关:参数 a 的绕过
php
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a']))
限制条件:
-
a参数必须存在 -
不能包含任何数字字符(0-9)
-
intval($_POST['a'])必须返回真值(非0)
绕过方法:
当 $_POST['a'] 是数组时:
-
isset($_POST['a'])→ true ✓ -
preg_match('/[0-9]/', $_POST['a'])→ 因为期望参数2是字符串但收到数组,返回false并产生警告,!false→ true ✓ -
intval($_POST['a'])→ 对数组类型调用intval()返回1(非0值)→ true ✓
Payload: a[]=1
第二关:参数 b1 和 b2 的绕过
php
if(isset($_POST['b1'])&&$_POST['b2']){
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){
限制条件:
-
b1 和 b2 必须存在且非空
-
b1 和 b2 的值必须不相等(
!=) -
两者的 MD5 值必须完全相等(
===严格比较)
绕过方法:
同样使用数组类型:
-
isset($_POST['b1']) && $_POST['b2']→ 两个数组都存在,条件成立 ✓ -
$_POST['b1'] != $_POST['b2']→ 两个不同的数组,比较结果为 true ✓ -
md5($_POST['b1']) === md5($_POST['b2'])→-
md5()函数处理数组时返回NULL -
NULL === NULL→ true ✓
-
为什么要用 b1 和 b2 作为数组?
如果用字符串寻找MD5碰撞,需要找到两个不同的字符串具有完全相同的MD5值(哈希碰撞),这在计算上非常困难。而利用PHP的类型特性,可以轻松绕过。
Payload: b1[]=240610708&b2[]=QNKCDZO
注意: 这里数组的值可以任意,只要两个数组不同即可。
第三关:参数 c1 和 c2 的绕过
php
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2']))
限制条件:
-
c1 和 c2 必须存在且不相等
-
c1 和 c2 必须是字符串类型
-
两者的 MD5 值使用弱比较(
==)相等
绕过方法:
使用两个字符串,它们的MD5值都以 0e 开头(科学计数法表示的数字0)。
在PHP的弱比较(==)中:
-
0e123456会被解释为0 × 10^123456=0 -
0e789012同样等于0 -
因此
0 == 0成立 ✓
经典的MD5碰撞对:
-
QNKCDZO→ MD5:0e830400451993494058024219903391 -
s878926199a→ MD5:0e545993274517709034328855841020
两者都以 0e 开头,在弱比较时都等于0。
Payload: c1=QNKCDZO&c2=s878926199a
完整PayloadPOST
php
a[]=1&b1[]=240610708&b2[]=QNKCDZO&c1=QNKCDZO&c2=s878926199a

得到flag
NSSCTF{cffb2f7e-e90f-450a-bda0-d1d36c101cc1}