PHP's comparison operator has = = = (equals) loose comparison, = = = = = = = = = = = = = = (equal) Strictly compare, there will be a lot of interesting problems.
When loosely compared, PHP will unify their type, such as character to number, non-bool type to bool type, in order to avoid unexpected effect, should use strict comparison. The following is a table of comparison operators on the PHP manual:
The example name result
$a = = $b equals TRUE, and $a equal to $b if the type is converted.
$a = = = $b congruent TRUE if $a equals $b, and they are of the same type.
the $a!= $b is not equal to TRUE, and if the type is converted $a is not equivalent to $b.
the $a <> $b does not equal TRUE, and if the type is converted $a is not $b.
$a!== $b is not congruent to TRUE if $a is not equal to $b, or they are of different types.
$a < $b Small and TRUE if $a are strictly smaller than $b.
$a > $b is greater than TRUE if $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 greater than or equal to TRUE if $a is greater than or equal to $b.
0X01 Security Issues
1 Hash comparison defect
PHP in the processing of hash string will be used to!=,== hash comparison, if the hash value to the beginning of 0e, the back is a number, and then compared with the number, will be interpreted as a 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, relaxed comparison will perform the best mode, such as 0e12345678 will be interpreted as 0*10^12345678, in addition to E is not all the time will not be equal, this can be from Var_dump ("0e1234abc" = = "0") can be seen.
2 BOOL Deception
When there are Json_decode and Unserialize, part of the structure is interpreted as a type of bool, which can also lead to 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 ");
}
Run 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 Deception
$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 (' <pre> '. Mysql_error (). ' </pre> ');
Print_r (Mysql_fetch_row ($result));
Send the user_id=0.999999999999999999999 out and get the results as follows:
Array
(
[0] => 0
[1] => LXX '
[2] =>
[3] =>
[4] =>
[5] =>
)
Originally to query user_id data, the result is user_id=0 data. int and intval are low when converting numbers, followed by 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, the uid=1 user can be operated on. In addition, Intval has a model of trying to convert all numbers until it encounters a non-numeric number, if you use:
if (intval ($qq) = = ' 123456 ')
{
$db->query ("select * from user where QQ = $QQ")
}
The attacker passes in the 123456 Union Select version () for an attack.
4 PHP5.4.4 Special case
A modification of this version of PHP resulted in a two-digit character overflow that resulted in a more equal
$ Php-r ' var_dump ("61529519452809720693702583126814" = = "61529519452809720000000000000000"); '
BOOL (TRUE)
3 digression:
There is also a similar problem with the PHP strcmp function, which is explained manual, int strcmp (string $str 1, String $str 2), STR1 is the first string, STR2 is the second string, and if str1 is less than str2, returns <0, if STR1>STR2, return >0, the two equals return 0, if str2 is an array?
$_get[' key '] = Array ();
$key = "Llocdpocuzion5dcp2bindhspiccy";
$flag = strcmp ($key, $_get[' key ');
if ($flag = = 0) {
print "welcome!";
} else {
print "bad key!";
}
Run 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
operation number 1 type |
operation number 1 type |
Results |
null or string |
string |
&NBSP; null convert to "" for numeric or lexical comparisons |
BOOL or null |
Any other type |
Convert to bool,FALSE < TRUE |
Object |
Object |
Built-in classes can define their own comparisons, not the same kind cannot be compared, the same classes and arrays in the same way compare attributes (PHP 4), PHP 5 has its own description |
string,resource or number |
string,resource or number |
Converts strings and resources to numbers, compared to normal mathematics |
Array |
Array |
An array with fewer members is smaller, if the key in operand 1 does not exist in operand 2, the array cannot be compared, otherwise the values are compared (see the following example) |
Array |
Any other type |
Array always bigger |
Object |
Any other type |
Object always bigger |