LIMIT子句中的盲 SQL注入漏洞利用
字数 1042 2025-08-26 22:11:57

LIMIT子句中的盲SQL注入漏洞利用技术详解

漏洞概述

本文详细分析了一种特殊的盲SQL注入漏洞,该漏洞存在于SQL查询的LIMIT子句中。攻击者通过控制LIMIT子句的参数值,利用PostgreSQL数据库的特性,实现了数据泄露。

漏洞发现环境

  • 目标系统:基于PHP的Web应用
  • 数据库:PostgreSQL
  • 漏洞位置:相册分页功能
  • 触发参数:num_max
  • 原始SQL查询:
    Select * from tbl_albums where page=2 order by album_date asc LIMIT 0,{{INPUT}}
    
    或等效形式:
    Select * from tbl_albums where page=2 order by album_date asc LIMIT {{INPUT}} OFFSET 0
    

漏洞确认

  1. 通过输入特殊字符测试SQL注入:

    • 单引号(')
    • 双引号(")
    • 反斜杠(\)
  2. 观察到PostgreSQL错误信息,确认存在SQL注入漏洞

技术难点

  1. 当ORDER BY与LIMIT一起使用时,无法使用UNION语句注入
  2. MySQL中可使用基于错误的注入,但目标为PostgreSQL
  3. LIMIT和OFFSET要求参数必须是数字

漏洞利用技术

前置条件

  1. 创建足够多的相册记录(至少127个)
    • 使用Burp Intruder批量创建约200个相册

核心原理

利用ASCII函数将字符转换为数字,通过控制返回的记录数量来泄露数据:

  1. 将想要查询的数据的第一个字符转换为ASCII码
  2. 使用该ASCII码作为LIMIT参数值
  3. 返回的记录数等于该字符的ASCII码值
  4. 通过计算返回的记录数反推出原始字符

具体步骤

  1. 提取数据库版本第一个字符的PoC:

    Select * from tbl_albums where page=2 order by album_date asc LIMIT 0,ascii(substr((Select version()),1,1))
    
  2. 工作流程:

    • substr((select version()),1,1) 获取版本字符串的第一个字符
    • ascii() 将该字符转换为ASCII码
    • 查询返回的记录数等于该ASCII码值
  3. 示例:

    • 如果版本是"PostgreSQL 9.6.2"
    • 第一个字符'P'的ASCII码是80
    • 查询将返回80条记录

自动化提取

  1. 使用JavaScript计算返回的相册数量:

    document.querySelectorAll('.ALBUM_CLASS').length
    
  2. 将数量转换回字符:

    String.fromCharCode(80) // 返回'P'
    
  3. 重复此过程提取后续字符

防御措施

  1. 参数化查询:使用预处理语句而非直接拼接SQL
  2. 输入验证:确保LIMIT参数为有效数字
  3. 范围限制:限制LIMIT参数的最大值
  4. 错误处理:避免显示详细的数据库错误信息
  5. 权限最小化:数据库用户只应具有必要权限

总结

这种技术展示了即使在看似受限的SQL注入场景(LIMIT子句)中,通过创造性思维仍可能实现数据泄露。关键在于:

  1. 理解数据库函数的行为(如ASCII())
  2. 利用返回记录数与数据值的关联
  3. 准备足够多的测试数据
  4. 自动化提取和转换过程

该技术不仅适用于PostgreSQL,经过适当调整也可应用于其他数据库系统。

LIMIT子句中的盲SQL注入漏洞利用技术详解 漏洞概述 本文详细分析了一种特殊的盲SQL注入漏洞,该漏洞存在于SQL查询的LIMIT子句中。攻击者通过控制LIMIT子句的参数值,利用PostgreSQL数据库的特性,实现了数据泄露。 漏洞发现环境 目标系统:基于PHP的Web应用 数据库:PostgreSQL 漏洞位置:相册分页功能 触发参数: num_max 原始SQL查询: 或等效形式: 漏洞确认 通过输入特殊字符测试SQL注入: 单引号( ' ) 双引号( " ) 反斜杠( \ ) 观察到PostgreSQL错误信息,确认存在SQL注入漏洞 技术难点 当ORDER BY与LIMIT一起使用时,无法使用UNION语句注入 MySQL中可使用基于错误的注入,但目标为PostgreSQL LIMIT和OFFSET要求参数必须是数字 漏洞利用技术 前置条件 创建足够多的相册记录(至少127个) 使用Burp Intruder批量创建约200个相册 核心原理 利用ASCII函数将字符转换为数字,通过控制返回的记录数量来泄露数据: 将想要查询的数据的第一个字符转换为ASCII码 使用该ASCII码作为LIMIT参数值 返回的记录数等于该字符的ASCII码值 通过计算返回的记录数反推出原始字符 具体步骤 提取数据库版本第一个字符的PoC: 工作流程: substr((select version()),1,1) 获取版本字符串的第一个字符 ascii() 将该字符转换为ASCII码 查询返回的记录数等于该ASCII码值 示例: 如果版本是"PostgreSQL 9.6.2" 第一个字符'P'的ASCII码是80 查询将返回80条记录 自动化提取 使用JavaScript计算返回的相册数量: 将数量转换回字符: 重复此过程提取后续字符 防御措施 参数化查询:使用预处理语句而非直接拼接SQL 输入验证:确保LIMIT参数为有效数字 范围限制:限制LIMIT参数的最大值 错误处理:避免显示详细的数据库错误信息 权限最小化:数据库用户只应具有必要权限 总结 这种技术展示了即使在看似受限的SQL注入场景(LIMIT子句)中,通过创造性思维仍可能实现数据泄露。关键在于: 理解数据库函数的行为(如ASCII()) 利用返回记录数与数据值的关联 准备足够多的测试数据 自动化提取和转换过程 该技术不仅适用于PostgreSQL,经过适当调整也可应用于其他数据库系统。