Workaround to bypass vulnerability in PHP with offset feature

Source: Internet
Author: User
This article mainly introduces the data about the bypass vulnerability caused by the character offset feature in PHP, the paper not only introduces the formation of the loophole, but also introduces the repair method, which has certain reference value for everyone, and hopes to help everyone.

Character offset properties in PHP

The string in PHP has a very interesting feature, and the string in PHP can be evaluated like an array.

$test = "Hello World"; Echo $test [0];

The final result is H.

But the above characteristics sometimes have unexpected effects, see the following code

$mystr = "Hello World"; Echo $mystr ["Pass"];

The output of the above code is H. What is this for? In fact, as in many other languages, strings can be used as arrays in PHP. The pass in the $MYSTR ["Pass"] is converted to 0 by the implicit type, so that the output of $mystr[0] is the first letter H.
Similarly, if you try the following code:

$mystr = "Hello World"; Echo $mystr ["1pass"];

The output is E. Because 1pass is converted to 1 by the implicit type, the output of the $MYSTR [1] is the second letter E.

Vulnerabilities caused by character attributes

The following code is used in phpspy2006 to determine which code to use when logging in.

$admin [' check '] = "1"; $admin [' pass '] = "Angel", ... if ($admin [' check '] = = "1") {...}

Such validation logic can easily be bypassed if the above features are used. $admin is not initially defined as an array type, when we phpsyp.php?admin=1abc with a string, PHP takes the first bit of the string 1xxx and successfully bypasses the IF condition.

The above code is a code fragment, the next piece of code is a complete logic code, from the Php4fun in the 5th question, more interesting.

<?php# goal:overwrite password for admin (id=1) # Try to login as admin# $yourInfo =array (//this are your user data in The db# ' id ' + 8,# ' name ' = ' jimbo18714 ', # ' pass ' = ' maybechanged ', # ' level ' = ', ' ' Level ', ' require '; f Unction MREs ($str) {return mysql_real_escape_string ($STR);} $userInfo = @unserialize ($_get[' userInfo '); $query = ' SELECT * from users WHERE id = \ '. MREs ($userInfo [' ID ']). ' \ ' and pass = \ '. MREs ($userInfo [' Pass ']). '\';'; $result = mysql_query ($query); if (! $result | | mysql_num_rows ($RESULT) < 1) {die (' Invalid password! ');} $row = Mysql_fetch_assoc ($result), foreach ($row as $key = = $value) {$userInfo [$key] = $value;} $oldPass = @$_get[' Oldpass '); $newPass = @$_get[' Newpass '];if ($oldPass = = $userInfo [' Pass ']) {$userInfo [' pass '] = $newPa ss $query = ' UPDATE users SET pass = \ '. MREs ($newPass). ' \ ' WHERE id = \ '. MREs ($userInfo [' ID ']). '\';'; mysql_query ($query); Echo ' Password Changed ';} else {echo ' Invalid old password entered. ';} 

This topic on the net only gives a final answer, the principle of which is not said or not to say very detailed. In fact, the principle is the above mentioned PHP character characteristics.

The problem is simple to change the admin password, admin ID is 1. Here are a few questions that we need to consider:

    • How to change the ID to 1 at the time of update

    • $userInfo [' pass '] = $newPass; What does this line of code do, and why this code exists in the IF Judgment statement

Having figured out these two issues, the final solution is also there. Change the password of the user with ID 8 to 8, then pass in a userInfo string ' 8 ', break through the query protection, and finally use $userinfo[' pass ' = $newPass change the ID to 1.

The ultimate payload is;

First Commit, Index.php?userinfo=a:2:{s:2: "id"; I:8;s:4: "Pass"; S:12: "Maybechanged";} &oldpass=maybechanged&newpass=8, the purpose is to change the password of the user with ID 8 to 8

Second Commit, index.php?userinfo=s:1: "8"; &oldpass=8&newpass=1, so the serialization $userinfo gets the string ' 8 ', which is $userinfo = ' 8 ', This enables database query validation to pass. Subsequent if validation can also pass through this line of code $userinfo[' Pass '] = $newPass, because the value of $newpass is 1, then the above code becomes $userinfo[' pass ' = 1; , $userInfo because of a string type, the final result is $userinfo= ' 1 ', and finally the password for the user with ID 1 can be updated.

How to fix

This vulnerability is also easy to fix, and it is best to check that the data type used is consistent with the expected data type when used in advance. Otherwise, the above-mentioned bypass problem will occur. At the same time to control the input, the input data to be checked and do not use arbitrarily.

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.