题目环境:
FLAG NEED YOUR 100000000 MONEY flag需要你的100000000元
F12瞅瞅源代码:
if (isset($_POST['password']))
{
$password = $_POST['password'];
if (is_numeric($password))
{
echo "password can't be number"
}
elseif ($password == 404)
{
echo "Password Right!
}
}
PHP代码审计:
两个通过POST方式传参的参数password和money isset函数判断参数是否存在以及值是否为空,存在及不为空则返回TRUE is_numeric() 函数用于检测变量是否为数字或数字字符串;这里需要注意数字字符串的意思就是字面意思通过数字组成的字符串,比如:“123456789” 如果是数字或者是数字字符串就会输出"password can’t be number" 如果password是404则密码就是正确的
当password是404的时候虽然满足了第二个elseif语句但是不满足第一个if语句 因为404是数字和数字字符串 想要满足第一个简单,让password成为普通字符串就可以,404a、404b、404c、404%10、404,%20、404%30等等 这样第二个条件也顺便满足了,为什么呢?(在比较的时候把值转换成了数字字符串) "=="是PHP弱比较逻辑运算符
PHP弱比较:
PHP中的弱比较(Weak comparison)是一种比较两个值是否相等的方法,但它不会对两个值进行严格的全等比较。相反,它允许某些类型的值在比较时进行自动类型转换。 弱比较使用以下规则:
传参并使用burpsuite进行抓包
password=404a&money=100000000
先通过火狐浏览器插件Max HackBar进行POST传参,再抓包,这样数据包就是POST传参方式,如果直接在数据包里面把GET方式传参改为POST方式传参的话,可能依旧是GET方式传参,这点需要注意。
鼠标右键Repeater->Send进行重放
仅学生用户可以购买FLAG 注意Cookie:user=0 user是用户,0通常代表flase(错误),1通常代表true(正确) 咱们将user修改为1使后台程序可以正常运行
修改user=1 继续Send进行重放
用户和密码都绕过了 Nember lenth is too long 你的数字太长了 到这里想到了使用科学计数法绕过 1e9代表1的后面有9个0 => 1000000000 > 100000000 (要大于题目要求的money值!) 既满足了条件,数字长度也不长
使用科学计数法绕过money:
password=404a&money=1e9
当money=1时
you have not enough money,loser 你没有足够的钱
经过给money参数分情况测试,有3种输出结果
猜测用到了函数strcmp()用来比较两个字符串,同时还可以比较两个字符串的字符数
strcmp(string1,string2)
所以当过滤不当不全时,可以通过将参数变为数组的方式进行绕过,这样的话就无法比较,直接返回true
这里大胆猜测他的后台源码:
<?php
$flag=100000000;
$Flag='flag{0c531ed2-9c1e-479a-adcb-d975b1376ca6}'
if (isset($_POST['money'])) {
if (strcmp($_POST['money'],$flag) == 0)#比较money和flag的值和字符数,"=="PHP弱比较逻辑运算符
echo $Flag;
elseif(strcmp($_POST['money'],$flag) < 0)
print 'you have not enough money,loser';
else
print 'Nember lenth is too long';
}
?>
通过数组绕过money:
password=404a&mony[]=0
中途我2023版Burp里面的Repeater消失不见了,这里问下师傅们,现在不知道怎么回事,所以我又用2021版本Kali做题了,苦涩
得到flag:
flag{cb3acdc3-dcda-49d0-9597-b7247f9c6ff0}