[NSSCTF 2022 Spring Recruit]babyphp

题目源码

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在处理不同类型数据时的特性来绕过限制:

  1. 第一层:利用数组绕过正则和intval检查

  2. 第二层:利用数组使md5()返回NULL,通过严格比较

  3. 第三层:利用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}

相关推荐
FLJwu4 小时前
存储与固件量产实战01:运动相机TF卡量产翻车实录!V30≠4K可用,90%OEM踩中的隐形售后坑
经验分享·数码相机·相机
xiaomu001235 小时前
床垫选型的技术评估模型:结构、材料、卫生与检测四层口径
经验分享
汉风设计装饰6 小时前
智慧办公弱电系统设计:门禁、监控与 IoT 传感器的集成方案
经验分享
m0_719640876 小时前
支持开源二次开发的VR遥操机器人2026年选型推荐
经验分享
陈卫军老师6 小时前
陈卫军:把口味写在一张纸上,店才稳得住
经验分享·笔记·流量运营
从零开始的嵌入式之旅8 小时前
day47
arm开发·经验分享·笔记·嵌入式硬件
恒锐丰科技林技术员8 小时前
EG1164 高压大电流升压同步整流芯片解析
经验分享·嵌入式硬件·硬件工程
欣悦财务9 小时前
怎么判断代理记账收费值不值,把费用折成服务密度再比
经验分享
灰山君10 小时前
企业三维可视化怎么选?山海鲸可视化与老子云3D优势对比
大数据·经验分享·数字孪生·可视化·数据可视化·实时大数据
虹科数字化与AR1 天前
FME与Python脚本做工程数据转换,如何选择?
经验分享