<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);

highlight_file(__FILE__);
include_once('flag.php');
if(isset($_GET['syc'])&&preg_match('/^Welcome to GEEK 2023!$/i', $_GET['syc']) && $_GET['syc'] !== 'Welcome to GEEK 2023!') {
    if (intval($_GET['lover']) < 2023 && intval($_GET['lover'] + 1) > 2024) {
        if (isset($_POST['qw']) && $_POST['yxx']) {
            $array1 = (string)$_POST['qw'];
            $array2 = (string)$_POST['yxx'];
            if (sha1($array1) === sha1($array2)) {
                if (isset($_POST['SYC_GEEK.2023'])&&($_POST['SYC_GEEK.2023']="Happy to see you!")) {
                    echo $flag;
                } else {
                    echo "再绕最后一步吧";
                }
            } else {
                echo "好哩,快拿到flag啦";
            }
        } else {
            echo "这里绕不过去,QW可不答应了哈";
        }
    } else {
        echo "嘿嘿嘿,你别急啊";
    }
}else {
    echo "不会吧不会吧,不会第一步就卡住了吧,yxx会瞧不起你的!";
}
?>

第一关:正则表达式与严格比较绕过 ($syc)

if(isset($_GET['syc'])&&preg_match('/^Welcome to GEEK 2023!$/i', $_GET['syc']) && $_GET['syc'] !== 'Welcome to GEEK 2023!')
  • 分析:要求传入的 GET 参数 syc 必须匹配正则表达式 ^Welcome to GEEK 2023!$,但又不能全等于字符串 'Welcome to GEEK 2023!'
  • 解法:注意正则表达式最后有一个 /i 修饰符,代表大小写不敏感。因此我们只需要改变原字符串中任意一个字母的大小写即可绕过。
  • Payloadsyc=welcome to GEEK 2023! (将首字母 W 改为小写 w)

第二关:intval() 弱类型转换绕过 ($lover)

if (intval($_GET['lover']) < 2023 && intval($_GET['lover'] + 1) > 2024)
  • 分析:要求 lover 的整数部分小于 2023,但对其加 1 后再取整又要大于 2024。
  • 解法:利用科学计数法特性。当我们传入 2e9(即 2×1092 \times 10^92×109)时:
    • intval('2e9') 会从左到右解析字符串,遇到非数字字符 e 停止,返回结果为 2,满足 < 2023
    • 而在执行 intval($_GET['lover'] + 1) 时,PHP 会先进行算术运算,触发隐式类型转换,'2e9' 被当做浮点数运算变成了 2000000000 + 1。最终结果为 2000000001,满足 > 2024
  • Payloadlover=2e9

第三关:SHA1 强比较 ($qw$yxx)

if (isset($_POST['qw']) && $_POST['yxx']) {
    $array1 = (string)$_POST['qw'];
    $array2 = (string)$_POST['yxx'];
    if (sha1($array1) === sha1($array2)) { ... }
  • 分析:要求传入 POST 参数 qwyxx,且 yxx 为弱真(不能为 0 或空)。参数被强制转换为字符串后,它们的 SHA1 值必须强相等 (===)。
  • 解法:这段代码其实是个“纸老虎”。它并没有限制 $array1 !== $array2(即没有要求两个参数不同)。所以我们不需要用数组绕过,直接给这两个参数赋完全相同的真值即可。
  • Payloadqw=1&yxx=1

第四关:PHP 变量名解析特性绕过 (SYC_GEEK.2023)

if (isset($_POST['SYC_GEEK.2023'])&&($_POST['SYC_GEEK.2023']="Happy to see you!"))
  • 分析:要求存在 POST 参数 SYC_GEEK.2023。后面的 = 是赋值操作,只要参数存在,赋值后就会返回 true。难点在于,PHP 在接收外部参数时,会自动将参数名中的点号(.)空格替换为下划线(_)。如果直接发送 SYC_GEEK.2023,PHP 后端接收到的会是 SYC_GEEK_2023,导致 isset 验证失败。
  • 解法:利用 PHP 的特殊解析规则。如果参数名中包含左中括号 [,PHP 会将第一个 [ 替换为下划线 _,并停止替换后续字符中的点号和空格。
  • Payload:发送 SYC[GEEK.2023=1。PHP 处理时,[ 被替换为 _,后面的 . 被保留,最终被解析为服务器期望的 SYC_GEEK.2023

更多推荐