一、php弱类型简介
1、弱类型导致的问题
可以看到intval在遇到不能转换的字符串时,并没有报错,而是将返回值置0
2、弱类型导致松散比较的问题
3、比较举例
'0e123' == 0 #true
'0e123’会被当成科学计数,相当于0的123次幂等于0,和数字0比较
'0e123' == '0e321' #true
0的123次幂和0的321次幂都等是零
'0x10' == 16
‘0x10’ 被php识别为16进制的10,对应的是10进制的16,都等于16
false == "" == 0 == NULL #true
false在和数字比较时被转化为0,同理true会被转化为1,""为字符串,比较时会先将字符串转为数字不能转换的字符串或NULL会被转换成0
"app" == 0
"app"被转化为0,和0比较,转换为0
更多松散比较的例子:
二、CTF中弱类型的应用
demo1:
<?php
highlight_file(__FILE__);
include('flag.php');
if (isset($_POST['a'])&isset($_POST['b'])) {
if ($_POST['a']!=$_POST['b']) {
if (md5($_POST['a']) == md5($_POST['b'])) {
echo $flag;
}else {
echo 'fail!';
}
}
}
问题分析
这个时候我们就需要用到之前松散比较的例子:
'0e123' == '0e321' #true
这个时候我们只需要找到两个字符串经过md5加密后,满足0e+30个纯数字就能满足我们的条件
事实上这样的字符串是存在的,在此举例几个:
demo2:
<?php
highlight_file(__FILE__);
include('flag.php');
if (isset($_POST['a'])&isset($_POST['b'])) {
if ($_POST['a']!=$_POST['b']) {
if (md5($_POST['a']) === md5($_POST['b'])) {
echo $flag;
}else {
echo 'fail!';
}
}
}
问题分析
我们将设给md5传入一个数组,看看会出现什么情况:
当我们给md5传入数组时,函数报出了警告,但是它并没有退出,而是返回了NULL,那么我们将a、b都传入数组的话,md5返回的数值都为NULL,NULL和NULL比较返回的就是true
demo3:
<?php
highlight_file(__FILE__);
include('flag3.php');
if(isset($_POST['a'])){
$temp = json_decode($_POST['a']);
if($temp->key == $flag){
echo $flag;
}else{
die('ERROR!');
}
}
问题分析
那么我们只需要传入一个json数据中包含数字的值和0比较就能返回true