如何针对Mysql漏洞测试您自己的Web服务器

电子说

1.3w人已加入

描述

第1步:设置测试环境

要测试代码,您应该设置一个测试环境。可以在计算机上使用xampp或lampp完成此操作。当然,您可以自己用php设置一个Apache网络服务器。

您将需要一个网络服务器,一个mysql数据库和一个运行中的php解释器来执行代码。

步骤2:示例数据库

对于我们的测试案例,我们使用一个非常基本的数据库,其中有两个用户。使用md5算法保护密码。只需在数据库上运行以下mysql代码即可创建表:

SET SQL_MODE = “NO_AUTO_VALUE_ON_ZERO”;

SET AUTOCOMMIT = 0;

START TRANSACTION;

SET time_zone = “+00:00”;

CREATE TABLE IF NOT EXISTS `user` (

`id` bigint(15) NOT NULL,

`email` varchar(255) NOT NULL,

`password` varchar(32) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

INSERT INTO `user` (`id`, `email`, `password`) VALUES

(1, ‘admin@mysite.com’, ‘b655e3f4ae881514c4896b9cd707e4d2’),

(2, ‘guest@mysite.com’, ‘5d41402abc4b2a76b9719d911017c592’);

ALTER TABLE `user`

ADD PRIMARY KEY (`id`);

ALTER TABLE `user`

MODIFY `id` bigint(15) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;COMMIT;

步骤3:关于密码安全性的简短介绍

全世界的计算能力正在飞速增长,md5不再是强大的哈希算法。所使用的哈希是使用以下密码生成的:

b655e3f4ae881514c4896b9cd707e4d2 = top secret password that will never be cracked that fast

5d41402abc4b2a76b9719d911017c592 = hello

由于存在彩虹表之类的东西,即使google本身也是一个很好的密码破解机。当您搜索“ 5d41402abc4b2a76b9719d911017c592”时,第一个结果是明文密码。当您在Google中搜索“ b655e3f4ae881514c4896b9cd707e4d2”时,由于输入字符串太长而无法使用蛮力方法破解,因此您将不会获得任何结果。

因此:请使用在任何词典中都不会出现的长密码!/p》

步骤4:示例代码

漏洞

出于测试原因,我编写了这个小脚本。它打开一个数据库连接,提供一个表单,并尝试在数据库中查找与您输入的凭据(电子邮件和密码)匹配的用户。只需将脚本保存在Web服务器上,然后将文件命名为“ mysql-injection.php”即可。当数据库名称不同时,可能必须为“ mysql_select_db”函数更新数据库名称:

error_reporting(E_ALL ^ E_DEPRECATED);

mysql_connect(‘localhost’, ‘root’, ‘’);

mysql_select_db(‘mysql-injection’);

if (!empty($_POST[‘email’]) && !empty($_POST[‘password’]))

{

$query = ‘SELECT * FROM `user` WHERE `email` = \’‘.$_POST[’email‘]。’\‘ AND `password` = \’‘.md5($_POST[’password‘])。’\‘’;

echo ‘Used query: ’,$query,‘’;

$resource = mysql_query($query);

$matches = mysql_num_rows($resource);

if ($matches 》 0)

{

$user = mysql_fetch_assoc($resource);

echo ‘Hello ’.$user[‘email’]。‘!’;

}

else

{

echo ‘Invalid credentials!’;

}

}

?》

Log in to get privileges!

Mail:

Password:

步骤5:测试脚本

漏洞

漏洞

漏洞

漏洞

要开始使用,只需在Web浏览器上调用脚本即可。在我的情况下,该网址为http://sand.box:8081/mysql-injection.php,因为我将“ sand.box”路由为“ 127.0.0.1”。您只需调用http://sand.box:8081/mysql-injection.php或http://sand.box:8081/mysql-injection.php即可使其正常工作。

我们现在可以使用以下凭据测试登录:

admin@mysite.com:top secret password that will never be cracked that fast

guest@mysite.com:hello

如您在屏幕快照中所见,脚本返回“ Hello ”以证明您的登录凭据正确。使用任何其他组合可获得“无效的凭据!”错误。

这是有效的用户身份验证。但是它非常危险。请查看下一步,了解原因。

步骤6:幕后花絮

由于脚本输出了用于选择正确用户的数据库查询,因此您可以看到背后发生了什么现场。当您以管理员身份登录时,以下查询:

‘SELECT * FROM `user` WHERE `email` = \’‘.$_POST[’email‘]。’\‘ AND `password` = \’‘.md5($_POST[’password‘])。’\‘’

计算为:

‘SELECT * FROM `user` WHERE `email` = \’admin@mysite.com\‘ AND `password` = \’‘.md5(’top secret password that will never be cracked that fast‘)。’\‘’

,然后计算为:

‘SELECT * FROM `user` WHERE `email` = \’admin@mysite.com\‘ AND `password` = \’b655e3f4ae881514c4896b9cd707e4d2\‘’

,发送到mysql数据库的是:

SELECT * FROM `user` WHERE `email` = ‘admin@mysite.com’ AND `password` = ‘b655e3f4ae881514c4896b9cd707e4d2’

因此,只需通过电子邮件地址和密码选择一个用户。在这种情况下,这是对邮件验证的可靠期望。变量$ _POST [‘email’]在附加到查询之前是不安全的,因此我们可以在此处注入很多邪恶的东西。 $ _POST [‘password’]变量在被隐式存储到数据库查询之前被传递给md5(),因此这是“意外的安全”,因为md5()仅返回数字和字符,没有任何东西会使我们的查询崩溃。 》

步骤7:破解!

漏洞

正如我们在上一步中了解到的那样,$ _ POST [‘email’]是我们的后门。因此,当您输入以下电子邮件时,您可以以所需的任何用户身份登录。对于ID为1的用户:

test@test.de‘ OR `id` = 1 OR 1 = ’

对于ID为2的用户:

test@test.de‘ OR `id` = 2 OR 1 = ’

如您所见,使用的mysql查询如下:

SELECT * FROM `user` WHERE `email` = ‘test@test.de’ OR `id` = 1 OR 1 = ‘’ AND `password` = ‘098f6bcd4621d373cade4e832627b4f6’

由于查询中没有括号,因此我们可以通过在电子邮件中传递一个‘来停止字符串。之后,我们可以修改查询本身。因此,我们仅添加另一个与用户ID相关的“ OR”条件。这使电子邮件和密码已过时,因为一旦“ OR”条件为真,mysql就会停止检查条件。因此,如果我们的数据库中有一个ID为“ 1”的用户,我们便已登录。

步骤8:保护您的代码

漏洞

要确保此代码安全,只需转义用户输入即可。例如,可以使用mysql_real_escape_string方法来完成此操作。另一个功能可能是斜杠。因此,“安全”解决方案将使用:

mysql_real_escape_string($_POST[’email‘])

而不是

$_POST[’email‘]

所以这是最终的php代码:

$query = ’SELECT * FROM `user` WHERE `email` = \‘’.mysql_real_escape_string($_POST[‘email’])。‘\’ AND `password` = \‘’.md5($_POST[‘password’])。‘\’‘;

计算的查询为:

SELECT * FROM `user` WHERE `email` = ’test@test.de\‘ OR `id` = 1 OR 1 = \’‘ AND `password` = ’098f6bcd4621d373cade4e832627b4f6‘

因此,您可以看到,字符串中的单引号现在已转义,不再结束mysql字符串。这将导致查询搜索以下电子邮件地址:

test@test.de\’ OR `id` = 1 OR 1 = \‘

当然,这将失败,因为数据库中没有匹配的电子邮件。

第9步:仅仅为了获得一个想法

编写此指令是为了在一个非常基本的情况下获得mysql注入的想法。在2015年,您不会自己编写php应用程序,而是使用可以为您处理大部分安全性和数据库内容的框架和库。但是您应该知道在幕后发生了什么事,以便快速,安全地编写代码。

例如,一个好的解决方案是使用symfony2框架。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分