Skip to content

1. 数字型注入

输入的参数为整型时,如:ID、年龄、页码等,如果存在注入漏洞,则可以认为是数字型注入。

假设 URL 为 http://www.xxxxx.com/test.php?id=8 ,发起网络请求后,php 脚本把会把它转化为 SQL 语句,猜测为 select * from table where id=8。

测试步骤如下:

① 排除网络问题

http://www.xxxxx.com/test.php?id=8'

这样的语句会出错,导致脚本程序无法从数据库中正常获取数据,从而使原来的页面出现异常。(也有可能网站只要看到特殊符号就会报错 -- WAF 拦截)。

② 真值测试 -- 阳性对照

http://www.xxxxx.com/test.php?id=8 and 1=1

网页正常显示,说明数据库认可语法,且执行“真”的逻辑。

③ 假值测试 -- 阴性对照

http://www.xxxxx.com/test.php?id=8 and 1=2

数据消失(查询不出数据),证明逻辑判断被控制了。

以上三个步骤全部满足,程序可能存在 SQL 注入漏洞。

简单检测 -- 数学运算测试

id=2-1 如果显示 id=1 相同的内容,可能是数字型注入。

弱类型与强类型语言的安全性差异

PHP / ASP 弱类型语言,不会检查是不是一个纯数字,直接把参数存储为变量,变量类型自动转换为字符串。

Java、C# 强类型语言,本应接收整形的变量接收到字符串,会抛出异常,无法继续执行。所以强类型语言很少存在数字型注入漏洞。


2. 字符型注入

输入的参数为字符串时,称为字符型。数字型与字符型注入最大的区别在于,数字型不需要单引号闭合,而字符型一般要使用单引号闭合。

$sql = "SELECT * FROM users WHERE id = '你的输入'";

数字型例句: select * from table where id=8

字符型例句: select * from table where username='admin'

  • 字符型注入最关键的是如何闭合 SQL 语句以及注释多余的代码。

  • 加入像数字型注入一样,输入 1 and 1=1 ,SQL 语句变成 select * from table where id='1 and 1=1' ,注入是无效的。

  • 典型地, ' --+ 闭合前引号并注释后面的内容。

    • SQL 规定 -- 为注释(后面要有空格);
    • 浏览器在发送请求时会把地址栏中的空格吞掉或编码;
    • URL 传输标准中, + 代表空格。
    • 或者输入 %23(这是井号 # 的编码,MySQL 独有的注释符,不需要加空格)(不能直接用 # ,代表的是锚点,及页面的具体位置,后面的内容不会发送给服务器)
  • 在 SQL Server 中闭合前后两个引号: '+(select @@version)+'

  • 数据库不同,字符串连接符也不同,如 SQL Server 为 + ,Oracle 为 || ,MySQL 为空格。


3. SQL 注入分类

  • 基本上所有注入都可以归纳为数字型注入或字符型注入。

一些常见的注入叫法:

  • POST 注入:注入字段在 POST 数据中;
  • Cookie 注入:注入字段在 Cookie 数据中;
  • 延时注入:使用数据库延时特性注入;
  • 搜索注入:注入处为搜索的地点;
  • base64 注入:注入字符串需要经过 base64 加密。