PHP comparison operators have = = (equals) loose comparison, = = = (exactly equal to) strict comparison, where the face will introduce a lot of interesting questions.
When loosely compared, PHP will unify their type, such as character to number, non-bool type to bool type, in order to avoid unexpected running effect, should use strict comparison. The following is a table of comparison operators on PHP manual:
The example name results $ A = = $b equals TRUE if $a equals $b after the type conversion. $a = = = $b congruent TRUE if $a equals $b, and they are of the same type. $a! = $b unequal to TRUE if the type is converted $a not equal to $b. $a <> $b Not equal to TRUE if the type is converted $a does not equate to $b. $a!== $b Not equal to TRUE if $a are not equivalent to $b, or they are of different types. $a < $b small with TRUE if the $a is strictly less than $b. $a > $b is greater than TRUE if the $a is strictly greater than $b. $a <= $b is less than or equal to TRUE if $a is less than or equal to $b. $a >= $b is greater than or equal to TRUE if $a is greater than or equal to $b.
0X01 Security Issues
1 Hash comparison defects
PHP in the processing of hash string will use!=,== to hash comparison, if the hash value starts with 0e, behind is the number, and then compared with the number, will be interpreted as 0*10^n or 0, will be judged equal, bypassing the login link.
root@kali:~/tool# php-r ' Var_dump ("00e0345" = = "0"), Var_dump ("0e123456789" = = "0"), Var_dump ("0e1234abc" = = "0"); '
BOOL (TRUE)
BOOL (TRUE)
BOOL (FALSE)
When all is the number, the loose comparison will perform the best effort mode, such as 0e12345678 will be interpreted as 0*10^12345678, except that the E is not all the number is not equal, this can be seen from Var_dump ("0e1234abc" = = "0").
2 BOOL Spoofing
When Json_decode and unserialize are present, some structures are interpreted as bool types, which can also cause deception. Json_decode Sample code:
$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 ");}
Operation Result:
root@kali:/var/www# php/root/php/hash.php
Logined in as bool
Unserialize Sample code:
$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 ");}
The results of the operation are as follows:
root@kali:/var/www# php/root/php/hash.php
Logined in Unserialize
3 Number Conversion Spoofing
$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) or Die ('' . Mysql_error (). '
');p Rint_r (Mysql_fetch_row ($result));
Send user_id=0.999999999999999999999 to get the result as follows:
Array
(
[0] = 0
[1] = LXX '
[2] = =
[3] = =
[4] = =
[5] = =
)
Originally is to query user_id data, the result is user_id=0 data. int and intval are low when converting numbers, and then the following code:
if ($_post[' uid ']! = 1) {$res = $db->query ("SELECT * from user WHERE uid=%d", (int) $_post[' uid ']); mail (...);} else { Die ("Cannot reset password of admin");}
If you pass in 1.1, you bypass the $_post[' UID '! =1 's judgment, you can operate on the uid=1 user. In addition, Intval also has an effort mode, that is, to convert all the numbers until it encounters a non-digit, if using:
if (intval ($qq) = = = ' 123456 ') { $db->query ("select * from user where QQ = $QQ")}
An attacker enters 123456 Union select version () to attack.
4 PHP5.4.4 Special Cases
A modification of this version of PHP resulted in an overflow of two numeric characters resulting in a comparison of equal
$ Php-r ' var_dump ("61529519452809720693702583126814" = = "61529519452809720000000000000000"); '
BOOL (TRUE)
3 Off-topic:
There are similar problems with the PHP strcmp function, which is explained on manual, int strcmp (string $str 1, String $str 2), STR1 is the first string, STR2 is the second string, if str1 is less than str2, returns <0, if STR1>STR2, return >0, both return equal to 0, if STR2 is an array?
$_get[' key ' = Array (); $key = "Llocdpocuzion5dcp2bindhspiccy"; $flag = strcmp ($key, $_get[' key ']); if ($flag = = 0) { PR int "welcome!";} else { print "bad key!";}
Operation Result:
root@kali:~/php# PHP strcmp.php
PHP warning:strcmp () expects parameter 2 to is string, array given in/root/php/strcmp.php on line 13
welcome!
Compare multiple types
Number of operations 1 types |
Number of operations 1 types |
result |
null or string |
string |
will NULL to "" for numeric or lexical comparisons |
bool or null |
Any other type |
Converted to BOOL,FALSE < TRUE |
Object |
Object |
Built-in classes can define their own comparisons, non-homogeneous cannot be compared, the same class and arrays are the same way to compare properties (PHP 4), PHP 5 has its own description |
string , resource or number |
string , resource or number |
Converts strings and resources to numbers, compared by ordinary mathematics |
Array |
Array |
Arrays with fewer members are smaller if the keys in the operand 1 do not exist in the operand 2, the array cannot be compared, otherwise the values are compared (see example below) |
Array |
Any other type |
Array always bigger. |
Object |
Any other type |
Object always bigger. |