| PHP弱类型 |
Hash比较(科学计数法)
"0e132456789"=="0e7124511451155" //true
"0e123456abc"=="0e1dddada" //false
"0e1abc"=="0" //true
十六进制转换
"0x1e240"=="123456" //true
"0x1e240"==123456 //true
"0x1e240"=="1e240" //false
字符串解析为十进制在进行比较
类型转换
Int转string
$var = 5;
方式1:$item = (string)$var;
方式2:$item = strval($var);
String转int : intval()函数
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
Ctf demo
if(intval($a)>1000) {
mysql_query(“select * from news where id=”.$a)
}
$a=1002 union… 造成sql注入
intval()
intval()转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。
即使出现无法转换的字符串,intval()不会报错而是返回0。
注:
在科学计数法字符串转换为数字时,如果 E 后面的数小于某个值会弄成 double 类型,再强制转换为 int 类型时可能会有奇妙的结果,测试发现某变量为 1e-1000 时已经可以触发这个漏洞绕过两个检查,使得某变量既大于 0 又不大于 0。
例如:
var_dump((int)('1e-1000')>0);
var_dump('1e-1000'>0);
结果
Command line code:1:
bool(true)
Command line code:1:
bool(false)
再如:
var_dump((int)('1e-10')>0);
var_dump('1e-10'>0);
结果
Command line code:1:
bool(true)
Command line code:1:
bool(true)
ereg()
字符串对比解析,ereg函数存在NULL截断漏洞,当ereg读取字符串string时,如果遇到了%00,后面的字符串就不会被解析。
注:这里的%00是需要urldecode才可以截断的,这是url终止符,且%00长度是1不是3
内置函数的参数的松散性
内置函数的松散性说的是,调用函数时给函数传递函数无法接受的参数类型。
md5()
$array1[] = array(
"foo" => "bar",
"bar" => "foo",
);
$array2 = 1;
var_dump(md5($array1)==var_dump($array2)); //true
Strcmp()
strcmp ( string $str1 , string $str2 ) : int
$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。
switch()
如果case判断值为int形,switch会将传入的参数转换为int类型
$i ="2abc";
switch ($i) {
case 0:
case 1:
case 2:
echo "i is less than 3 but not negative";
break;
case 3:
echo "i is 3";
}
“==”和’===’弱类型问题
==
:比较两侧的值,不同类型会自动转换为同种类型。如传参与整形比较->整形。传参与字符串比较->字符串
<?php
$a = $_GET['a'];
if ($a==1)
{
echo ‘vul->’.$a;
}
Payload : http://127.0.0.1/fuzz.php?a=1a
成功进入if条件语句中“===”
: 符号比较两侧的值和类型,但不是绝对安全的。在加减乘除中会自动进行整形转换。
DEMO:
<?php
$a = $_GET['a'];
$b = $_GET['b'];
if($a+$b===2)
{
echo 'vul->'.$a.'</br>'.$b;
}
Payload : "http://172.31.19.5/fuzz.php?a=1a&b=1b"
成功进入条件语句
修复策略
:intval强制类型转换或者过滤
In_array()函数使用不严谨导致的弱类型
if(in_array($_GET['id'],array(1,2,3,4,5)))
{
echo $_GET['id'];
}
Payload:"http://172.31.19.5/fuzz.php?id=1a"
成功转换
修复方式
开启函数中的参数strict=Ture ,传参使用intval修饰if(in_array(intval($_GET['id']),array(1,2,3,4,5),true))
is_numeric()十六进制转换字符
<?php
if(is_numeric($_GET['num']))
{
//echo $_GET['num'];
echo '</br>';
//假设这个插入进了mysql数据库,mysql数据库就会把十六进制转换成了字符串,这里为了方便用 Hex2String 函数代替
echo Hex2String($_GET['num']);
}
function Hex2String($hex){
$string=”;
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
?>
//输入http://127.0.01/equal.php?num=0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f21212729
//输出0x39393939393939393939393920756e696f6e20616c6c202873656c656374202748656c6c6f2121272
//输出9999999999999 union all (select ‘Hello!!’)
参考链接;https://blog.spoock.com/2016/06/25/weakly-typed-security/
https://skysec.top/2017/07/22/PHP%E5%87%BD%E6%95%B0%E9%BB%91%E9%AD%94%E6%B3%95%E5%B0%8F%E6%80%BB%E7%BB%93/
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!