0. 运行环境:Ubuntu 16.04 LTS
1. 搭建 mysql 数据库,建立数据库 test ,数据表 student ,包含 id 、 name 、 score 三列。
1.1 搭建 MySQL 数据库
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.22-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
1.2 创建 test 数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| info_list |
| mysql |
| performance_schema |
| radius |
| student_info |
| sys |
| test | #目标数据库test
+--------------------+
8 rows in set (0.08 sec)
1.3 创建 student 数据表
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| student |
+----------------+
1 row in set (0.00 sec)
mysql> desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | double | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| score | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
# 已创建的数据
mysql> select * from student;
+-------------+-----------+-------+
| id | name | score |
+-------------+-----------+-------+
| 15180110007 | 闫瑞驰 | 86 |
| 15180110015 | 李雷 | 69 |
| 15180110033 | Tom | 76 |
| 15180110044 | Jack | 56 |
| 15180110055 | 韩梅梅 | 60 |
| 15180110066 | Jackson | 47 |
| 15180110077 | 梨花 | 98 |
+-------------+-----------+-------+
7 rows in set (0.00 sec)
2. 环境:PHP+Apache
3. 编写带有 sql 注入漏洞的接口程序
3.1 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果展示。如根据输入的学号展示姓名和分数。
查询结果中文字符被编码
3.2 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果是否为空。如输入学号,展示是否有该学生存在。
正常查询
非正常查询:
3.3 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果是否为空展示在两段随机内容之间。
3.4 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果的条件表达式结果,并将结果展示在两段随机内容之间。如入学号,展示该学生分数是否大于 60 。
3.5 根据输入的参数值,拼接 SQL 查询语句并执行,但展示一个固定的结果。如如输入学号,查询是否有学生存在,然后输出固定内容。
正常查询:
非正常查询:
3.6 据输入入的参数值,拼接SQL语句句并执行行行,更更新数据库。如输入入学号和分数,将对应学生生的分数更更新。
原始分数:
查询结果成绩为:86
更改成绩为:96
再次查询成绩为:96
4. 针对上述各个应用接口,手工修改请求参数,尝试各种 SQL 注入的攻击向量,和正常访问的对照组一起,观察结果并记录。
4.1 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果展示。如根据输入的学号展示姓名和分数。
通过字符串拼接注入展示 student 数据表中所有的数据
正常访问仅显示一条数据,而通过MySQL查询语句拼接可显示全部数据,此处可进行 Union 注入
4.2 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果是否为空。如输入学号,展示是否有该学生存在。
查询不存在的 0000 号学生
通过拼接MySQL查询语句,可查询到数据表中全部数据的情况,由此可推出数据表中的数据量有7个
4.3 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果是否为空展示在两段随机内容之间。
注入方法类似与上条,可以查询到数据库在数据量
4.4 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果的条件表达式结果,并将结果展示在两段随机内容之间。如入学号,展示该学生分数是否大于 60 。
注入方法类似与上条,因为输出内容为布尔型,可使用布尔注入
4.5 根据输入的参数值,拼接 SQL 查询语句并执行,但展示一个固定的结果。如如输入学号,查询是否有学生存在,然后输出固定内容。
注入方法类似与上条,因为输出内容固定,可使用基于时间的注入方法
4.6 据输入入的参数值,拼接SQL语句句并执行行行,更更新数据库。如输入入学号和分数,将对应学生生的分数更更新。
通过 MySQL 语句拼接,不仅可以更新分数,还可以对姓名进行更改
更新分数,拼接注入字段,更改姓名为 Richard
再次查询
姓名已更改为 Richard
5. 针对上述各个应用接口, 用 Sqlmap 尝试各种注入方式,并用 Wireshark 抓包,记录每次的目标、SQL 命令行、结果(包括出结果的过程、和最终的输出)、和抓包文件。
5.1 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果展示。如根据输入的学号展示姓名和分数。
正常访问:
使用Sqlmap注入
根据返回结果可判断此接口可通过 boolean-based、time-based、UNION query 方法注入
然后,使用 Wireshark 抓包,过滤规则:ip.src eq 127.0.0.1 and http.request.method == GET
选择其中一个攻击向量 urldecode
"/student/search.phpid=15180110007%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL--%20tMGo"
decode 后
"/student/search.php?id=15180110007 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL-- tMGo"
Sqlmap 尝试 Union query 注入。
5.2 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果是否为空。如输入学号,展示是否有该学生存在。
正常查询
使用 Sqlmap 注入
由此可以判断无法使用NULL值注入
最终可判断此接口可通过 boolean-based、time-based 方法注入,较上一个接口缺少了 Union query 方法,因为此接口返回值为布尔型返回值
然后,使用 Wireshark 抓包,过滤规则:ip.src eq 127.0.0.1 and http.request.method == GET
选择其中一个攻击向量 urldecode
"/student/search.phpid=-1273%20UNION%20ALL%20SELECT%20CONCAT%280x716a627071%2C0x4558737052456d564a6b%2C0x7170717071%29%2CNULL%2CNULL--%20LpWE"
decode 后
"/student/search.php?id=-1273 UNION ALL SELECT CONCAT(0x716a627071,0x4558737052456d564a6b,0x7170717071),NULL,NULL-- LpWE"
Sqlmap 尝试 Union query 注入,但没有成功。
5.3 根据输入的参数值,拼接 SQL 查询语句并执行,将查询结果是否为空展示在两段随机内容之间。**
正常访问
使用 Sqlmap 注入
可判断此接口可通过 boolean-based、time-based 方法注入,较上一个接口缺少了 Union query 方法,因为此接口返回值为布尔型返回值
然后,使用 Wireshark 抓包,过滤规则:ip.src eq 127.0.0.1 and http.request.method == GET
选择其中一个攻击向量 urldecode
"GET /student/search.php?id=15180110007%20ORDER%20BY%201--%20VPuP HTTP/1.1\r\n"
decode 后
"GET /student/search.php?id=15180110007 ORDER BY 1-- VPuP HTTP/1.1\r\n"
Sqlmap 尝试 ORDER BY 语句用于根据指定的列对结果集进行排序。
5.4 根据输入的参数值,拼接 SQL 查询语句并执行,展示查询结果的条件表达式结果,并将结果展示在两段随机内容之间。如入学号,展示该学生分数是否大于 60 。
使用 Sqlmap 注入
与上个接口结果类似,不作赘述
5.5 根据输入的参数值,拼接 SQL 查询语句并执行,但展示一个固定的结果。如如输入学号,查询是否有学生存在,然后输出固定内容。
正常查询:
使用 Sqlmap 注入
可判断此接口仅可通过 time-based 方法注入,较上一个接口缺少了 boolean-based、Union query 方法,因为此接口返回值为固定值,仅能通过时延来判断注入结果
然后,使用 Wireshark 抓包,过滤规则:ip.src eq 127.0.0.1 and http.request.method == GET
选择其中一个攻击向量 urldecode
"GET /student/search.php?id=15180110007%29%3BSELECT%20PG_SLEEP%285%29-- HTTP/1.1\r\n"
decode 后
"GET /student/search.php?id=15180110007);SELECT PG_SLEEP(5)-- HTTP/1.1\r\n"
Sqlmap 尝试使用 SLEEP 语句通过时延来判断注入结果。
5.6 根据输入的参数值,拼接SQL查询语句并执行,更更新数据库。如输入入学号和分数,将对应学生生的分数更更新。
使用 Sqlmap 注入
可判断此接口仅可通过 boolean-based 方法注入,较上一个接口缺少了 time-based、Union query 方法
然后,使用 Wireshark 抓包,过滤规则:ip.src eq 127.0.0.1 and http.request.method == GET
选择其中一个攻击向量 urldecode
"GET/student/update.phpid=%28SELECT%20%28CASE%20WHEN%20%2890%3D61%29%20THEN%206895%20ELSE%206895%2A%28SELECT%206895%20FROM%20INFORMATION_SCHEMA.PLUGINS%29%20END%29%29&score=88%27%2C%20name%20%3D%20%27Richard HTTP/1.1\r\n"
decode 后
"GET /student/update.php?id=(SELECT (CASE WHEN (90=61) THEN 6895 ELSE 6895*(SELECT 6895 FROM INFORMATION_SCHEMA.PLUGINS) END))&score=88', name = 'Richard HTTP/1.1\r\n"
Sqlmap 尝试使用 SELECT 语句注入。
6. 分析抓包文件,了解攻击向量,体会各种注入技术的原理。并回到 4 步骤中手动尝试。
抓包文件已放在附件
总结
经过这几天的上手操作,把以前学的数据库知识又拾起来了,并且学会了很多关于 SQL 注入的知识,学会了使用 Sqlmap、 Wireshark 等工具,了解了数据库的注入漏洞及注入方法,也学会了一些数据库防注入的一些方法,受益匪浅。