文档库 最新最全的文档下载
当前位置:文档库 › SQL注入攻击实验

SQL注入攻击实验

SQL注入攻击实验
SQL注入攻击实验

课外实践作业一:SQL注入实验

(1) 实验描述

在本次实验中,我们修改了phpBB的web应用程序,并且关闭了phpBB实现的一些对抗SQL注入的功能。因而我们创建了一个可以被SQL注入的phpBB版本。尽管我们的修改是人工的,但是它们代表着web开发人员的一些共同错误。学生的任务是发现SQL注入漏洞,实现攻击者可以达到的破坏,同时学习抵挡这样的攻击的技术。

(2) 实验环境

SEED Ubuntu镜像

●环境配置

实验需要三样东西,Firefox、apache、phpBB2(镜像中已有):

①运行Apache Server:镜像已经安装,只需运行命令%sudo service apache2 start

②phpBB2 web应用:镜像已经安装,通过https://www.wendangku.net/doc/634908185.html,访问,应

用程序源代码位于/var/www/SQL/SQLLabMysqlPhpbb/

③配置DNS:上述的URL仅仅在镜像内部可以访问,原因是我们修改了/etc/hosts

文件使https://www.wendangku.net/doc/634908185.html,指向本机IP 127.0.0.1。如果需要在其他机器访问,应该修改hosts文件,使URL映射到phpBB2所在机器的IP。

●关闭对抗措施

PHP提供了自动对抗SQL注入的机制,被称为magic quote,我们需要关闭它。

1.找到/etc/php5/apache2/php.ini

2.找到magic_quotes_gpc = On这一行

3.改为magic_quotes_gpc = Off

4.重启Apache:”sudo service apache2 restart”

●Note for Instructors最好拥有一些背景知识

1.使用虚拟机,Firefox的插件LiveHttpHeaders和Tamper Data

2.对SQL语句的一些了解

3.如何操作MySQL数据库

4.对PHP一些了解

(3) 实验任务

①对SELECT语句的攻击

此次任务,你需要通过访问虚拟机内的URL:https://www.wendangku.net/doc/634908185.html,。在进入phpBB 之前系统会要求你登陆。这个登陆认证由服务器上的login.php实现,需要用户输入用户名和密码来通过认证。界面如下:

用户键入用户名和密码后,login.php会将它们与mysql数据库中的username和user_password字段进行比较,如果匹配就登陆成功。和其他大多数web应用程序一样,PHP 程序使用SQL语言与背后的数据库交互。在phpBB2中,下面的语句实现了对用户的认证

对登陆的SQL注入攻击:以上语句存在SQL注入漏洞,你能利用这个漏洞来达到以下目的吗?

●你能在不知道其他人的密码下登陆他的账号吗?

●你能找到修改数据库的方法吗(依旧使用上面的SQL语句)?比如新建一个database,

或者删除一个用户的账号。很显然,上述语句是数据库查询语句,并不能修改(UPDA TE)数据库。然而,使用SQL注入,你可以使上面的语句变成两句,用第二句来修改数据库。请尝试这种方法,看是否能够成功。

坦白地说,我们没能够更改数据库,这是由于MySQL的防御措施。在报告中,你应该描述你如何尝试的,并找出为什么会失败,MySQL使用了什么方法来抵御这样的攻击。你可以从网上寻找答案(第二手),当然你的第一手证据会有更多得分。万一你找到了方法成功地攻击了,那将得到一个额外加分。

②对UPDATE语句的攻击

当用户想要在phpBB2中修改他们的资料时,可以点击Profile,然后填写表单修改。用户发送修改请求后,会执行include/usercp_register.php中的一条UPDA TE SQL语句。在这条语句中同样有一个SQL注入漏洞,请用它来达到以下目标:

在不知道其他人密码的情况下修改其资料。例如:你以Alice登陆,你的目标就是修改Ted的资料信息,包括他的密码。攻击成功后你将可以登陆Ted的账号。

③对抗SQL注入

SQL注入漏洞的根本原因是没有将代码和数据区分开。当组建一个SQL语句时,程序(如PHP程序)知道哪个部分是代码哪个部分是数据。不幸的是当SQL语句送往数据库执行时,这个边界被打破,当程序被注入时,SQL解释器看到的边界可能和最初的边界不一样。为了解决这个问题,保持服务端程序和数据库看到的边界一样就十分重要。

●使用magic_quotes_gpc避开特殊字符。

PHP代码中的字符串类型的数据需要用单引号(…)引起来。比如上面的任务中username=?$username?,单引号用于把$username从代码中区分出来。不幸的是如果$username 中含有单引号,这个区分将被打破。我们需要一个机制告诉数据库$username中的单引号应该被当做数据,而不是SQL语句的特殊字符。为此我们只需要在单引号前加一个反斜杠(\) PHP提供了自动在单引号、双引号、反斜杠和空字符前添加反斜杠的机制,如果这个选项启用,那么所有这些从用户输入的特殊字符会被加反斜杠。启用方法为,修改/etc/php5/apache2/php.ini的magic_quotes_gpc = On,然后重启Apache。

请分别启用/禁用该功能来看这个机制是如何实现保护的。(php5.3.0后该功能弃用)

●使用addslashes()来避开特殊字符。

PHP的方法addslashes()可以达到magic quote同样的功能。如果magic quote没有弃用,phpBB2的代码会使用该功能来防止SQL注入攻击。请查看/var/www/SQL/SQLLabMysqlPhpbb目录下的common.php。实际上为了使SQL注入攻击成功,我们注释掉了phpBB2的保护措施。

请修改回phpBB2的保护功能,并观察移除下面代码中”and FALSE”前后的区别,描述这个保护机制如果防止SQL注入攻击的。

if( !get_magic_quotes_gpc() and FALSE )

为了帮助描述区别,你需要打印出SQL语句。

●使用mysql_real_escape_string避开特殊字符

一个较好的方法来防止SQL注入攻击是使用数据库的回避机制。MySQL提供了一个机制,叫mysql_real_escape_string(),它在一些特殊字符前加反斜杠,包括:\x00, \n, \r, \, ?, “, 和\x1A。

请使用该功能来修复前面任务中的SQL注入漏洞(需要禁用前面提到的保护机制)。

●Prepare Statement

一个更平常的解决方法是将数据和SQL逻辑区分开来准确地告诉数据库哪是数据部分以及哪是逻辑部分。MySQL提供了Prepare Statement机制来达到这一目的。

$db=newmysqli("localhost","user","pass","db");

$stmt=$db->prepare("SELECT * FROMusersWHEREname=?ANDage=?");

$stmt->bind_param("si",$user,$age);

$stmt->execute();

使用该机制,我们将发送SQL语句分为几步。第一步先发送代码,如需要下一步填入数据的SQL语句,这是进行准备的一步。然后我们再用bind_param()发送数据至数据库。这样数据库就可以区分代码和数据了。

请使用该机制来修复前面的SQL注入漏洞。(bind_param函数中的第一个参数”si”的意思是第一个参数$user是字符串类型,第二个参数$age是整数类型)。

相关文档