您现在的位置是:烟消火灭网 > 知识
sql通过漏洞位置报错注入
烟消火灭网2026-10-17 07:47:02【知识】5人已围观
简介SQL注入能直接回显数据当然最省事,但实战里十有八九页面是哑巴——你插了引号,它只给你一个500或者空白页。这时候报错注入就是救命稻草。原理不复杂:数据库执行SQL出错时,如果应用把错误信息直接吐到页
SQL注入能直接回显数据当然最省事,过漏但实战里十有八九页面是洞位哑巴——你插了引号,它只给你一个500或者空白页。置报这时候报错注入就是错注救命稻草。原理不复杂:数据库执行SQL出错时,过漏如果应用把错误信息直接吐到页面上,洞位你就能把想查的置报数据塞进错误消息里带出来。
MySQL里最经典的错注报错函数是extractvalue()和updatexml()。拿extractvalue举例,过漏它第二个参数要求是洞位XPath格式,你传个concat(0x7e,置报 (select database()), 0x7e)进去,数据库会报错:XPATH syntax error: '~security~'。错注数据就这么出来了。过漏0x7e是洞位波浪号,当分隔符用,置报防止数据跟错误信息黏在一起看不清。
实际测试时我先用and extractvalue(1,concat(0x7e,version()))-- -探路。返回XPATH syntax error: '~5.7.26~',说明注入点存在,版本也拿到了。接着换database()、user(),逐个往外掏。注意extractvalue返回值最长32位,超长会截断,查表名的时候得用substring或者limit分段取。
查表名那一步稍微绕一点。直接select group_concat(table_name) from information_schema.tables where table_schema=database()塞进concat里,如果表名多,32位根本不够。我的做法是用limit 0,1逐条取,再配合substring切。比如and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))-- -,一次拿一张表。虽然慢,但稳。
有人问为什么不用floor(rand(0)*2)那种报错?那个依赖group by和临时表,MySQL 5.7之后很多环境已经打不出来了。extractvalue和updatexml更直接,只要XPath解析出错就报,不挑版本。不过MySQL 8.0开始这两个函数被移除了,得换GTID_SUBSET或者json相关的报错点。我上个月测一个8.0的站,extractvalue直接返回空,换成and gtid_subset(concat(0x7e,(select database())),1)-- -才出数据。
报错注入最怕两件事:一是应用把错误关了,页面只显示“系统繁忙”;二是WAF把extractvalue、updatexml这些关键词拦了。前者没辙,只能换盲注。后者可以尝试大小写混写、内联注释/*!extractvalue*/、或者用updatexml替代extractvalue。有次遇到安全狗,extractvalue被拦,我把e换成%65做URL编码,居然绕过去了。
还有个小细节:报错注入在order by后面用不了,因为order by不接受函数。得找where后面的注入点。如果只有order by能注,那就得用procedure analyse()那种老办法,或者干脆放弃报错走布尔盲注。
最后提一嘴,报错注入拿数据快,但请求量不小。查一个库的表名可能得发几十个请求。我习惯先count(*)看数量,再决定是group_concat一把梭还是limit慢慢磨。别嫌麻烦,能出数据就是好方法。
很赞哦!(8492)







