extractvalue()和updatexml()最常用,因在mysql 5.1–8.0.21间稳定可用,原理均为传入非法xpath(如concat(0x7e, (select database()), 0x7e))触发错误,使数据库将拼接内容原样回显在xpath syntax error消息中,但均受限于32字节长度。

报错注入能一次请求就拿到数据,不是靠猜,是让数据库自己“说漏嘴”。
extractvalue() 和 updatexml() 为什么最常用
这两个函数在 MySQL 5.1–8.0.21 之间稳定可用,原理都是:传入非法 XPath 表达式 → 触发错误 → 把第二个参数原样塞进错误消息里回显。
-
extractvalue(1, concat(0x7e, (SELECT database()), 0x7e))错误提示形如XPATH syntax error: '~security~' -
updatexml(1, concat(0x7e, (SELECT user()), 0x7e), 1)同样回显波浪号包裹的内容 - 必须用
concat(0x7e, ... , 0x7e),因为0x7e是~,破坏 XPath 语法才触发错误;直接拼字符串可能被当作文本处理而不报错 - 两者都限制第二个参数总长 ≤32 字节,超长会被截断——查长字段名或密码哈希时,必须配合
substr()分段提取
floor(rand()*2) 报错为什么越来越难用
这个老套路依赖 GROUP BY + 随机数导致主键冲突,但实战中失败率高、构造复杂。
- 必须嵌套三层:外层
SELECT、中间GROUP BY x、内层CONCAT(..., FLOOR(RAND(0)*2)),少一层就不报错 - 第一次执行可能不触发(因 rand 种子未复现),重放 payload 有时成功有时失败
- MySQL 8.0.3+ 对
rand()在聚合上下文中的行为做了调整,很多环境直接静默忽略 - WAF 更容易识别
rand+group by组合特征,比extractvalue更容易被拦截
MySQL 8.0.22+ 之后还能用报错注入吗
能,但 extractvalue() 和 updatexml() 默认禁用,得换函数。
- 优先试
geometrycollection((select * from (select geometrycollection(point(1,1)), (select database())) a))—— 利用几何函数解析失败回显 - 或用
polygon((select * from (select polygon(point(1,1)), (select user())) a)),原理类似 - 这些替代函数没有 32 字节硬限制,但错误格式不如
extractvalue整洁,需正则提取波浪号或括号间内容 - 注意:若目标开了
sql_mode=STRICT_TRANS_TABLES,部分几何函数会直接报语法错误而非回显,此时要退回到布尔盲注
真正卡住报错注入的,往往不是函数失效,而是错误信息被应用层吃掉——比如 PHP 开启了 display_errors = Off,或前端用 try/catch 吞了异常再返回通用提示。这种情况下,连 ' 都不报错,报错注入就彻底失效。











