注入漏洞总结
字数 4585 2025-08-10 20:35:59

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

1. SQL注入概述

SQL注入是Web安全中最常见且危险的漏洞之一,位列十大Web安全漏洞之中。其本质是应用程序对用户输入数据未进行充分验证和过滤,导致攻击者能够构造恶意SQL语句并执行。

1.1 SQL注入产生条件

  • 参数用户可控:攻击者能够控制输入参数
  • 参数动态拼接SQL语句:应用程序直接将用户输入拼接到SQL查询中
  • 参数过滤不严:缺乏有效的输入验证和过滤机制

2. SQL注入分类

2.1 按注入效果分类

2.1.1 UNION联合注入

  • 适用条件

    • 参数所在SQL语句为查询语句
    • 页面存在回显
    • 示例:select * from users where id="$id"
  • 利用方法

    1. 使用order by判断列数
    2. 使用select 1,2,3...确定回显位
    3. 构造union select语句获取数据库信息
    4. 使用concat()group_concat()合并多行结果

2.1.2 布尔盲注

  • 适用条件:页面无回显信息,但不同输入会导致不同页面响应
  • 利用方法
    • 构造条件判断语句:id=0' or length(database())>4 --+
    • 逐字符判断:id=0' or substring(database(),1,1)='s'--+
    • 使用ASCII码判断:id=0' or ord(substring(database(),1,1))=65 --+

2.1.3 时间盲注

  • 适用条件:不同输入页面响应相同,但可通过响应时间判断
  • 利用方法
    • 结合if()sleep()函数:if(1=1,sleep(1),1)
    • 通过页面响应时间判断条件真假

2.1.4 报错注入

  • 适用条件:SQL语句执行错误后页面显示错误信息
  • 常见报错方法
    • XPATH报错(MySQL 5.1.5+):
      • extractvalue()id=0'or (select extractvalue(1,concat('!',database()))) --+
      • updatexml()
    • floor型报错
      • 结合rand()group by使用
      • 示例:0' or (select count(*) from users group by concat(database(),floor(rand(0)*2)))--+
    • 几何函数报错(MySQL 5.5.47-5.7.17):
      • geometrycollection(), multipoint(), polygon()
      • 示例:id = 1 and GeometryCollection((select from (select from(select database())a)b))
    • 整数溢出报错
      • 使用~0表示最大整数值:id=0'or (select(~0+!(select * from (select database())a))) --+
      • exp函数:(select exp(~(select * from (select database())a))) --+

2.1.5 堆叠注入

  • 原理:利用SQL语句中;分隔多条语句的特性
  • 风险:可执行任意合法SQL语句,包括删除数据等危险操作
  • 限制:多数服务器限制一次只能执行一条SQL语句

2.1.6 二次注入

  • 原理
    1. 用户上传参数时被转义(如test'变为test\'
    2. 从数据库取出数据时未再次转义
    3. 导致原始注入语句被还原执行
  • 示例
    • 输入:test' union select 1,2,version() --+
    • 查询时变为:select * from user where username='test' union select 1,2,version() --+'

2.2 按提交方式分类

2.2.1 GET注入

  • 参数出现在URL中
  • 受URL长度限制

2.2.2 POST注入

  • 参数通过POST请求体提交
  • 多见于表单

2.2.3 HTTP头注入

  • 注入点位于HTTP头部字段
  • 常见注入点:
    • Cookie
    • HTTP_CLIENT_IP
    • HTTP_X_FORWARDED_FOR
    • User-Agent
    • Referer

3. 文件读写操作

3.1 条件

  • 了解目标主机路径
  • 有相应读写权限
  • 可使用outfileload_file()等函数

3.2 风险

  • 写入webshell
  • 通过工具(如中国菜刀、webacoo)连接控制服务器

4. SQL注入绕过技术

4.1 大小写绕过

  • 示例:Union代替union
  • 现代WAF基本已防御

4.2 双写绕过

  • 示例:uniunionon过滤后变为union
  • 主要用于过滤替换型WAF

4.3 编码绕过

  • URL编码
  • Unicode编码
  • Hex编码等

4.4 注释绕过

  • 示例:id=1 /*!union*/ /*!select*/
  • 或:union /*kuyed*/ select /*iuysv*/ 1

4.5 宽字节绕过

  • 条件:客户端与服务端编码不一致(如PHP utf8,MySQL gbk)
  • 方法:在/前加%df

4.6 Cookie绕过

  • 利用$_REQUEST获取参数顺序(GET > POST > COOKIE)
  • 当程序只检测GET/POST时,通过COOKIE传参

4.7 非常用函数

  • 使用WAF不检测的冷门函数

5. SQL注入防御措施

5.1 基本原则

  • 永远不信任用户输入:包括数据库返回的数据
  • 拒绝而非修复:直接拒绝可疑请求而非尝试修复数据

5.2 参数化查询(预处理语句)

  • 使用PDO的bind_param()绑定参数
  • 避免SQL语句动态拼接
  • 示例:
    $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
    $stmt->bindParam(':id', $id, PDO::PARAM_INT);
    $stmt->execute();
    

5.3 严谨编码实践

  • 生产环境移除调试信息(如mysql_error
  • 验证数据最终存储需求(如字段长度限制)

5.4 最小权限原则

  • 区分读写用户权限
  • 业务用户仅拥有必要的最小权限

6. XSS注入(跨站脚本攻击)

6.1 分类

  • 反射型:非持久化,通过URL等即时触发
  • 存储型:持久化到数据库,所有访问者受影响
  • DOM型:完全在客户端执行
  • 基于页面型

6.2 常见触发方式

6.2.1 事件触发

  • onclick:点击元素时
  • onerror:资源加载失败时
  • onmouseover:鼠标悬停时
  • onload:元素加载完成时

6.2.2 常用标签

  • <script>alert("xss");</script>
  • ``
  • <a href=javascript:alert('xss')>test</a>
  • <iframe onload=alert("xss");></iframe>
  • <svg onload=alert(1)>

6.3 XSS绕过技术

6.3.1 编码绕过

  • Unicode编码
  • Base64编码
  • URL编码

6.3.2 特殊构造

  • 使用data:协议:data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=
  • 拼接绕过:``
  • 优先级绕过:<title>>

6.4 XSS防御措施

6.4.1 输入过滤

  • 使用htmlspecialchars()转义HTML特殊字符
  • 白名单验证输入内容

6.4.2 纯前端渲染

  • 静态HTML不包含业务数据
  • 明确设置内容类型(.innerText.setAttribute等)

6.4.3 HttpOnly Cookie

  • 禁止JavaScript读取敏感Cookie

7. 命令注入漏洞

7.1 产生条件

  • 执行系统命令的函数参数用户可控
  • 后端过滤不严格

7.2 危险函数(PHP)

  • system()
  • exec()
  • shell_exec()
  • passthru()
  • popen()
  • proc_popen()

7.3 命令拼接符

7.3.1 Windows

  • $, `

\[`, `|`, `||` #### 7.3.2 Linux - `&`:后台运行 - `;`:命令结束符 - `|`:管道 - `&&`:前命令成功则执行后命令 - `||`:前命令失败则执行后命令 ### 7.4 绕过技术 #### 7.4.1 通配符 - `?`:匹配单个字符 - `*`:匹配任意字符 - `[]`:字符集匹配 - 示例:`cat /*tc/pa??wd` #### 7.4.2 未定义变量 - Linux中未定义变量为null - 示例:`cat$a /etc$a/passwd$a` #### 7.4.3 反引号与$() - 将命令结果保存到变量 - 示例:`echo $(pwd)` #### 7.4.4 关键字替换 - `cat` → `more`、`vi`、`head`等 #### 7.4.5 分段写入执行 - 将代码分段写入文件再执行 - 适用于长度受限情况 ### 7.5 命令注入防御 #### 7.5.1 输入验证 - 严格校验输入格式(如IP地址、URL等) #### 7.5.2 白名单限制 - 限制参数允许的内容 #### 7.5.3 最小权限 - Web应用程序使用最低必要权限 ## 8. 代码注入漏洞(PHP) ### 8.1 文件包含漏洞 #### 8.1.1 危险函数 - `include()` - `include_once()` - `require()` - `require_once()` #### 8.1.2 利用方式 - 包含恶意构造的文件 - 远程文件包含(需`allow_url_include`开启) #### 8.1.3 常见协议 - `http(s)://`:远程文件包含 - `file://`:本地文件访问 - `zip://`:访问压缩包内文件 - `data://`:直接包含数据流 - `php://`:特殊PHP流 #### 8.1.4 绕过技术 - 路径遍历:`../../../etc/passwd` - 空字节截断(PHP版本限制) - 超长路径截断 ### 8.2 代码执行函数 #### 8.2.1 直接执行 - `eval()`:执行字符串作为PHP代码 - `assert()`:与`eval`类似 #### 8.2.2 正则执行 - `preg_replace()`的`e`修饰符(已弃用) #### 8.2.3 回调函数 - `call_user_func()` - `array_map()` - `usort()`等 #### 8.2.4 动态函数 - `$func = "system"; $func("whoami");` - ` \]

`可变变量

8.3 代码注入防御

8.3.1 避免危险函数

  • 尽量不使用eval()assert()

8.3.2 严格输入过滤

  • 过滤特殊字符(/, ., ..等)
  • 限制文件包含路径

8.3.3 权限控制

  • 重要文件加密存储
  • 使用非常见路径名称

9. 总结

9.1 核心防御原则

  1. 不信任任何用户输入
  2. 最小权限原则
  3. 防御性编程
  4. 持续更新与补丁

9.2 开发者自查清单

  • 是否使用预处理语句?
  • 是否过滤所有用户输入?
  • 是否关闭错误回显?
  • 是否使用最低必要权限?
  • 是否定期更新依赖库?

9.3 渗透测试要点

  1. 识别所有用户输入点
  2. 尝试各种注入技术
  3. 验证过滤与转义机制
  4. 检查错误处理方式
  5. 评估漏洞潜在影响

通过全面理解这些注入漏洞的原理、利用方式和防御措施,开发人员可以构建更安全的Web应用程序,安全人员也能更有效地发现和修复这些漏洞。

SQL注入漏洞全面解析与防御指南 1. SQL注入概述 SQL注入是Web安全中最常见且危险的漏洞之一,位列十大Web安全漏洞之中。其本质是应用程序对用户输入数据未进行充分验证和过滤,导致攻击者能够构造恶意SQL语句并执行。 1.1 SQL注入产生条件 参数用户可控 :攻击者能够控制输入参数 参数动态拼接SQL语句 :应用程序直接将用户输入拼接到SQL查询中 参数过滤不严 :缺乏有效的输入验证和过滤机制 2. SQL注入分类 2.1 按注入效果分类 2.1.1 UNION联合注入 适用条件 : 参数所在SQL语句为查询语句 页面存在回显 示例: select * from users where id="$id" 利用方法 : 使用 order by 判断列数 使用 select 1,2,3... 确定回显位 构造 union select 语句获取数据库信息 使用 concat() 或 group_concat() 合并多行结果 2.1.2 布尔盲注 适用条件 :页面无回显信息,但不同输入会导致不同页面响应 利用方法 : 构造条件判断语句: id=0' or length(database())>4 --+ 逐字符判断: id=0' or substring(database(),1,1)='s'--+ 使用ASCII码判断: id=0' or ord(substring(database(),1,1))=65 --+ 2.1.3 时间盲注 适用条件 :不同输入页面响应相同,但可通过响应时间判断 利用方法 : 结合 if() 和 sleep() 函数: if(1=1,sleep(1),1) 通过页面响应时间判断条件真假 2.1.4 报错注入 适用条件 :SQL语句执行错误后页面显示错误信息 常见报错方法 : XPATH报错 (MySQL 5.1.5+): extractvalue() : id=0'or (select extractvalue(1,concat('!',database()))) --+ updatexml() floor型报错 : 结合 rand() 、 group by 使用 示例: 0' or (select count(*) from users group by concat(database(),floor(rand(0)*2)))--+ 几何函数报错 (MySQL 5.5.47-5.7.17): geometrycollection() , multipoint() , polygon() 等 示例: id = 1 and GeometryCollection((select from (select from(select database())a)b)) 整数溢出报错 : 使用 ~0 表示最大整数值: id=0'or (select(~0+!(select * from (select database())a))) --+ exp 函数: (select exp(~(select * from (select database())a))) --+ 2.1.5 堆叠注入 原理 :利用SQL语句中 ; 分隔多条语句的特性 风险 :可执行任意合法SQL语句,包括删除数据等危险操作 限制 :多数服务器限制一次只能执行一条SQL语句 2.1.6 二次注入 原理 : 用户上传参数时被转义(如 test' 变为 test\' ) 从数据库取出数据时未再次转义 导致原始注入语句被还原执行 示例 : 输入: test' union select 1,2,version() --+ 查询时变为: select * from user where username='test' union select 1,2,version() --+' 2.2 按提交方式分类 2.2.1 GET注入 参数出现在URL中 受URL长度限制 2.2.2 POST注入 参数通过POST请求体提交 多见于表单 2.2.3 HTTP头注入 注入点位于HTTP头部字段 常见注入点: Cookie HTTP_ CLIENT_ IP HTTP_ X_ FORWARDED_ FOR User-Agent Referer 3. 文件读写操作 3.1 条件 了解目标主机路径 有相应读写权限 可使用 outfile 、 load_file() 等函数 3.2 风险 写入webshell 通过工具(如中国菜刀、webacoo)连接控制服务器 4. SQL注入绕过技术 4.1 大小写绕过 示例: Union 代替 union 现代WAF基本已防御 4.2 双写绕过 示例: uniunionon 过滤后变为 union 主要用于过滤替换型WAF 4.3 编码绕过 URL编码 Unicode编码 Hex编码等 4.4 注释绕过 示例: id=1 /*!union*/ /*!select*/ 或: union /*kuyed*/ select /*iuysv*/ 1 4.5 宽字节绕过 条件:客户端与服务端编码不一致(如PHP utf8,MySQL gbk) 方法:在 / 前加 %df 4.6 Cookie绕过 利用 $_REQUEST 获取参数顺序(GET > POST > COOKIE) 当程序只检测GET/POST时,通过COOKIE传参 4.7 非常用函数 使用WAF不检测的冷门函数 5. SQL注入防御措施 5.1 基本原则 永远不信任用户输入 :包括数据库返回的数据 拒绝而非修复 :直接拒绝可疑请求而非尝试修复数据 5.2 参数化查询(预处理语句) 使用PDO的 bind_param() 绑定参数 避免SQL语句动态拼接 示例: 5.3 严谨编码实践 生产环境移除调试信息(如 mysql_error ) 验证数据最终存储需求(如字段长度限制) 5.4 最小权限原则 区分读写用户权限 业务用户仅拥有必要的最小权限 6. XSS注入(跨站脚本攻击) 6.1 分类 反射型 :非持久化,通过URL等即时触发 存储型 :持久化到数据库,所有访问者受影响 DOM型 :完全在客户端执行 基于页面型 6.2 常见触发方式 6.2.1 事件触发 onclick :点击元素时 onerror :资源加载失败时 onmouseover :鼠标悬停时 onload :元素加载完成时 6.2.2 常用标签 <script>alert("xss");</script> `` <a href=javascript:alert('xss')>test</a> <iframe onload=alert("xss");></iframe> <svg onload=alert(1)> 6.3 XSS绕过技术 6.3.1 编码绕过 Unicode编码 Base64编码 URL编码 6.3.2 特殊构造 使用 data: 协议: data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4= 拼接绕过: `` 优先级绕过: <title>> 6.4 XSS防御措施 6.4.1 输入过滤 使用 htmlspecialchars() 转义HTML特殊字符 白名单验证输入内容 6.4.2 纯前端渲染 静态HTML不包含业务数据 明确设置内容类型( .innerText 、 .setAttribute 等) 6.4.3 HttpOnly Cookie 禁止JavaScript读取敏感Cookie 7. 命令注入漏洞 7.1 产生条件 执行系统命令的函数参数用户可控 后端过滤不严格 7.2 危险函数(PHP) system() exec() shell_exec() passthru() popen() proc_popen() 7.3 命令拼接符 7.3.1 Windows $ , $$ , | , || 7.3.2 Linux & :后台运行 ; :命令结束符 | :管道 && :前命令成功则执行后命令 || :前命令失败则执行后命令 7.4 绕过技术 7.4.1 通配符 ? :匹配单个字符 * :匹配任意字符 [] :字符集匹配 示例: cat /*tc/pa??wd 7.4.2 未定义变量 Linux中未定义变量为null 示例: cat$a /etc$a/passwd$a 7.4.3 反引号与$() 将命令结果保存到变量 示例: echo $(pwd) 7.4.4 关键字替换 cat → more 、 vi 、 head 等 7.4.5 分段写入执行 将代码分段写入文件再执行 适用于长度受限情况 7.5 命令注入防御 7.5.1 输入验证 严格校验输入格式(如IP地址、URL等) 7.5.2 白名单限制 限制参数允许的内容 7.5.3 最小权限 Web应用程序使用最低必要权限 8. 代码注入漏洞(PHP) 8.1 文件包含漏洞 8.1.1 危险函数 include() include_once() require() require_once() 8.1.2 利用方式 包含恶意构造的文件 远程文件包含(需 allow_url_include 开启) 8.1.3 常见协议 http(s):// :远程文件包含 file:// :本地文件访问 zip:// :访问压缩包内文件 data:// :直接包含数据流 php:// :特殊PHP流 8.1.4 绕过技术 路径遍历: ../../../etc/passwd 空字节截断(PHP版本限制) 超长路径截断 8.2 代码执行函数 8.2.1 直接执行 eval() :执行字符串作为PHP代码 assert() :与 eval 类似 8.2.2 正则执行 preg_replace() 的 e 修饰符(已弃用) 8.2.3 回调函数 call_user_func() array_map() usort() 等 8.2.4 动态函数 $func = "system"; $func("whoami"); $$ 可变变量 8.3 代码注入防御 8.3.1 避免危险函数 尽量不使用 eval() 、 assert() 等 8.3.2 严格输入过滤 过滤特殊字符( / , . , .. 等) 限制文件包含路径 8.3.3 权限控制 重要文件加密存储 使用非常见路径名称 9. 总结 9.1 核心防御原则 不信任任何用户输入 最小权限原则 防御性编程 持续更新与补丁 9.2 开发者自查清单 是否使用预处理语句? 是否过滤所有用户输入? 是否关闭错误回显? 是否使用最低必要权限? 是否定期更新依赖库? 9.3 渗透测试要点 识别所有用户输入点 尝试各种注入技术 验证过滤与转义机制 检查错误处理方式 评估漏洞潜在影响 通过全面理解这些注入漏洞的原理、利用方式和防御措施,开发人员可以构建更安全的Web应用程序,安全人员也能更有效地发现和修复这些漏洞。