极客大挑战2023-web-easy_php
·
<?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修饰符,代表大小写不敏感。因此我们只需要改变原字符串中任意一个字母的大小写即可绕过。 - Payload:
syc=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。
- Payload:
lover=2e9
第三关:SHA1 强比较 ($qw 和 $yxx)
if (isset($_POST['qw']) && $_POST['yxx']) {
$array1 = (string)$_POST['qw'];
$array2 = (string)$_POST['yxx'];
if (sha1($array1) === sha1($array2)) { ... }
- 分析:要求传入 POST 参数
qw和yxx,且yxx为弱真(不能为 0 或空)。参数被强制转换为字符串后,它们的 SHA1 值必须强相等 (===)。 - 解法:这段代码其实是个“纸老虎”。它并没有限制
$array1 !== $array2(即没有要求两个参数不同)。所以我们不需要用数组绕过,直接给这两个参数赋完全相同的真值即可。 - Payload:
qw=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

更多推荐


所有评论(0)