Artifice in the infiltration of PHP websites: Checking for vulnerabilities at equal time

Source: Internet
Author: User
Tags first string md5 digest md5 hash strcmp

PHP is one of the most commonly used back-end languages in Web sites, and is a type of system dynamic, weakly typed object-oriented programming language. can be embedded in HTML text, is one of the most popular web back-end languages, and can and web Server such as Apache and nginx convenient integration. At present, the market has occupied a large share of the service side.

However, weak types, some convenient features due to the improper use of novice programmers, resulting in a number of loopholes, this article will introduce some of the characteristics of infiltration can be used.

It's all crap, let's get down to the chase.

1. Weak type comparison = = vulnerability caused by

Note: These vulnerabilities apply to all versions of PHP

Let's review the basic syntax: There are two comparison symbols in PHP: Two equals sign and three equals sign (this and JavaScript) are similar

$a==$b$a===$b

Let's take a look at the official PHP manual.

$a == $bTRUE,如果类型转换后 $a 等于 $b。$a === $b 全等 TRUE,如果 $a 等于 $b,并且它们的类型也相同。

Clearly, the two equals sign equals the comparison of type conversions at the time of comparison.

If you compare a number and a string or compare strings that involve numeric content, the strings are converted to numeric values and compared to numeric values. This rule also applies to switch statements. The type conversion is not performed when compared with = = = or!==, because the type and the value are compared at this time.

Explicitly write out if a numeric value is compared to a string, the string is converted to a numeric value (instead of converting the value to a string)

However, how does PHP convert a string into a numeric value, we continue to view the PHP manual

When a string is taken as a numeric value, the result and type are as follows: If the string does not contain '. ', ' e ' or ' e ' and its numeric value is within the range of the integer (as defined by Php_int_max), the string will be evaluated as an integer. All other cases are evaluated as float. The starting part of the string determines its value. If the string starts with a valid numeric value, the value is used. Otherwise its value is 0 (0). The legal value is represented by an optional sign, followed by one or more digits (which may have decimal points), followed by an optional exponential portion. The exponential part is composed of one or more digits followed by ' e ' or ' e '.

Here are a few examples from the Official Handbook.

<?php$foo =1 +"10.5";$foo is float (11.5) $foo =1 +" -1.3e3";$foo is float (-1299) $foo =1 +"Bob-1.3e3";$foo is Integer (1) $foo = 1 +  "BOB3"; //$foo is integer (1) $foo = 1 + " Small Pigs "; //$foo is integer (11) $foo = 4 +  "10.2 Little piggies"; //$foo is float (14.2) $foo =  "10.0 Pigs "+ 1; //$foo is float (11) $foo =  "10.0 Pigs" + 1.0; //$foo is float (11) ?>   

We can probably summarize the following rules: When a string is converted to a numeric value

    • If a string is a "valid number +e+ legal number" type, it will be interpreted as the scientific notation for floating-point numbers
    • If a string is a "valid number + string not interpreted as a valid number" type, it will be converted to the value of that legal number, and the subsequent string will be discarded
    • If a string is a string of "non-interpreted as a valid number + any" type, it is converted to 0! For 0 ... is 0

      <?php‘a‘==0 // true‘12a‘==12 //true‘1‘==1 //true‘1aaaa55sss66‘==1 //true

Of course, the above equation for the = = = is false, the original should be used with = = =, the place is misused, resulting in the place can be injected.

Example code 1: Exploiting a vulnerability that is equal to a number
<?phpif (isset ($_get[ ' v1 ']) & & isset ($_get[ ' v2 ')) {$logined = true; $v 1 = $_get[ ' v1 '; $v 2 = $_get[ ' V2 ']; if (!ctype_alpha ($v 1)) {$logined = false;} if (!is_numeric ($v 2)) {$logined = FALSE;} if (MD5 ($v 1)! = MD5 ($v 2)) {$logined = false;} if ($logined) {//Continuue to doing other things}  else {echo  "Login Failed"}}?      

This is a CTF topic, very interesting, can be seen, asked to give two strings, one is a pure digital type, a character can only appear, so that two MD5 hash value equal, but this strong collision in cryptography is not possible.

But we see that when we finally compare the hashes of the two, we use equals and not all equals, so we can exploit this vulnerability

And look back at a md5() function

string md5 ( string $str [, bool $raw_output = false ] )

The original STR string. Raw_output If the optional raw_output is set to TRUE, then the MD5 Digest is returned in the original binary format in 16-byte length.

It can be known that the second parameter is true when the 16-bit result is displayed, and when there is no second argument, the 32-bit 16-digit code (16-bit result is the 32-bit as ASCII code parsing)

16 binary data contains E, can be constructed to compare two numbers, here is a ready-made example:

md5(‘240610708‘) //0e462097431906509019562988736854.md5(‘QNKCDZO‘) //0e830400451993494058024219903391

As you can see, these two strings contain only numbers, one containing only letters, although the two hashes are not the same, but they are all a form: 0e pure Numbers The string in this format is considered to be the number of scientific notation when judged equal, and the string-to-number conversion is done first.

After the conversion has become a lot of 0 many times, are 0, equal. (You can try it yourself)

md5(‘240610708‘)==md5(‘QNKCDZO‘); //Truemd5(‘240610708‘)===md5(‘QNKCDZO‘); //False

Use = = = To avoid this vulnerability.

Example code 2: Exploit the vulnerability of class ' a ' ==0
<?php if (isset($_POST[‘json‘])) { $json = json_decode($_POST[‘json‘]); $key ="**********************"; if ($json->key == $key) { //login success ,continue } else { //login failed ,return }?>

This time this example is to pass in a JSON data, JSON in a restful web site is a very common form of data transmission. This form will upload the data of input with name Key as JSON to the server.

{"key":"your input"}

How do we break it? Think "a" ==0 this loophole, we make $json->key is a number type of variable can, how to do it?

PHP's json_decode() function converts it to the corresponding type of data in PHP based on the data type in the JSON data, that is, if we pass a string type in JSON, then the variable is a string, and if the number is passed in, the variable is number. Therefore, if we pass in a number, we can make it equal. A form in a Web page may restrict all input to a string, even if you enter a number, the incoming item is also

{"key":"0"}

This is a string 0, we need to let him for the number type, with Burp intercept, the two double quotation marks removed, into this:

{"key":0}

Can.

It is worth discussing that, in the exploit of this method, it is very difficult to use the direct form type of post data, this is for what, this and the HTTP protocol. First, let's look at several types of data in the post to the server, the Content-type in the HTTP header:

application/x-www-form-urlencodedmultipart/form-dataapplication/jsonapplication/xml

The first application/x-www-form-urlencoded, which is a generic form of Content-type, is the second, the form that contains the file. The third, four, respectively, is JSON and XML, which is usually uploaded in JS.

But because in the direct post of the payload is unable to distinguish between strings and numbers, because in which there is no quotation marks, to give an example of a grab packet

POST /login HTTP/1.1Host: xxx.comContent-Length: 41Accept: application/json, text/javascript,application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36Content-Type: application/x-www-form-urlencoded; charset=UTF-8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8Connection: closeusername=admin&password=admin

As you can see, payload is placed on the last side of the HTTP packet and is passed in an unquoted form, and there is no way to distinguish whether it is a string or a number. As a result, PHP saves post data in a string form, and there is no way to inject data of numeric type, but JSON is not the same, JSON itself is a complete string, after parsing may have string, number, Boolean and many other types.

2. strcmp Vulnerability

Note: This vulnerability applies to versions of PHP prior to 5.3

Let's take a look at this function, which is a function for comparing strings

int strcmp ( string $str1 , string $str2 )

The parameter str1 the first string. STR2 a second string. If STR1 is less than str2 returns < 0, if STR1 is greater than str2 returns > 0, if both are equal, 0 is returned.

It is known that the incoming expected type is a string type of data, but if we pass the non-string type of data, this function will have what kind of behavior? In fact, when this function accepts a non-conforming type, the function will have an error, but in PHP prior to 5.3, a warning message with an error is displayed, and a return of 0 will be taken!!!! That is, although the report was wrong, but it was judged equal. This is a fatal flaw in the code that uses this function to make a judgment in a SELECT statement, and of course, the PHP official fixes the vulnerability in later versions, making the function return no value when the error is made. However, we can still use this vulnerability to conduct penetration testing of websites using older versions of PHP. Look at the sample code:

<?php    $password="***************"     if(isset($_POST[‘password‘])){ if (strcmp($_POST[‘password‘], $password) == 0) { echo "Right!!!login success";n exit(); } else { echo "Wrong password.."; }?>

For this piece of code, what can we do to get around the validation, as long as we $_POST[‘password‘] are an array or an object, but the last question when we can only upload the string type, then how do we do it.

In fact, PHP in order to be able to upload an array, will end with a pair of brackets in the variable, for example, xxx[] the name (that is, the key in $_post), as a name for xxx the array to construct a request similar to the following

POST /login HTTP/1.1Host: xxx.comContent-Length: 41Accept: application/json, text/javascriptUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36Content-Type: application/x-www-form-urlencoded; charset=UTF-8Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8Connection: closepassword[]=admin

Can make the above code bypass validation successful.

3 Summary

The main feature of this type of vulnerability is the use of type features in PHP to bypass validation. Due to the obvious distinction between = = and = = =, it is estimated that the author of PHP will not adjust the strategy for these two symbols in the short term. And for the development market, with the increase of training institutions, the threshold of the back-end programmers, especially the PHP back-end programmer is getting lower, the level must also be mixed, these DAO programmers may bring more such a vulnerability to improper use of features, so this kind of vulnerability is still very valuable.

To summarize, for developers, there are several habits that need to be adhered to:

  • Read PHP manual carefully and cannot be fully encoded in PHP with the experience of other languages
  • Before using an operator or function, look at the document in detail and figure out what kind of behavior the function will have under what conditions.

Remember the motto of security: Any user input is untrusted! For Web applications, the front-end (browser-side) security restrictions can only prevent the normal user from the wrong input behavior, it is completely impossible to the black Hat behavior has any defensive effect

Therefore, in the process of defending this vulnerability, a few things are guaranteed:

  • In all possible places, used instead of =====
  • Filtering and type checking for user input
  • Try to use the new version of Php,apache

Basically, you can defend this kind of loophole perfectly.

For penetration testers, in the process of code audit, for == strcmp The comparison should be extremely sensitive. In the case of black box infiltration can also be used to guess the code, combined with some version of the information collection features, the use of these vulnerabilities to bypass authentication.

Artifice in the infiltration of PHP websites: Checking for vulnerabilities at equal time

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.