PHP弱类型问题
首先,我们要明确PHP弱类型源于PHP本身就是弱类型语言,它不会严格检验变量的类型。变量可以不显式地声明其类型,而是在运行期间直接赋值。PHP中的等号(=)有多种情况,具体表述如下:
❑= 赋值。
❑== 弱类型比较,先将两端的数据类型进行转换。
❑=== 强类型比较,不转换数据类型,直接比较。
PHP的弱类型问题主要体现在两个变量之间进行弱类型比较(==)的 时候:如果两个变量的类型不一致,就会对变量进行类型转换,变成同一类型,在这个转换过程中,会出现一些特殊情况。 下面,我们针对这些情况讲解CTF Web中常见的考点。
1.科学记数法与MD5值比较
当字符串的格式为“0e+纯数字”时,例如0e12314,PHP会将其按科学记数法进行处理,计算结果一定是0。下面给出 几个示例。(注意等号个数!)

考点分析
在CTF Web中,一般不会对科学记数法单独进行考查,而是会结合其 他函数(例如MD5函数)进行考查。通过之前的学习我们知道,MD5 值应该是唯一的(理论上),所以想找到两个MD5值相等的字符串是 非常困难的。但在结合科学记数法和弱类型的情况下,是存在相等这 种可能性的,具体代码如下:
注:- MD5是一种消息摘要算法(Message - Digest Algorithm 5),在PHP中主要用于对数据(如字符串、文件内容等)进行加密(更准确地说是生成消息摘要)操作。它会将任意长度的数据转换为一个固定长度(128位,通常以32位十六进制字符串表示)的哈希值。

由于是弱类型比较(==),因此可以考虑借助科学记数法进行 绕过,只要提交的字符串以0e开头,后面全是数字即可。

只要使用以上任意两个字符串,即可实现绕过。
还可以通过另一种方法实现绕过
原理:在PHP中,md5()函数只 能用于处理字符串。如果传递过来的数据类型无法被处理(例如数 组),那么md5()函数会返回NULL,导致出现NULL==NULL的情况。

使用数组方式绕过md5()函数时,并不在意使用强类型比较还是弱类型比较,因为NULL==NULL, NULL===NULL,所以,在MD5比较中,数组方式应用得更广泛一些
2.科学记数法比较大小
一般都是设置输入数据的最大长度,然后给出一个更大的数(起码从长度上体现),然后做比较。
比如:最大的3位数是几?
答案并不是999
这个数字可以更大,那就是9e9

其中time()函数是一个时间戳函数,其返回的数字并不是当前的时间,而是自UNIX纪元(格林威治时间1970年1月1日 00:00:00)起到当前时间的秒数。所以该数值的长度显然是大于4的。
所以你就可以提交9e99
3.strcmp 函数问题
strcmp(str1, str2)函数用于对两个字符串进行比较。比较的规则是逐字节比较(根据其ASCII码来比较大小),如果str1>str2,则返回值>0;如果str1<str2,则返回值<0;如果str1=str2,则返回0。类似C语言中的strcmp 函数。

$password变量通过GET请求进行赋值,请求参数为password,如果password参数的值等于’This is password’,那么就输出Right(strcmp的结果为0),否则就输出Wrong(strcmp的结果非 0)
在实际的CTF Web题目中,假设让我们比较的字符串本身是未知的,strcmp()函数本身只能用于比较字符串,这时如果传递其他类型的数据(例如数组),就会导致函数出错,从而返回NULL (0)。