PHP弱类型

PHP 属于弱类型语言, PHP 不必声明该变量的数据类型,PHP 会根据变量的值自动把变量的值转换为所需的数据类型,但在这个自动转换过程中可能存在安全问题。
常见可能导致弱类型漏洞的有:1)== 2)switch() 3)in_array() 4)array_search() 5)is_number() 6)strcmp() 7)Magic Hashes

1) 比较运算符==与===

http://php.net/manual/zh/types.comparisons.php

Loose comparisons with == 松散比较 ==
Strict comparisons with === 严格比较 ===
在松散比较时,PHP会将类型进行强制转换。一个数字和一个字符串进行比较,PHP会把字符串转换成数字再进行比较。PHP转换规则:若字符串以数字开头,则取开头数字作为转换结果,若无则输出0。 两个字符串比较,如果两个都是数字形式,则同时转换为数字进行比较。

1
2
3
4
5
$a == $b	等于     TRUE,如果类型转换后 $a 等于 $b。
$a === $b 全等 TRUE,如果 $a 等于 $b,并且它们的类型也相同。
$a != $b 不等 TRUE,如果类型转换后 $a 不等于 $b。
$a <> $b 不等 TRUE,如果类型转换后 $a 不等于 $b。
$a !== $b 不全等 TRUE,如果 $a 不等于 $b,或者它们的类型不同。

示例1

1
2
3
4
5
6
7
8
9
<?php
var_dump('abc' == 0); //true
var_dump('123abc' == 123); //true
var_dump('1' == 1); //true
var_dump('1' == true); //true
echo "<br>";
var_dump("1" == "01"); // true
var_dump('1' === 1); //false //严格比较
?>

实例-DedeCMS(20180109)任意用户密码重置

http://blog.nsfocus.net/dedecms-20180109/ DedeCMS最新版(20180109)任意用户密码修改

2) switch()

http://us1.php.net/manual/zh/control-structures.switch.php
switch/case 是松散比较(loose comparison)。当switch case是数字类型时,switch会先将其中的参数转换为int类型

示例1

1
2
3
4
5
6
7
8
9
10
<?php
$i ="2lltest";
switch ($i) {
case 1:
echo "1";
case 2:
echo $i;
//输出2lltest
}
?>

实例-HDWIKI鸡肋SQL注入

https://www.secpulse.com/archives/30532.html HDWIKI鸡肋SQL注入(PHP弱类型实例)

3) in_array()

http://php.net/manual/en/function.in-array.php
in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] ) : bool
in_array 检查数组中是否存在某个值。在数组haystack中搜索needle是否存在,如果没有设置 strict为true时 则使用松散比较。

示例1

1
2
3
4
5
6
7
8
9
10
11
12
<?php
//in_array()如果没有设置第三个参数为true 则松散比较
$a = array(0,1,2,7,'9');
var_dump(in_array('7lltest.php', $a));//返回true #7lltest.php被强制转换成整型 7
var_dump(in_array('lltest.php', $a));//返回true #lltest.php被强制转换成整型 0

echo "<br>";

var_dump(in_array('7lltest.php', $a, true));//返回false
var_dump(in_array('lltest.php', $a, true));//返回false
#如果第三个参数设置为 true,只有当元素存在于数组中且数据类型与给定值相同时才返回 true。
?>

实例-免费开源相册Piwigo<= v2.7.1 SQL注入

https://www.freebuf.com/articles/web/55075.html 免费开源相册Piwigo<= v2.7.1 SQL注入漏洞分析

array_search ( mixed $needle , array $haystack [, bool $strict = false ] ) : mixed
array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名,否则返回 FALSE。如果没有设置 strict为true时 则使用松散比较。

示例1

1
2
3
4
5
6
7
<?php
//array_search()如果没有设置第三个参数为true 则松散比较
$array=array(0,1);
var_dump(array_search('test.php', $array)); //0
var_dump(array_search('1test.php', $array)); //1
var_dump(array_search('7test.php', $array)); //false
?>

5) is_number()

is_numeric ( mixed $var ) : bool
is_numeric 检测变量是否为数字或数字字符串。如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。
而如果该值是0x十六进制格式,同样会返回TRUE,就可能存在二次注入等问题。

示例1

1
2
3
4
5
6
7
8
9
10
<?php
$id = '0x3120616e6420313d31';
if (is_numeric($id)){
$sql = "select * from user where id = $id";
echo $sql;
}
else{
echo "$id is not number";
}
?>

实例-phpyun注入漏洞

http://www.anquan.us/static/bugs/wooyun-2015-0122884.html

6) strcmp()

http://php.net/manual/zh/function.strcmp.php
strcmp ( string $str1 , string $str2 ) : int
strcmp 字符串比较。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0
在PHP >=5.3版本中,strcmp($_GET[‘pass’], $password) == 0,当GET请求xxx.php?pass[]=xxx 时,由于类型不符合,发生错误,但还是判断其相等 返回0

示例1

1
2
3
4
5
6
7
8
9
<?php
//Vulnerability (in PHP >=5.3)
//测试版本: PHP Version 5.3.29
$password="123456";
if (strcmp($_GET['pass'], $password) == 0) {
echo "Success";
}
//GET请求: xxx.php?pass[]=xxx 类型不符合,发生错误,但还是判断其相等 返回0
?>

7) Magic Hashes

https://www.whitehatsec.com/blog/magic-hashes/
PHP中当利用!=或==进行比较时,会把以0e开头的值视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0
所以当两个不同的密码经过哈希以后,如果其哈希值恰好都是以0e开头的,那么PHP会认为他们相同,都是0
MD5或者其他哈希算法值是以0e开头的 其实不多

示例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
var_dump("0e1234567890"=="0"); //true
var_dump("0e1234567890"==="0"); //false
var_dump("10" == "1e1"); // 10 == 10 -> true php以科学计数形式将字符串转换为对应数字(1e1 = 1*10^1 = 1)
var_dump(100 == "1e2"); //true
echo "<br>";

echo md5('240610708'); //0e462097431906509019562988736854
echo "<br>";
echo md5('QNKCDZO'); //0e830400451993494058024219903391
echo "<br>";

if ( md5('240610708') == md5('QNKCDZO')) {
echo "ok";
}
?>

实例-wordpress- cookie伪造漏洞(CVE -2014- 0166)

https://www.freebuf.com/news/67007.html

参考:

https://www.freebuf.com/articles/web/166543.html PHP弱类型引发的漏洞实例
http://vinc.top/2017/04/04/php%E5%BC%B1%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%E9%97%AE%E9%A2%98%E6%B1%87%E6%80%BB/ PHP弱类型安全问题汇总
http://blog.topsec.com.cn/?p=2137 php代码审计之弱类型引发的灾难