[BUUCTF] 极客大挑战 BuyFlag

本文解析CTF题目中利用PHP弱类型特性,通过构造特定payload绕过认证的过程。介绍is_numeric()函数及弱类型的原理,演示如何利用科学计数法和数组形式的money参数获取flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x1分析题目

像往常一样拿到题目后寻找有用的信息,在pay.php中看到了我们此次的目标
在这里插入图片描述有一个身份认证,还需要一个正确的密码。查看源码我们发现了一段代码:


	~~~post money and password~~~
if (isset($_POST['password'])) {
	$password = $_POST['password'];
	if (is_numeric($password)) {
		echo "password can't be number</br>";
	}elseif ($password == 404) {
		echo "Password Right!</br>";
	}
}

审计一下,我们需要post password,然后通过is_numeric()函数的检测,如果password==404则输出正确。在这里提一下is_numeric()函数弱类型

0x2知识点

is_numeric()函数

检测字符串是否只由数字组成,如果字符串中只包括数字,就返回Ture,否则返回False。举几个例子: 123 ,12.3 ,+123这些都能返回true,但是如果字符串中含有别的符号或者字母则返回false。

PHP弱类型

PHP中有== 和 ===两种比较方法,前者比较之前会把等号两边的数据类型转换成相同的,后者在比较之前要先判断数据类型是否相同,我们称前者为PHP的弱类型,因为很容易发生“意外情况”。

var_dump("a"==0); //true;
var_dump("1a"==1); //true;
var_dump("a1"==1) //false;
var_dump("a1"==0) //true
以这几个为例,我们可以看到字符直接被转换成了0,如果字符前面有数字则字符串等于数字,这种弱类型经常出现在ctf的题中。

还有一个特殊一点的:
var_dump("0e123456"=="0e4456789"); //true
因为科学计数法0的任意次方都等于0,所以这种类型也相等。

0x3构造payload

回到题目,我们可以利用这两个知识点构造出password=404a,抓包后联想一下之前的身份验证,cookie改为1,把money=1000000000,最后post上去,并没有出flag,提示说money太长了,试一下科学计数法,money=1e9,出现了flag。

看了别人的wp之后发现这里money其实是用来strcmp()函数比较,这个也是经常碰到的,strcmp(a,b),如果a<b返回负数,如果a>b返回正数,如果a=b返回0。

但是!如果a,b的类型不匹配,它会报错返回0,这就很致命了,明明数据类型不匹配但是判定相等了,所以我们只要把money以数组的形式上传就好了。money[]=a,也能出现flag。
话不多说,上图!
在这里插入图片描述在这里插入图片描述结果是一样的。

ps:若有不足之处,欢迎大佬们及时斧正,感谢您的观看!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值