php比較操作符安全問題

詳解php比較操作符的安全問題

php的比較操作符有==(等于)松散比較,===(完全等于)嚴(yán)格比較,這里面就會(huì)引入很多有意思的問題,本文給大家詳解php比較操作符的安全問題,對(duì)php操作符相關(guān)資料感興趣的朋友一起學(xué)習(xí)吧

php的比較操作符有==(等于)松散比較,===(完全等于)嚴(yán)格比較,這里面就會(huì)引入很多有意思的問題。

在松散比較的時(shí)候,php會(huì)將他們的類型統(tǒng)一,比如說字符到數(shù)字,非bool類型轉(zhuǎn)換成bool類型,為了避免意想不到的運(yùn)行效果,應(yīng)該使用嚴(yán)格比較。如下是php manual上的比較運(yùn)算符表:

例子? ? 名稱? ? 結(jié)果

$a == $b? 等于? TRUE,如果類型轉(zhuǎn)換后 $a 等于 $b。

$a === $b? 全等? TRUE,如果 $a 等于 $b,并且它們的類型也相同。

$a != $b? 不等? TRUE,如果類型轉(zhuǎn)換后 $a 不等于 $b。

$a <> $b? 不等? TRUE,如果類型轉(zhuǎn)換后 $a 不等于 $b。

$a !== $b? 不全等? TRUE,如果 $a 不等于 $b,或者它們的類型不同。

$a < $b? 小與? TRUE,如果 $a 嚴(yán)格小于 $b。

$a > $b? 大于? TRUE,如果 $a 嚴(yán)格大于 $b。

$a <= $b? 小于等于? TRUE,如果 $a 小于或者等于 $b。

$a >= $b? 大于等于? TRUE,如果 $a 大于或者等于 $b。

0x01 安全問題

1 hash比較缺陷

php在處理hash字符串的時(shí)候會(huì)用到!=,==來(lái)進(jìn)行hash比較,如果hash值以0e開頭,后邊都是數(shù)字,再與數(shù)字比較,就會(huì)被解釋成0*10^n還是為0,就會(huì)被判斷相等,繞過登錄環(huán)節(jié)。

root@kali:~/tool# php -r 'var_dump("00e0345" == "0");var_dump("0e123456789"=="0");var_dump("0e1234abc"=="0");'

bool(true)

bool(true)

bool(false)

當(dāng)全是數(shù)字的時(shí)候,寬松的比較會(huì)執(zhí)行盡力模式,如0e12345678會(huì)被解釋成0*10^12345678,除了e不全是數(shù)字的時(shí)候就不會(huì)相等,這能從var_dump("0e1234abc"=="0")可以看出來(lái)。

2 bool 欺騙

當(dāng)存在json_decode和unserialize的時(shí)候,部分結(jié)構(gòu)會(huì)被解釋成bool類型,也會(huì)造成欺騙。json_decode示例代碼:

$json_str='{"user":true,"pass":true}';

$data= json_decode($json_str,true);

if($data['user'] =='admin'&&$data['pass']=='secirity')

{

print_r('logined in as bool'."\n");

}

運(yùn)行結(jié)果:

root@kali:/var/www# php /root/php/hash.php

logined in as bool

unserialize示例代碼:

$unserialize_str='a:2:{s:4:"user";b:1;s:4:"pass";b:1;}';

$data_unserialize= unserialize($unserialize_str);

if($data_unserialize['user'] =='admin'&&$data_unserialize['pass']=='secirity')

{

print_r('logined in unserialize'."\n");

}

運(yùn)行結(jié)果如下:

root@kali:/var/www# php /root/php/hash.php

logined in unserialize

3 數(shù)字轉(zhuǎn)換欺騙

$user_id= ($_POST['user_id']);

if($user_id=="1")

{

$user_id= (int)($user_id);

#$user_id=intval($user_id);

$qry="SELECT * FROM `users` WHERE user_id='$user_id';";

}

$result= mysql_query($qry)ordie('

'. mysql_error() .'

');

print_r(mysql_fetch_row($result));

將user_id=0.999999999999999999999發(fā)送出去得到結(jié)果如下:

Array

(

[0] => 0

[1] => lxx'

[2] =>

[3] =>

[4] =>

[5] =>

)

本來(lái)是要查詢user_id的數(shù)據(jù),結(jié)果卻是user_id=0的數(shù)據(jù)。int和intval在轉(zhuǎn)換數(shù)字的時(shí)候都是就低的,再如下代碼:

if($_POST['uid'] != 1) {

$res=$db->query("SELECT * FROM user WHERE uid=%d", (int)$_POST['uid']);

mail(...);

}else{

die("Cannot reset password of admin");

}

假如傳入1.1,就繞過了$_POST['uid']!=1的判斷,就能對(duì)uid=1的用戶進(jìn)行操作了。另外intval還有個(gè)盡力模式,就是轉(zhuǎn)換所有數(shù)字直到遇到非數(shù)字為止,如果采用:

if(intval($qq) ==='123456')

{

$db->query("select * from user where qq = $qq")

}

攻擊者傳入123456 union select version()進(jìn)行攻擊。

4 PHP5.4.4 特殊情況

這個(gè)版本的php的一個(gè)修改導(dǎo)致兩個(gè)數(shù)字型字符溢出導(dǎo)致比較相等

$ php -r 'var_dump("61529519452809720693702583126814" == "61529519452809720000000000000000");'

bool(true)

3 題外話:

同樣有類似問題的還有php strcmp函數(shù),manual上是這么解釋的,int strcmp ( string $str1 ,

string $str2

),str1是第一個(gè)字符串,str2是第二個(gè)字符串,如果str1小于str2,返回<0,如果str1>str2,返回>0,兩者相等返回0,假如str2為一個(gè)array呢?

$_GET['key'] =array();

$key="llocdpocuzion5dcp2bindhspiccy";

$flag=strcmp($key,$_GET['key']);

if($flag== 0) {

print"Welcome!";

}else{

print"Bad key!";

}

運(yùn)行結(jié)果:

root@kali:~/php# php strcmp.php

PHP Warning:? strcmp() expects parameter 2 to be string, array given in /root/php/strcmp.php on line 13

Welcome!

比較多種類型

運(yùn)算數(shù) 1 類型運(yùn)算數(shù) 1 類型結(jié)果

nullstringstringNULL轉(zhuǎn)換為 "",進(jìn)行數(shù)字或詞匯比較

boolnull任何其它類型轉(zhuǎn)換為bool,FALSE<TRUE

objectobject內(nèi)置類可以定義自己的比較,不同類不能比較,相同類和數(shù)組同樣方式比較屬性(PHP 4 中),PHP 5 有其自己的說明

string,resourcenumberstring,resourcenumber將字符串和資源轉(zhuǎn)換成數(shù)字,按普通數(shù)學(xué)比較

arrayarray具有較少成員的數(shù)組較小,如果運(yùn)算數(shù) 1 中的鍵不存在于運(yùn)算數(shù) 2 中則數(shù)組無(wú)法比較,否則挨個(gè)值比較(見下例)

array任何其它類型array總是更大

object任何其它類型object總是更大

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容