课程编写

类别

内容

实验课题名称

SQL注入攻击

实验目的与要求

1.了解SQL注入攻击带来的危险性。

2.掌握SQL注入攻击的原理与方法

3.掌握防范攻击的方法

实验环境

VPC1(虚拟PC

Windows server 2003

VPC1 连接要求

PC 网络接口,本地连接与实验网络直连

软件描述

1、学生机要求安装java环境
2
vpc安装windwos 系统

实验环境描述

  1. 学生机与实验室网络直连;
  2. VPC1与实验室网络直连;
  3. 学生机与VPC1物理链路连通;

预备知识

PHPWeb应用程序架构中,大部分都是配合MySQL数据库来保存相关的数据。例如会员登录、留言板、讨论区的账号、密码、真实姓名、住址及联系电话等个人信息,或是购物系统的商品与价格等记录。

    Web应用程序使用SQL语句来操作MySQL数据库。例如,select表达式用来读取数据库的记录,insert表达式用来在数据库中插入新的记录,delete表达式用来删除数据库中的记录。

    设置了SQL语句的字符串后,使用mysql_query这类的PHP函数来将SQL语句传递给MySQL数据库系统处理。MySQL处理完后,会返回Web应用程序所需要的数据库记录。

    SQL注入攻击(SQL Injection)是利用在客户端的网页中输入数据,例如,在会员登录文本框中输入用户的账号和密码,用户在提交会员登录文本框的数据后,Web应用程序会将这些账号和密码与网站数据库中的相关记录相比较,或是插入到数据库内。

    一般地,用户在他的浏览器中输入的表单数据,Web应用程序会使用$_POST变量来保存。例如,$_POST["name"]是用户的名字,$_POST["email"]是用户的电子邮件信箱。而旦在SQL语句中,直接将SQL字符串与这些$_POST变量进行字符串连接。

    下面是一个简单的例子:

$query = "insert into member (name) values ("' . $_POST["name"] . '")";

$result = mysql_query($query)

黑客利用这种网页设计的既定模式,在客户端输入的表单数据(即$_POST变量的值)中加入特殊的代码,来改变原来的SQL语句。如果Web应用程序没有仔细检查$_POST变量的值就直接提交这个SQL语句,那么就会启动SQL注入攻击。

SQL注入攻击的步骤如图所示。

步骤1:黑客登录有SQL注入漏洞的网站,网站显示会员登录的网页。

步骤2:黑客在客户端输入会员登录所需的账号和密码,但是在账号/密码的字符串内加入特殊的代码。

步骤3:有SQL注入漏洞的网站将黑客所输入的账号和密码用$_POST变量来保存。并且将账号和密码的$_POST变量与SQL字符串进行连接来生成一个新的SQL语句。

步骤4:SQL注入漏洞的网站将查询的SQL语句提交到MySQL数据库处理。

步骤5:因为SQL语句中被黑客注入了代码而引发SQL注入攻击。

实验内容

1.了解SQL注入攻击带来的危险性。

2.掌握SQL注入攻击的原理与方法

3.掌握防范攻击的方法

实验步骤

 

  1. 学生单击实验拓扑按钮,进入实验场景,进入目标主机,(第一次启动目标主机,还需要安装java控件),如图所示:

 

2.打开虚拟机,输入用户名和密码,用户为Adminsitrator 密码为 123456

3.打开浏览器,输入http://localhost:8080/example_code/ 如图:

4、找到“5SQl注入攻击(SQL injection,俗称负料隐码)”项,并点击打开。

 

5攻击实例:绕过账号、密码的检查

    先来看看上图,这是一个常见的形式简单的会员登录的画面。会员登录的功能是让来访者输入账号和密码来登录网站,入口网页的程序代码会判断来访者输入的账号和密码是否存在于数据库中。

如果输入的数据存在于数据库中,就让这个来访者登录网站,否则就提示信息要求来访者必须先注册。

 

图的网页是一个简单的会员登录的画面login.php,请试着执行它。login.php文件会读取ch数据库中的member数据表内的记录,如果使用者所输入的账号和密码存在于member数据表内,就会打开首页ex5-1.php

 

源码为http://localhost:8080/example_code/source/code5/login.php

 

所谓SQL注入攻击,就是在客户端的网页中输入特定的与SQL语句有关的代码。这段特定的程序代码会改变SQL语句,也就是login.php文件中有一段代码:

$query = "select * from member where username="' . $_POST["username"] . "' and password='" . $_POST["password"] . "'";

这个SQL语句用来把在账号密码文本框的输入值,与select语句连接成一个查询语句。

假如在上图的账号文本框中输入“daniel”,在密码文本框中输入“123456”,那么这个SQL语句会是:

select * from member where usemame='daniel' and password='123456'

使用mysql_query函数提交这个SQL语句后,如果daniel"“123456”的账号/密码值存在于ch数据库中的member数据表内,那么mysql_query函数会返回一个结果集:

$result=mysql_query($query);

    如果“daniel”“123456”的账号/密码值不存在于ch数据库中的member数据表内,那么mysql_query函数会返回FALSE

    如果能够让SQL语句:

        $query="select * from member where username="'.$_POST["username"]."' and password='" . $_POST["password"] . "'";

不检查$_POST["username"]$_POST["password"]的值,那么就可以绕开会员登录的数据检查而随意录入数据。

在类似这种检查账号密码值的入口网页,许多黑客利用暴力破解的方式来尝试账号/密码,或是设法取得他人的cookie来得获得目标的账号/密码。如果使用SQL注入攻击的话,根本就不需要账号/密码就可以直接进入网站。

 

6、开始攻击

攻击1实例

    现在打开“攻击1”,进行输入,账号文本框中输入“'OR"='”密码文本框中输入“'OR"='”

    “'OR"='”字符串是由下列字符所组成的:

      一个单引号:

      一个空白;

      OR

      一个空白:

      两个单引号;

      =;

      一个单引号。

输入情况下图所示。

 

    图为输入SQL注入攻击的字符串

结果如下图所示,无效的账号/密码值也可以用来登录网站。

     无效的账号/密码也可以登录

现在回头看看login.php文件中所用的SQL语句:

$query = "select * from member where username="' . $_POST["username"] . "' and password='" . $_POST["password"] , "'";

    账号文本框中输入“'OR"='”,在密码文本框中输入“'OR"='”,那么这个SQL语句会是:

select * from member where username='' OR ''='' and password='' OR ''=''

where子句中,username=''(两个单引号)表示username等于空字符串“"”,"="表示空字符串“''”等于空字符串“''”,所以结果为TRUEusemame='' OR ''=''的结果为TRUE,因为''=''TRUE,所以'' OR TRUE的结果为TRUE

    同样地,password=''(两个单引号)表示password等于空字符串“''”''=''表示空字符串''等于空字符串'',所以结果为TRUEpassword='' OR ''=''的结果为TRUE,因为''=''TRUE,所以 '' OR TRUE的结果为TRUE

    所以login.php文件的SQL语句:

 select * from member where username='' OR ''='' and password='' OR ''=''

等同于:

select * from member where TRUE and TRUE

    因此这个SQL语句不会验证账号和密码文本框所输入的值,而是直接查询member数据表内的所有记录。

 

 

攻击1的防护方法是:字符串变量的过滤方式(使用addslashes函数)。

      使用addslashes函数来将SQL语句中的单引号、双引号、“\”NULL字符加上反斜线“\”

      例如:addslashes("O'reilly")会变成:"O\'reilly"

注意,如果在php.ini文件中将magic_quotes_gpc设置为On,那么在GETPOSTCOOKIE的数据上会自动执行addslashes函数。如果再调用一次addslashes函数,就会变成加了两次反斜线“\”而产生错误。

点击“防护1”,进行输入,账号文本框中输入“'OR"='”密码文本框中输入“'OR"='”,网页不会提交

 

攻击2实例:删除数据库的所有记录

    现在来看下图,这是一个常见的简单形式的留言板。

下图的网页是ex5-2.php,执行这个页面,ex5-2.php文件会将留言的数据插入MySQL数据库ch5里面的postmessage数据表中。

 

    执行ex5-2-check.php文件,浏览ch数据库的postmessage数据表内的记录。

ex5-2-check.php文件的页面如图所示。

 

在如下图所示的标题文本框中,单击第一条超链接。这时会打开ex5-2-show.php文件来显示这一条留言,在ex5-2-show.php文件中有一个删除按钮,单击这个【删除】按钮后就会删除目前显示的这一条留言,如下图所示。

 

请注意在ex5-2-show.php的一段这样的程序代码,有一个删除按钮的程序代码:

<input type="submit" name="delete" id="delete" value="删除" />

删除’’按钮的nameid属性值是delete

    在删除目前这一条留言的时候,我们使用postmessage数据表内的id字段来标识。

$query = "delete from postmessage where id=" . $_POST["id"];

$_POST["id"]的值是由id这个隐藏文本框:

<input type="hidden" name="id" value="<?php echo $_GET['id'] ?>" />

而来的。

    id隐藏文本框的值,则是从ex5-2-show.phpURL参数id而来。

攻击1的防护方法是:字符串变量的过滤方式(使用addslashes函数)。

 

打开“攻击2”,点击超链接按钮进行攻击,删除所有记录,如下图。

 

同样攻击2的防护也可以使用addslashes函数来将SQL语句中的单引号、双引号、“\”NULL字符加上反斜线“\”

例如:打开“防护3”,点击按钮超链接进行防护。

 

攻击3实例:盗取密码

    现在来看下图,这是一个简单的首页的画面。

下图的网页是ex5-3.php,请试着执行它。ex5-3.php文件会读取ch5数据库中的member数据表内的记录,然后在访客:文字处显示member数据表的username文本框的值。

 

    上图是一个简单的首页的画面

    ex5-3.php文件需要URL参数id,这个id值是member数据表内的id文本框的值。在访客:文字处显示的username值,就是URL参数id所对应的username文本框的值。

    这段在ex5-3.php中的程序代码http://localhost:8080/example_code/source/code5/ex5-3.php

 

如何攻击

ex5-3.php文件中,查询所用的SQL语句是:

$query="select username from member where id=" . $_GET["id"];

    黑客利用在$_GET["id"]变量内加入union select表达式的方式来达到盗取会员密码的目的。

    union select表达式用来实现多重查询的功能,在$_GET["id"]变量内加入union select就会让ex5-3.php文件的SQL语句变成有两个select查询语句。

    1select查询语句是ex5-3.php原本的:

select username from member

2select查询语句是黑客加入的:

select password from member

    这个select查询语句用来盗取别人的密码。

    黑客必须让第1select查询语句失效,而让第2select查询语句成功,那么这个SQL语句就会返回password,而不是username的值。由于ex5-3.php预期SQL语句会返回username,所以在访客:文字处显示了这个SQL语句的查询结果。

但是实际上这个SQL语句返回的是password,所以原本要显示账号的地方就会显示密码的值。因此黑客就可以借着这种SQL注入攻击,来盗取网站会员的密码。

 

开始攻击

这个攻击的程序代码在ex5-3-attack.html文件中:

http://localhost:8080/example_code/source/code5/ex5-3-attack.html

ex5-3-attack.html文件实际上是执行一个HTTP链接:

http://localhost/example/ex5-3.php?id="union select password from member where usemame='daniel'/*

ex5-3.php文件的URL参数id的值等于:

"union select password from member where username='daniel'/*

开头是两个单引号“''”

    URL参数id的值代入SQL语句:

$query = "select username from member where id=".$_GET["id"];

结果得到:

        select username from member where id="union

        select password from member where username='daniel' /*

1select查询语句是ex5-3.php原本的:

        select username from member

但是无法执行。

2select查询语句是黑客加入的:

select password from member where username='daniel'

因此,这个SQL语句会返回password,而不是username的值。

打开“攻击3,攻击ex5-3.php文件,如下图所示。

  单击【攻击ex5-3.php文件】按钮后,就会执行ex5-3.php文件,使用SQL注入攻击来盗取密码,结果如下图所示。

在上图的访客:文字处,原本是要显示账号:

访客  : <?php echo htmlspecialchars($row['username'], ENT_QUOTES); ?>

但是,因为SQL注入攻击的缘故却显示了密码,黑客就因此盗取了网站会员的密码。

 

防范的方法:

    SQL注入攻击(SQL Injection)之所以会发生,是由于SQL语句被篡改的缘故。因此防御的方法,就是检查SQL语句中的变量数据是否是正确的格式。

    (1)如果数据确定是整数,就使用intval函数来将数据转换成整数。例如,id值通常是由MySQL数据库产生的整数类型的数字,因此使用intval函数来将id值转换成整数,以避免id值被窜改。

    (2)如果数据确定是浮点数,就使用floatvaldoubleval函数来将数据转换成浮点数。floatvaldoubleval函数的功能与语法相同。

    (3)如果数据确定是字符串,就使用addslashes函数来将单引号、双引号、“\”、及NULL字符加上反斜线“\”

 

7、实验完毕,关闭虚拟机和所有窗口。