CTF Web - [geek challenge 2019]PHP

Keywords: Programming PHP Python github


CTF Web - [geek challenge 2019]PHP

Blog description

The information involved in this article comes from Internet collation and personal summary, which means personal learning and experience summary. If there is any infringement, please contact me to delete, thank you! This article is only for learning and communication, not for illegal use!

CTP platform




Web class, [geek challenge 2019]PHP

Open an instance of the topic


Seeing this kind of problem, I love it

Especially this animation effect, is it so good to be a safe front-end? mogul

But I'm going to send the next question: I can't type open source code for this animation. I'm going to do it, but I don't need to use it. When it comes to file backup, first of all, I'll blow up the directory of the website and use dirsearch


A directory blasting tool based on Python 3

Download address



-u specify url

-e specify website language

-w can add its own dictionary (with path)

-r recursive running (after finding a directory, running repeatedly after the directory, very slow, not recommended)

After entering dirsearch directory

Execute. / dirsearch.py -u -e php similar directory, here we use

./dirsearch.py -u http://71f04e34-1537-41f0-8c4f-e3de12f432b9.node3.buuoj.cn -e php

There are so many files in it, but I just need to backup them

Add www.zip directly to the back of the website, download it to the local unzip and check it, and find some files like this

Open the index.php file

There is a paragraph in it that loads a class.php file, passes a select parameter through get, and then deserializes it

Open class.php

include 'flag.php';


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>";
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";


According to the meaning of the code, if password=100, username=admin, you can get the flag when executing the \destruct(), so we need to meet these requirements

Construct serialization


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

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


Save file once

The obtained serialization is. It is recommended to type it manually


At this stage, the problem comes. In the process of deserialization, we will first execute the \\\\\\\\\\\\\

Skip ()

When deserializing a string, if the number of properties is greater than the actual number of properties, the execution of the \

So we will serialize this setting


But it's not over, because the declared variable is private


The fields declared by private are private fields, which are only visible in the declared class, but not in the subclass of the class and the object instance of the class. So when the field name of private field is serialized, the class name and field name will be prefixed with \ 0. String length also includes the prefixed length

Let's change the serialization again



Use get request to pass our prepared serialization as a parameter of select


Remember to change the previous website to your own

The last sentence is that the cat is so cute and wants to steal it. Hahaha!



And the industrious self

Posted by ebbatten on Sun, 03 May 2020 17:02:43 -0700