环境配置
Kali-Linux-2021 + WebGoat 8.2.2
1
概念
本课将介绍什么是结构化查询语言(SQL),以及如何操纵 SQL 来执行开发人员原意之外的任务。
目标
-
用户将基本了解 SQL 的工作原理和用途
-
用户将基本了解什么是 SQL 注入及其工作原理
-
用户将展示以下方面的知识
-
DML、DDL 和 DCL
-
字符串 SQL 注入
-
数字 SQL 注入
-
SQL 注入如何违反中央情报局三要素
-
2
什么是 SQL?
SQL 是一种标准化(1986 年 ANSI 标准,1987 年 ISO 标准)编程语言,用于管理关系数据库并对其中的数据执行各种操作。
数据库是数据的集合。数据被组织成行、列和表,并编制索引,以便更有效地查找相关信息。
包含雇员数据的 SQL 表示例;表名为 "雇员":
某公司在数据库中保存了以下员工信息:唯一的员工编号("userid")、姓、名、部门、工资和交易验证码("auth_tan")。每条信息都存储在单独的列中,每一行代表公司的一名员工。
SQL 查询可用于修改数据库表及其索引结构,以及添加、更新和删除数据行。
SQL 命令主要分为三类:
-
数据操作语言(DML)
-
数据定义语言(DDL)
-
数据控制语言(DCL)
攻击者可以使用上述每种命令类型来破坏系统的机密性、完整性和/或可用性。继续学习本课,进一步了解 SQL 命令类型及其与保护目标的关系。
如果您还在为 SQL 而苦恼,需要更多信息或练习,可以访问 SQLCourse: Beginner & Advanced Interactive SQL Tutorials 免费获取互动在线培训。
轮到你了!
查看示例表。尝试检索雇员 Bob Franco 的部门。请注意,在这项任务中,您已被授予完全管理员权限,可以访问所有数据而无需身份验证。
答:SELECT department FROM employees WHERE first_name = 'Bob' AND last_name = 'Franco'
3
数据操作语言(DML)
顾名思义,数据处理语言就是处理数据的语言。许多最常见的 SQL 语句,包括 SELECT、INSERT、UPDATE 和 DELETE,都可归类为 DML 语句。DML 语句可用于请求记录(SELECT)、添加记录(INSERT)、删除记录(DELETE)和修改现有记录(UPDATE)。
如果攻击者成功将 DML 语句 "注入 "到 SQL 数据库中,他就可以破坏系统的机密性(使用 SELECT 语句)、完整性(使用 UPDATE 语句)和可用性(使用 DELETE 或 UPDATE 语句)。
-
DML 命令用于存储、检索、修改和删除数据。
-
SELECT - 从数据库中检索数据
-
INSERT - 向数据库中插入数据
-
UPDATE - 更新数据库中的现有数据
-
DELETE - 从数据库中删除记录
-
示例
-
检索数据:
-
SELECT phone FROM employees WHERE userid = 96134;
-
该语句检索用户名为 96134 的雇员的电话号码。
-
轮到你了!
尝试将 Tobi Barnett 的部门更改为 "销售"。请注意,在这项任务中,您已被授予完全管理员权限,可以访问所有数据而无需身份验证。
答:UPDATE employees SET department = 'Sales' WHERE first_name = 'Tobi' AND last_name = 'Barnett'
4
数据定义语言(DDL)
数据定义语言包括用于定义数据结构的命令。DDL 命令通常用于定义数据库的模式。模式是指数据库的整体结构或组织,在 SQL 数据库中包括表、索引、视图、关系、触发器等对象。
如果攻击者成功将 DDL 类型的 SQL 命令 "注入 "数据库,他就可以破坏系统的完整性(使用 ALTER 和 DROP 语句)和可用性(使用 DROP 语句)。
-
DDL 命令用于创建、修改和删除数据库对象的结构。
-
CREATE - 创建表格和视图等数据库对象
-
ALTER - 更改现有数据库的结构
-
DROP - 从数据库中删除对象
-
示例:
-
CREATE TABLE employees(userid varchar(6) not null primary key,
first_name varchar(20),
last_name varchar(20),
department varchar(20),
salary varchar(10),
auth_tan varchar(6)
);
-
该语句创建了第 2 页中的雇员示例表。
-
现在尝试修改模式,在表 "employees "中添加列 "phone"(varchar(20)):
答:ALTER TABLE employees ADD phone varchar(20)
5
数据控制语言(DCL)
数据控制语言用于在数据库中实现访问控制逻辑。DCL 可用于撤销和授予数据库对象(如表、视图和函数)的用户权限。
如果攻击者成功地将 DCL 类型的 SQL 命令 "注入 "数据库,他就可以破坏系统的保密性(使用 GRANT 命令)和可用性(使用 REVOKE 命令)。例如,攻击者可以授予自己数据库管理员权限或撤销真正管理员的权限。
-
DCL 命令用于对数据库对象实施访问控制。
-
GRANT - 授予用户对数据库对象的访问权限
-
REVOKE - 撤销先前使用 GRANT 授予的用户权限
尝试将 grant_rights
表的权限授予用户 unauthorized_user
:
答:GRANT ALL PRIVILEGES ON grant_rights TO unauthorized_user;
6
什么是 SQL 注入?
SQL 注入(也称 SQLi)是最常见的网络黑客技术之一。SQL 注入攻击包括通过客户端向应用程序输入的 SQL 查询插入或 "注入 "恶意代码。如果处理不当,SQL 注入会严重影响数据完整性和安全性。
当来自客户端的未过滤数据(如来自搜索字段的输入)进入应用程序本身的 SQL 解释器时,就会发生 SQL 注入。如果应用程序未能正确消毒用户输入(使用准备语句或类似语句)或过滤输入的特殊字符,黑客就可以操纵底层 SQL 语句以达到自己的目的。
例如,如果输入未过滤 SQL 元字符,如--(注释掉该行的其余部分)或;(结束 SQL 查询),就可能导致 SQL 注入。
SQL 注入示例
例如,一个网络应用程序允许用户通过在表单字段中输入用户名来获取用户信息。用户的输入会被发送到服务器,并被插入到 SQL 查询中,然后由 SQL 解释器进行处理。
从数据库中获取用户信息的 SQL 查询如下:
"SELECT * FROM users WHERE name = '" + userName + "'";
变量 userName 保存来自客户端的输入,并将其 "注入 "查询。
如果输入是 Smith,查询就会变成
"SELECT * FROM users WHERE name = 'Smith'";
并将检索名称为 Smith 的用户的所有数据。
如果攻击者输入的数据中包含对 SQL 解释器有 "特殊 "含义的字符或字符串(如 ;、-- 或 '),而这些数据未经过正确的消毒或验证,攻击者就可以修改 SQL 查询的预期行为,从而在数据库上执行其他(恶意)操作。
下面是一个输入字段。请尝试在此输入一些 SQL,以便更好地理解查询是如何变化的。
Username:
"SELECT * FROM users WHERE name = ''";
示例
SQL 注入的用途远不止读取单个用户的数据。以下是黑客在表单字段(或接受用户输入的任何地方)输入数据以试图利用 SQL 注入漏洞的几个示例:
-
Smith' OR '1' = '1
结果是
SELECT * FROM users WHERE name = 'Smith' OR TRUE;
这将返回用户表中的所有条目 -
Smith' OR 1 = 1; --
结果为
SELECT * FROM users WHERE name = 'Smith' OR TRUE;--';
与第一个示例一样,也将返回用户表中的所有条目 -
Smith'; DROP TABLE users; TRUNCATE audit_log; --
为了 DROP 表 users 和删除 audit_log 表中的所有条目,使用多个 SQL 命令链
7
SQL 注入的后果
成功的 SQL 注入可
-
读取和修改数据库中的敏感数据
-
在数据库上执行管理操作
-
关闭审计或 DBMS
-
截断表格和日志
-
添加用户
-
-
恢复 DBMS 文件系统中给定文件的内容
-
向操作系统发出命令
SQL 注入攻击允许攻击者
-
伪造身份
-
篡改现有数据
-
引发拒绝问题,如交易作废或余额变更
-
允许完全披露系统中的所有数据
-
销毁数据或以其他方式使其不可用
-
成为数据库服务器的管理员
8
SQL 注入的严重性
SQL 注入攻击的严重程度受以下因素限制
-
攻击者的技能和想象力
-
深度防御对策
-
输入验证
-
最小权限
-
-
数据库技术
并非所有数据库都支持命令链
-
微软 Access
-
MySQL 连接器/J 和 C
-
甲骨文
SQL 注入在 PHP、Classic ASP、Cold Fusion 和旧版语言中更为常见
-
不支持参数化查询的语言
-
新版本中已添加参数化查询
-
网络技术的早期采用者(即旧代码)
并非所有数据库都一样(SQL 服务器)
-
命令 shell:
master.dbo.xp_cmdshell 'cmd.exe dir c:'
-
注册表命令:
xp_regread
、xp_regdeletekey
、...
9
试试看 字符串 SQL 注入
如上例所示,代码中的查询建立了一个动态查询。该查询是通过连接字符串建立的,因此容易受到字符串 SQL 注入的攻击:
"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
尝试使用下面的表单从用户表中检索所有用户。您不需要知道任何具体的用户名,就可以获得完整的列表。
SELECT * FROM user_data WHERE first_name = 'John' AND last_name = 'Smith' or '1' = '1'
答:Smith'
、or
、'1'='1
10
试试看 数字 SQL 注入
如上例所示,代码中的查询建立了一个动态查询。代码中的查询通过连接一个数字建立了一个动态查询,因此容易受到 Numeric SQL 注入的攻击:
"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = " + User_ID;
使用下面的两个输入字段,尝试检索用户表中的所有数据。
警告: 这些字段中只有一个容易被 SQL 注入。您需要找出是哪个字段,以便成功检索所有数据。
答:
Login_Count: 1
User_Id: 1 or 1 = 1
11
利用字符串 SQL 注入破坏保密性
如果一个系统容易受到 SQL 注入的攻击,那么该系统的 CIA 三元组就会很容易受到攻击(如果您不熟悉 CIA 三元组,请查看综合类别中的 CIA 三元组课程)。在接下来的三节课中,您将学习如何使用 SQL 字符串注入或查询链等技术入侵 CIA 三元组的每个方面。
本课我们将学习保密性。攻击者可以使用 SQL 注入轻松破坏保密性;例如,成功的 SQL 注入可以让攻击者从数据库中读取信用卡号码等敏感数据。
什么是字符串 SQL 注入?
如果应用程序只是通过将用户提供的字符串连接到查询来建立 SQL 查询,那么该应用程序很可能会受到字符串 SQL 注入的攻击。
更具体地说,如果用户提供的字符串未经任何消毒或处理就被连接到 SQL 查询中,那么只需在输入字段中插入引号,就可以修改查询行为。例如,可以用引号结束字符串参数,然后输入自己的 SQL。
轮到你了!
你是一名员工,名叫John Smith,在一家大公司工作。公司有一个内部系统,允许所有员工查看自己的内部数据,如所在部门和工资。
该系统要求员工使用唯一的身份验证 TAN 来查看自己的数据。
您当前的 TAN 是 3SL99A。
由于你总是有成为最高薪员工的冲动,因此你想利用该系统,不查看自己的内部数据,而是查看所有同事的数据,查看他们当前的工资。
使用下面的表格,尝试从雇员表中检索所有雇员数据。你不需要知道任何具体的姓名或 TAN 就能获取所需的信息。 您已经发现执行您的请求的查询如下所示:
"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
答:
Employee Name: 1
Authentication TAN: 1' or '1' = '1' --
12
利用查询链破坏完整性
继上一课破坏数据的机密性之后,这一次我们将使用 SQL 查询链破坏数据的完整性。
如果存在足够严重的漏洞,就可以使用 SQL 注入来破坏数据库中任何数据的完整性。成功的 SQL 注入可以让攻击者更改本不应该访问的信息。
什么是 SQL 查询链?
查询链就像它的名字一样。通过查询链,您可以尝试将一个或多个查询附加到实际查询的末尾。使用 ;
元字符就可以做到这一点。;
标志着 SQL 语句的结束;它允许在初始查询后立即开始另一个查询,甚至无需另起一行。
轮到你了!
你刚刚发现托比和鲍勃挣的钱似乎都比你多!你当然不能就这样算了。
最好去改变一下你自己的工资,让你赚得最多!
记住:你的名字是 John Smith,你现在的 TAN 是 3SL99A。
答:
Employee Name: 1
Authentication TAN: 1'; UPDATE employees SET salary=100000 WHERE first_name = 'John' AND last_name = 'Smith'; --
13
破坏可用性
在前几课成功破坏了保密性和完整性之后,我们现在要破坏 CIA 三要素中的第三个要素:可用性。
破坏可用性的方法有很多种。如果账户被删除或密码被更改,账户的实际所有者就无法再访问该账户。攻击者还可以尝试删除数据库的部分内容,甚至删除整个数据库,使数据无法访问。取消管理员或其他用户的访问权限是另一种影响可用性的方法;这将阻止这些用户访问数据库的特定部分,甚至整个数据库。
轮到你了!
现在你是公司里最赚钱的人。但你看到了吗?似乎有一个 access_log 表,其中记录了你的所有操作!
最好在别人发现之前彻底删除它。
答:
Action contains: '; DROP TABLE access_log; --