弱类型
一、基本数据类型比较
1. php.net网站上有专门的基本数据类型比较
<?php
$a = '';
$b = '0';
$c = ' ';
$d = null;
$e = 0;
var_dump($a == $b);//false
var_dump($a == $c);//false
var_dump($a == $d);//true
var_dump($a == $e);//true
var_dump($b == $c);//false
var_dump($b == $d);//false
var_dump($b == $e);//true
var_dump($c == $d);//false
var_dump($c == $e);//true
var_dump($d == $e);//true
2. 下面这些函数也是弱类型函数
isset()
empty()
is_null()
二、字符串与数字进行比较 会发生字符串向数字的转换
1. 当字符串与字符串比较时,通过看值是否完全一致,不一致则不同
2. 空字符串和null一致
3. 其他数据类型与数字比较时 会转化为数字进行比较
(1)当字符串与数字进行比较时,字符串会转化为数字
从左往右取,取到非数字停止,如果没有取到数字,则直接返回0
var_dump("admin" == 0); //true
var_dump("1admin" == 1); //true
var_dump("admin1" == 1); //false
var_dump("admin1" == 0);//true
(2) null == 0
三、0x 开头的字符串 当作16进制
php低版本才行 在5.x 左右的版本 才生效
当字符串中出现0x 当作16进制
var_dump('0x1046A'== 66666);
四、0e 开头 0的多少次方
科学技术法
3e2 = 300
0e321 == 0
0e2115523423 == 0
'0e3212313'=0
五、in_array 默认弱类型 除非第三个参数设置为true
<?php
$a = $_GET['input'];
$arr = array(0,1,2);
preg_match('/\d+/', $a, $match);
if ($match)exit("不允许使用数字");
if (in_array($a, $arr)){
echo 'ok';
}
//自定义in_array_div实现in_array
function in_array_div($needle,$haystack,$strict = false){
foreach($haystack as $v){
if($v == $needle && !$strict ){
return true;
}
elseif($v === $needle){ return true;}
}
return false;
}
$arr = array(0,1,2);
var_dump(in_array_div('0',$arr));
六、strcmp 字符串比较
1. strcmp函数,两个字符串比较
左边 < 右边 返回 -1
左边 = 右边 返回 0
左边 > 右边 返回 1
secret.php 中$a的值为随意字符串,$a = 'sdasdafadfasdgwrqw34234,;554asfasdfasd';
<?php
include 'secret.php';
$b = $_GET['b'];
var_dump($b);//
if (@strcmp($a, $b) == 0) {
echo "success";
} else {
echo "failed";
}
解题思路:
<?php
$a = array(1);
$b = 'z';
var_dump(strcmp($a,$b));
当数组与字符串比较 返回null,而null == 0 ,从而输出success
七、md5 函数
1. 数组 返回null
<?php
$a = $_GET['a'];
$b = $_GET['b'];
if ($a != $b && md5($a) == md5($b)) {
echo 'ok ';
}
strcmp的时候用的是数组,这里也测试下
发现对数组进行md5加密的时候返回null
那么这里传两个数组即可
2. hash碰撞
(1) md5和md5的hash碰撞
<?php
$a = $_GET['a'];
$b = $_GET['b'];
if (is_string($a) && $a != $b && md5($a) == md5($b)){
echo 'ok';
}
当限制,必须传字符串的时候
网上搜的两个特殊的值,是字符串,并且值不相同,但是它们的md5值是相同的
QNKCDZO
240610708
md5('QNKCDZO') = '0e830400451993494058024219903391'
md5('240610708') = '0e462097431906509019562988736854'
因为0e特性,所以两个md5都和0相等,两个md5相等
(2) 字符串和md5的hash碰撞
<?php
if ($_GET['a'] == md5($_GET['a'])) {
echo 'ok';
}
创0e开头后面跟数字的字符串,并且md5的值也是0e开头后面数字
脚本(百度搜下绕过for最大限制):
<?php
$a = '0e';
for($i=0;$i<=9999999;++$i){
$md5 = md5($a.$i);
preg_match('/^0e\d+$/',$md5,$match);
if($match){
echo 'now the $a is '.$i.'<br>';
return ;
}
}
跑出来的值为 0e215962017
md5('0e215962017') = 0e291242476940776845150308577824
'0e215962017' = 0
'0e291242476940776845150308577824' = 0
所以二者相等
(3) 强hash碰撞,限制md5的值必须全等
flag.php中 $flag = "flag:bihuo.cn"
<?php
include('flag.php');
highlight_file(__FILE__);
if ((string)$_GET['a'] !== (string)$_GET['b'] && md5($_GET['a']) === md5($_GET['b'])) {
echo "$flag";
} else {
echo "NONONO";
}
网上有这样的两个值,它们值不一样,但是md5值一模一样:
$data_1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
$data_2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2
八、json_decode 保留数据类型 生成对应的stdclass对象
$a = 'helloworld';
<?php
include "test12345.php";
if (isset($_GET['message'])) {
$message = json_decode($_GET['message']);
if ($message->key == $a) {
echo 'ok';
} else {
echo 'fail';
}
}
<?php
$arr = array('key'=>0);
echo json_encode($arr); //{'key':0}
当传入{'key':0}的时候json_decode解码之后,生成一个stdclass对象
$a = json_decode("{'key':0}");
$a->key = 0
九、array_search 默认弱类型 除非第三个参数设置为true
功能: array_search在数组中搜索特定的值,返回对应的key值,找不到也返回0
<?php
if (!is_array($_GET['bihuo'])){
die();
}
$bihuo = $_GET['bihuo'];
for($i = 0; $i < count($bihuo); ++$i){
if($bihuo[$i] === 'bihuo.cn'){
echo 'no';
die();
}
$bihuo[$i] = intval($bihuo[$i]);
}
if (array_search('bihuo.cn', $bihuo) === 0){
echo 'ok, you get it ';
}
else{
echo 'no, you failed';
}
//是不是就相当于在一个数组中,找寻对应的键值对,
//需要满足该键值对中的value=bihuo.cn,
//然后返回对应的键值对中的key的值
array(0=>0)
?bihuo[0]=0
$bihuo = 0
array_search('bihuo.cn',[0=>0])
就是if('bihuo.cn'== 0) 是相等的
所以返回键的值 0
//自定义array_search_div实现array_search
function array_search_div($needle,$haystack,$strict=false){
foreach ($haystack as $k=>$v){
if(!$strict && $v == $needle){
return $k;
}elseif ($v === $needle){
return $k;
}
return false;
}
}
$arr = array('key'=>'bihuo','aaa'=>'bihuo15');
var_dump(array_search_div('bbb',$arr,true));
十、switch
<?php
$a = $_GET['a'];
switch ($a){
case 0:
echo '0';
break;
case 1:
echo '1';
break;
default:
echo 'default';
break;
}
原理也是
if($a == 0)
if($a == 1)