网络安全---SQL注入攻击

一、实验目的

SQL 注入是一种代码注入技术,可利用 Web 应用程序和数据库服务器之间接口中的漏洞。当用户的输入在发送到后端数据库服务器之前未在 Web 应用程序中正确检查时,该漏洞就存在。

许多 Web 应用程序从用户处获取输入,然后使用这些输入构建 SQL 查询,以便从数据库获取信息。Web 应用程序还使用 SQL 查询将信息存储在数据库中。这些都是开发 Web 应用程序的常见做法。当 SQL 查询没有仔细构建时,可能会出现 SQL 注入漏洞。SQL 注入是 Web 应用程序上最常见的攻击之一。

在此次实验中,我们创建了一个易受 SQL 注入攻击的 Web 应用程序。我们的 Web 应用程序包括许多Web开发人员所犯的常见错误。我们实验的目标是找到利用 SQL 注入漏洞的方法,演示攻击可能造成的损害,并掌握有助于抵御此类攻击的技术。

本实验涵盖以下几个内容:SQL 语句:SELECT 和UPDATE 语句;SQL 注入;Prepared statement

二、实验环境

该实验已在SEED Ubuntu 20.04 VM上进行了测试。您可以从 SEED 网站下载VM影像,并在自己的计算机上运行 SEED VM。此外,大多数 SEED 实验都可以在云上进行,您也可以按照我们的指示在云上创建SEED VM。

实验设置文件

可以根据一下路径引导,在对应的网站下载安装相对应的数据压缩包,或者在我们自己的虚拟机中输入路径下载该文件,两种方式在后续都会展示。

作者网站下载:

首先进入链接SEED Project

展示如下:

此时我们点击页面展示中的labsetup.zip即可下载此次实验需要的安装包。

此外我们可以直接在虚拟机中下载解压该文件,操作如下:

首先在虚拟机中进入此次实验的文件路径,才相应的文件夹下,输入命令

$ wget https://seedsecuritylabs.org/Labs_20.04/Files/Web_SQL_injection/Labsetup.zip

--no-check-certificate **。**正常运行通过后,即下载完成,而后在该目录下进行解压缩即可。解压缩之后,我们通过相对应的容器命令对容器进行设置。容器的设置及命令如下所述。

容器设置和命令

在下面,我们列出了一些常用的Docker和Compose命令写。由于我们将非常频繁地使用这些命令,所以我们在.bashrc 文件中为他们创建了别名。

$ docker-compose build # Build the container image

$ docker-compose up # Start the container

$ docker-compose down # Shut down the container

// Aliases for the Compose commands above

$ dcbuild # Alias for: docker-compose build

$ dcup # Alias for: docker-compose up

$ dcdown # Alias for: docker-compose down

所有的容器都将在后台运行。要在容器上运行命令,我们通常需要在容器上获得一个shell。我们首先需要使用"docker ps"命令来找出容器的 ID,然后使用" docker exec "在该容器上启动shell。同样。我们在 .bashrc文件中为这些命令创建了别名。

$ dockps %%//%% Alias for: docker ps --format "{{.ID}} {{.Names}}"

$ docksh %%//%% Alias for: docker exec -it /bin/bash

// The following example shows how to get a shell inside hostC

注意:如果docker命令需要容器 ID,则不需要键入整个 ID 字符串。输入前几个字符就足够了,只要它们在所有容器中能够相互区分。通过以上命令,我们首先对容器进行创建:

$dcbuild 运行结果如下:

而后我们对容器进行启动:

$dcup 运行结果如下:

至此,我们的docker容器已经创建并且成功启动,其中包含了此次实验所需要的数据库的加载和生成相关信息。

同时,我们根据压缩文件中的相关信息可以知道,我们已经为这个实验开发了一个网络应用程序,并使用容器来设置这个网络应用程序。实验设置中有两个容器,一个用于托管 Web 应用程序,另一个用于托管 Web 应用程序依赖的数据库。Web 应用程序容器的 IP 地址为 10.9.0.5,Web应用程序的 URL 如下:

http://www.seed-server.com

我们需要将此主机名映射到容器的IP地址。请将以下条目添加到 /etc/hosts 文件中。您需要使用root特权来更改此文件(使用sudo)。需要注意的是,由于其他一些实验,此名称可能已添加到文件中。如果映射到不同的 IP 地址,则必须删除旧条目。

10.9.0.5 www.seed-server.com

最后一行中我们添加上我们需要的映射即可

MySQL 数据库

容器通常是一次性的,因此一旦被销毁,容器内的所有数据都会丢失。对于此次实验,我们确实希望将数据保留在 MySQL 数据库中,确保我们在关闭容器时,我们不会丢失工作。为此,我们将主机上的mysql_data文件夹(在 MySQL 容器运行后,在Labsetup文件夹内创建)装载(mounted)到MySQL容器内的 /var/lib/mysql 文件夹中。mysql_data文件夹是 MySQL 存储其数据库的地方。因此,即使容器被销毁,数据库中的数据仍保留。如果我们确实想从纯净的数据库开始,可以删除此文件夹:

$ sudo rm -rf mysql_data

关于 Web 应用程序

我们创建了一个 Web 应用程序,这是一个简单的员工管理应用程序。员工可以通过此Web应用程序查看和更新数据库中的个人信息。此Web应用程序主要有两个角色:Administrator是一个特权角色,可以管理每个员工的个人资料信息:Employee是一个正常的角色,可以查看或更新自己的个人资料信息。表1中描述了所有员工信息。

Table 1: Database

Name Employee ID Password Salary Birthday SSN Nickname Email Address Phone#
Admin 99999 seedadmin 400000 3/5 43254314
Alice 10000 seedalice 20000 9/20 10211002
Boby 20000 seedboby 50000 4/20 10213352
Ryan 30000 seedryan 90000 4/10 32193525
Samy 40000 seedsamy 40000 1/11 32111111
Ted 50000 seedted 110000 11/3 24343244

三、实验内容

任务 1: 熟悉 SQL 语句

任务 2: 基于SELECT语句的SQL注入攻击

任务 3: 基于UPDATE语句的 SQL 注入攻击

任务 4: 对策---Prepared 语句

四、实验步骤

任务 1: 熟悉SQL语句

此任务的目标是通过使用提供的数据库来熟悉 SQL 命令。我们的 Web 应用程序使用的数据存储在 MySQL 数据库中,该数据库托管在我们的 MySQL 容器中。我们已经创建了一个名为sqllab_users的数据库,其中包含一个名为credential的表。该表存储每个员工的个人信息(例如,eid, password, salary, ssn等)。在这项任务中,您需要使用数据库来熟悉 SQL 查询。请在 MySQL 容器上获取shell(请参阅容器说明;手册链接到实验的网站)。然后使用 mysql 客户端程序与数据库进行交互。用户名是root,密码是 dees。

// Inside the MySQL container

mysql -u root -pdees

可知此时我们开启容器,并且进入数据库容器,运行SQL命令后即可进入数据库。登录后,我们可以创建新的数据库或加载现有数据库。由于我们已经利用labsetup压缩文件中创建的sqllab_users数据库,因此只需要使用使用命令加载此现有数据库。要显示sqllab_users数据库中存在哪些表,您可以使用显示表命令打印出选定数据库的所有表。后续的操作可以进一步使我们熟悉SQL的相关语句。

mysql> use sqllab_users; //使用数据库

Database changed

mysql> show tables; //展示数据库中的表信息

+------------------------+

| Tables_in_sqllab_users |

+------------------------+

| credential |

+------------------------+

运行上述命令后,您需要使用 SQL 命令打印员工 Alice 的所有个人资料信息。截图如下:

任务 2: 基于SELECT语句的SQL注入攻击

SQL 注入是一种基本攻击技术,攻击者可以通过该技术执行自己的恶意 SQL 语句(通常称为恶意payload有效载荷)。通过恶意 SQL 语句,攻击者可以从受害者数据库窃取信息:更糟的是,他们也许能够对数据库进行更改。我们的员工管理 Web 应用程序具有 SQL 注入漏洞,它模仿了开发人员经常犯的错误。

我们将使用 www.seed-server.com 的登录页面执行此任务。登录页面显示在图 1 中。它要求用户提供用户名和密码。Web 应用程序根据这两个数据对用户进行身份验证,因此只有知道密码的员工才能登录。作为攻击者,我们的工作是在不知道任何员工凭据的情况下登录 Web 应用程序。登录界面如下:

我们首先了解如何在 Web 应用程序中实现身份验证。PHP 代码unsafe home.php位于/var/www/SQL_Injection 目录中,用于进行用户身份验证。以下代码片段显示用户如何进行身份验证。

$input_uname = $_GET['username'];

$input_pwd = $_GET['Password'];

hashed_pwd = sha1(input_pwd);

...

$sql = "SELECT id, name, eid, salary, birth, ssn, address, email,nickname, Password FROM credential

WHERE name= 'input_uname' and Password='hashed_pwd'";

$result = conn -\> query(sql);

%%//%% The following is Pseudo Code

if(id != NULL) {

if(name=='admin') {

return All employees information;

} else if (name !=NULL){

return employee information;

}

} else {

Authentication Fails;

}

上述 SQL 语句从credential表中选择员工个人信息,如 ID、姓名、工资、ssn等。

SQL 语句使用两个输入变量input_uname和hashed_pwd,其中input_uname是在登录页面的用户名字段中键入的字符串,而hashed_pwd则保存用户键入的密码的sha1哈希值。程序检查任何记录是否与所提供的用户名和密码匹配;如果匹配,用户将成功进行身份验证,并获得相应的员工信息。如果没有匹配,则身份验证将失败。

任务 2.1 :来自网页的 SQL 注入攻击。

我们的任务是从登录页面以管理员的身份登录 Web 应用程序,以便可以查看所有员工的信息。我们假设确实知道管理员的帐户名称是admin,但不知道密码。此时,我们需要决定在用户名和密码字段中键入什么才能在攻击中取得成功。

我们通过分析登录界面的相关代码可以知道,其中的SQL语句存在登录的漏洞,我们通过输入一直的用户名,构造一个伪SQL语句即可登录,展示如上。

任务 2.2 :从命令行进行 SQL 注入攻击。

此时的任务是重复任务 2.1,但需要在不使用网页的情况下执行此任务。我们可以使用命令行工具,如curl,它可以发送 HTTP 请求。值得一提的是,如果要在 HTTP 请求中包含多个参数,则需要将 URL 和参数放在一对单引号之间;否则,用于分离参数(& )的特殊字符将由shell程序解释,从而更改命令的含义。下列示例显示了如何向我们的 Web 应用程序发送 HTTP GET 请求,并附加了两个参数(用户名和密码):

$ curl 'www.seed-server.com/unsafe_home.php?username=alice&Password=seedalice'

如果需要在用户名或密码字段中包含特殊字符,则需要正确编码它们,或者它们可能更改请求的含义。如果想在这些字段包含单引号,我们应该用%27代替:如果想包括空格,我们应该使用%20。在这项任务中,当使用curl发送请求时,我们确实需要处理 HTTP 编码。

由上图,我们可以看出,通过命令行的方式,我们也能够访问到我们的目标网页,通过对图中标记的代码段进行解析,我们可以得到相应的数据信息。但是此时我们需要注意的是需要讲1中的"'""#"转换成%27和%23以及将其中的空格转换成"+"。

任务 2.3 :附加新的 SQL 语句。

在上述两次攻击中,我们只能从数据库中窃取信息;如果我们能够使用登录页面中的相同漏洞修改数据库,情况会更好。一种想法是使用 SQL 注入攻击将一个 SQL 语句变成两个,第二个是更新或删除语句。在 SQL 中,分号(;)用于分离两个 SQL 语句。请尝试通过登录页面运行两个 SQL 语句。

通过登录界面实现两个SQL语句登录:由图可知登录失败

通过curl的方式,我们在命令行进行访问时,得到的结果是一样的,也就是说,在MySQL数据库中是无法利用两个SQL语句进行对漏洞的攻击和访问的。

任务 3:基于UPDATE语句的 SQL 注入攻击

如果 SQL 注入漏洞发生在 UPDATE 声明中,则损坏将更为严重,因为攻击者可以使用该漏洞修改数据库。在我们的员工管理应用程序中,有一个编辑配置文件页面(图 2),允许员工更新其个人资料信息,包括昵称、电子邮件、地址、电话号码和密码。要访问此页面,员工需要首先登录。

当员工通过编辑配置文件页面更新其信息时,将执行以下SQL UPDATE查询。Unsafe_edit_backend.php代码文件用于更新员工的个人资料信息,该PHP 文件位于 /var/www/SQLInjection目录中。

hashed_pwd = sha1(input_pwd);

$sql = "UPDATE credential SET

nickname='$input_nickname',

email='$input_email',

address='$input_address',

Password='$hashed_pwd',

PhoneNumber='$input_phonenumber'

WHERE ID=$id;";

conn-\>query(sql);

任务 3.1 :修改自己的工资。

如编辑配置文件页面所示,员工只能更新昵称、电子邮件、地址、电话号码和密码;他们无权更改工资。假设我们是员工Alice,而你的老板Boby今年没有增加你的薪水。我们希望通过利用编辑配置文件页面中的 SQL 注入漏洞来增加自己的工资。并且我们知道工资在SQL语句中存储在字段名为salary中。

由上面所得到的代码段落分析,我们通过下图中的操作,即可利用该系统中的SQL漏洞进行修改个人的工资。

工资修改之前的个人各项数据情况,分别是个人主页面和Edit Profile页面的情况:

由上文的代码块我们可知,最终提交的字段为Phone Number,所以我们在输入时通过更改在Phone Number中的数据内容,来完成我们对个人工资信息的更改,输入语句如下:

Phonenumber',salary=' 修改工资 ( 标点均为英文)

通过上述操作后,我们在此查看自己个人的信息,可以看到已经修改了个人的工资以及其他的各项信息:

任务 3.2 :修改他人工资。

由上操作,我们可知晓,可以通过更改相关的字段来更改自己个人的工资,下面我们将利用相同的原理对Boby的工资进行修改(目标为将工资修改为1)。

Password='$hashed_pwd',

PhoneNumber='$input_phonenumber'

WHERE ID=$id;";

这几行代码我们可以知道,最终提交哦SQL语句时是通过ID进行区别人员的,所以我们还是和任务3.1一样,在Phone Number中进行操作,入的代码如下:

Phonenumber',salary='1' where name='Boby';#

截图展示如下:

过此番操作后,我们可以通过登录管理员的账号进行查询,以验证我们的操作是否生效,查询结果如下图所展示:

过查询,我们可以看到已经将 Boby 的工资修改为 "1"

任务 3.3 :修改他人密码。

由3.2我们已经对Boby的薪资进行了修改,下一步我们希望能够通过类似的方式,利用sql语句中的漏洞,将Boby 的账户密码修改为我们知晓的,从而我们可以登录其账户进行进一步的操作。此时,我们知道了上述的相应代码块以及知晓数据库存储了密码的哈希值,而不是简单的密码字符串并且它使用了SHA1 哈希功能生成密码的哈希值。下面我们将尝试是否能够更改Boby的账户密码。

此过程中我们将通过修改Phone number中的语句来修改Boby的密码,语句如下:

123456',Password=sha1('alice11') where name='Boby';#

通过上述的修改后,我们通过登录Boby的账户进行验证是否修改成功,我们将先输入原始密码:seedboby,通过登录发现密码错误无法登录。:

接下来我们将输入自己修改后的密码进行登录验证:

此时我们发现,登录成功,证明我们对Boby的密码修改成功。

五、实验结果及分析

此次实验,我们通过多项操作能够实现对一个简单编写的前端页面和数据库的SQL注入攻击,实验过程中我们通过不同的方法实现了对用户信息以及用户账户信息的更改和侵入。此外,我们通过对源代码的分析,基本上实现了简单SQL注入攻击的防御,但是相对而言还有更多的问题亟待解决,不过就整体而言,初步达到了实验的预期目标。

六、总结

通过此次实验,我们利用SQL注入的方法实现了相关的简易攻击,进一步理解了数据库漏洞的危害性,同时明白了web开发过程中严谨性的重要性,熟悉了web开发中开发人员常犯的常规错误,使得我们更加清晰的认识了SQL注入攻击带来的损害。

相关推荐
鸭梨山大。22 分钟前
Jenkins 任意文件读取(CVE-2024-23897)修复及复现
安全·中间件·jenkins
小蜗牛慢慢爬行26 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
hanbarger30 分钟前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
码农土豆44 分钟前
PaddlePaddle飞桨Linux系统Docker版安装
linux·docker·paddlepaddle
微服务 spring cloud1 小时前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试
先睡1 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式
弗罗里达老大爷1 小时前
Redis
数据库·redis·缓存
黑客老陈1 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
仰望大佬0072 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#