[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}

相关推荐
一滴泪的时间13 小时前
2026RFID 涉密载体管控系统推荐,实现密件全流程闭环管控
经验分享·政务
ZICK_ZEON1 天前
Vue拼接字符串的几种办法
经验分享
哎写bug的程序员1 天前
【无标题】
经验分享
kingx31 天前
Windows Server安全配置深度复盘:关键 Payload 与解题思路
windows·靶场·web·加固
灰度少爷2 天前
Everything 三款实用插件:拼音搜索、双击 Ctrl 启动与 EverythingToolbar 扩展
经验分享
kingx32 天前
网络安全事件应急响应:X集团 WebServer 入侵溯源与处置
中间件·web·应急响应·取证·恶意样本
中云DDoS CC防护蔡蔡2 天前
DDOS和CC攻击谁更可怕
运维·服务器·经验分享·网络安全·ddos
上海广测检测科技有限公司2 天前
蓝牙音箱的 BQB 认证:音频服务层组合、引用链判定与测试状态设定
经验分享
网安小学生(兼顾数据库版)2 天前
Black Duck 退出中国市场后,替代方案怎么选?5 项核心能力评估
经验分享
AAwangzong2 天前
AI时代RPA技术解析:如何构建兼顾流程执行与智能决策的自动化平台?
人工智能·经验分享·rpa·智能体