PHP弱类型
== 和 === 的区别
强类型比较:===
强类型比较在进行比较的时候,会先判断两种字符的类型是否相等,在比较数值
弱类型比较:==
弱类型比较在进行比较的时候,会先将字符串类型转换成相同的类型,再比较,中间有一个强转的过程(优先转换为数字类型) —重点
在弱比较(=)如果比较一个数字和字符串 或者 比较涉及到数字内容的字符串,首个字符串值会被转换成数值,并按照数值来进行比较
1 2 3 4 5 6
| <?php var_dump("admin"==0); var_dump("2admin"==1); var_dump("admin" == 2); var_dump("admin" ==0); var_dump("0e123456"=="0e654321");
|
注意
1、和布尔型比较
在布尔值之间进行比较的时候,0 和 ‘’ 空字符串,都代表false,' ',非空的字符串,代表非false
1 2 3 4
| <?php var_dump(0==false); var_dump(''==false); var_dump(' '==false);
|
2,单引号0意味着等于空
思考: 为什么会存在‘0’和 布尔值之间的比较
总结:’0’ 字符串’0’ “0”等于空等于false
3、‘0’等于 ‘ ’二者又不相等
注意以前: ‘’ 引号里面没有内容,代表false, ‘0’引号里面有个0,也代表false
奇怪的特性死记硬背
当‘0’单引号0和 别的数据相比较时,‘0’单引号0意味着等于‘’空 等于false
但是‘0’单引号和‘’空相比较时,他们二者又不相等
1 2 3
| <?php var_dump('0'==false); var_dump(''=='0');
|
4、0e开头的字符串比较hash值比较
在进行比较运算时,如果遇到了0e这类字符串,PHP会将它解析为科学计数法。
PHP它把每一个以”0E”开头的哈希值都解释为0,
如果两个不同的数据参数值经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0
1 2
| <?php var_dump("0e1234" == "0e4567");
|
哈希值0e开头的,不同密码值
1 2 3 4 5 6 7 8 9
| 0e开头的md5和原值: QNKCDZO 0e830400451993494058024219903391 240610708 0e462097431906509019562988736854 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469
|
5、0x开头的字符串比较
在进行比较运算时,如果遇到了0x这类字符串,PHP会将它解析为十六进制
所谓的弱类型比较漏洞,也就在在进行比较判断下一步执行行为的时候,可以利用该漏洞,实现一个
最终结果为真的 一个 返回值
1 2
| <?php var_dump("0x1046a" == "66666" );
|
6、in_array
重点:函数搜索 比较的时候,是有可能存在弱类型比较漏洞的
1 2 3 4 5 6 7 8 9 10
| <?php $arr1 = array("hello","nihao","wohao") ; $brr1 = "hello";
if(in_array($brr1,$arr1)){ echo "在数组中"; }else{ echo "不在数组中"; }
|
关键在于in_array的第三个参数:
- true 代表=== 强类型比较
- false 代表== 弱类型比较
默认为false
1 2 3 4 5 6 7 8 9 10
| <?php $arr1 = array(0,"nihao","wohao") ; $brr1 = "hello";
if(in_array($brr1,$arr1)){ echo "在数组中"; }else{ echo "不在数组中"; }
|
7、strcmp()字符串比较 -Ascii码
1 2 3 4 5 6 7 8 9
| 注意:此比较区分大小写 用途:比较括号内的两个字符串string1和string2的大小 语法:strcmp(string $string1, string $string2): int 返回: str1等于str2时候,返回0 str1大于str2时候,返回1 str1小于str2时候,返回-1
略记: strcmp -二进制安全字符串比较
|
在5.3及以后的php版本中,当strcmp()括号内是一个数组与字符串比较时,也会返回0。
结论:进行字符串进行比较的时候,比较的是,第1个字符的值,第1个字符的值,决定了整个比较结果
进行比较的时候,只比较字符串,只比较ascii码,含有特殊意义的字符,也只会被认为是字符,并不会具有特殊意义
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php $a ='abc'; $c = 'dbc'; echo strcmp($a,$c); echo "<br>";
$a ='abc'; $c = 'Abc'; echo strcmp($a,$c); echo "<br>";
$a ='abc'; $c = 'abc'; echo strcmp($a,$c);
|
ASCII码对照表
8、MD5比较–利用条件苛刻
注意:在进行 MD5 弱类型比较漏洞利用的时候,必须是对方也使用了MD5(数组)的情况下,才有可能利用成功
用途:计算字符串的 MD5 散列值
当你传递一个array时,md5()不会报错,只是会无法正确地求出array的md5值,返回null,
这样就会导致任意2个array的md5值都会相等。
1 2 3 4 5 6 7 8 9
| <?php $a = array("abcde"); $b = array("qwerio"); if ($a != $b && md5($a) == md5($b)){ echo '比较的值相等'; }else{ echo '比较的值不相等'; }
|
9、Json_decode相关的弱类型比较
注意:变量不变量并不重要,重要的是,我们可以通过key,取到对应的值

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php $a="ssss";
$message = json_decode('{"b":"ssssb"}'); if($a === $message->b) { echo "ok"; }else{ echo "no"; }
<?php $json_str = '{"a":1,"b":2,"c":3}'; $ret =json_decode($json_str,true); var_dump($ret);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php $a="admin";
if (isset($_GET['message'])) { $message = json_decode($_GET['message']); if ($message->key == "admin"){ exit(); } if ($message->key == $a) {
echo '你比较的值二者相等'; } else{ echo '失败'; } }
|
10、Array_search弱类型
array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名,也是通过 == 进行比较的
1 2 3 4 5 6
| <?php $array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); $key = array_search('red', $array); ?>
|
1 2 3 4
| <?php $a=array("a"=>"llll","b"=>0,"c"=>"blue"); echo array_search("red",$a); ?>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php if (!is_array($_GET['cmd'])){ die(); } $cmd = $_GET['cmd']; for($i = 0; $i < count($cmd); ++$i){ if($cmd[$i] === 'admin'){ echo 'no'; die(); } $cmd[$i] = intval($cmd[$i]); }
if (array_search('admin', $cmd) === 0){
echo 'flag'; } else{ echo 'no, you failed'; }
|
11、Switch比较缺陷
//本质上switch 做了一个弱类型比较 //$a==’hello’?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php $a = 0;
switch ($a){ case 'hello': echo 'hello'; break; case 0: echo 0; break; default: echo '没找到'; }
|