查看: 21930|回复: 9

再谈Mysql中limit后的注入

[复制链接]
发表于 2016-3-11 09:10:31 | 显示全部楼层 |阅读模式
0x01 问题来了
   前几天@DM_同学在群里发现一个问题,关于mysql中limit的注入。目前limit后注入的唯一方法是使用procedure analyse进行报错注入,详细请阅读http://zone.wooyun.org/content/18220,在文中提到此方法适用于5.x系列的mysql,然而DM_测试5.6.11的时候此方法报错(无耻盗@DM_图一张):
2016031019040392033.jpg
那么问题就来了,翻遍国内外资料,群里各位大佬介不知情况。本着追根溯源的精神,我“不自量力”的翻看了mysql源码,发现了此问题的原因。

0x02问题根源
先说结论:此方法只适用于小于5.6.6的5.x系列。
翻看5.6.6以下版本的analyse()实现
https://github.com/mysql/mysql-server/blob/5.5/sql/sql_analyse.cc
重点在加粗函数
[PHP] 查看源码 复制代码
else if (param->next) 
  { 
    // first parameter 
    if (!(*param->item)->fixed && (*param->item)->fix_fields(thd, param->item)) 
    { 
      DBUG_PRINT("info", ("fix_fields() for the first parameter failed")); 
      goto err; 
    } 
······ 
······   
    // second parameter 
    if (!(*param->item)->fixed && (*param->item)->fix_fields(thd, param->item)) 
    { 
      DBUG_PRINT("info", ("fix_fields() for the second parameter failed")); 
      goto err; 
    }

我们动态调试
输入语句:
[PHP] 查看源码 复制代码
SELECT id FROM test WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(1,extractvalue(rand(),concat(0x3a,version())));

给proc_analyse_init函数下断点
对第一个参数做验证,fixed=1
2016031019072968668.png
对第二个参数做验证,fixed=0,表示此参数没有被固定,将被fix_fields函数处理
2016031019074825028.png
此次可以看见我们的第二个参数
[PHP] 查看源码 复制代码
extractvalue(rand(),concat(0x3a,version()))

将被fix_fields处理
在mysql中所有函数都是用Item_func类来表示的,当然extractvalue也不例外。
继续跟:
2016031019084080015.png
0x03为什么5.6.6以后不行了
在这个版本的时候analyse函数进行了改写,于是乎不行了
2016031019142357445.png
怎么改写的?你没有看错,两个参数都只能为uint了。
2016031019091774272.png
0x03总结
各种装逼半天,其实我就想说limit后的注入,使用analyse()只能5.0.0<mysql<5.6.6的版本
2016031019094888383.jpg
2016031019100199998.png
回复

使用道具 举报

发表于 2016-3-11 09:14:13 | 显示全部楼层
赞一个…… 快拿本子记一下
回复 支持 反对

使用道具 举报

发表于 2016-3-11 09:22:00 | 显示全部楼层
这个牛逼,赞一个!
回复 支持 反对

使用道具 举报

发表于 2016-3-11 09:30:53 | 显示全部楼层
卧槽C动态调试,老牛换口味了
回复 支持 反对

使用道具 举报

发表于 2016-3-11 15:07:06 | 显示全部楼层
转载请注明出处
回复 支持 反对

使用道具 举报

发表于 2016-3-11 16:53:06 | 显示全部楼层
我无耻的转载了
回复 支持 反对

使用道具 举报

发表于 2016-3-12 23:05:38 | 显示全部楼层
原来如此...学习了
回复 支持 反对

使用道具 举报

发表于 2026-5-20 08:10:01 | 显示全部楼层

Re: 再谈Mysql中limit后的注入

感谢楼主的深入分析和源码追踪,清晰地解释了 `LIMIT` 后注入的版本限制原因。之前只知道`procedure analyse`可以报错,但没想过为什么高版本失效,这篇从源码层面解答了疑惑。对于还在使用低版本MySQL的环境,这个技巧依然有用;升级后确实需要寻找其他方法。干货满满,赞!
回复 支持 反对

使用道具 举报

发表于 2026-6-19 14:20:01 | 显示全部楼层

Re: 再谈Mysql中limit后的注入

楼主的分析很深入,从源码层面解释了为什么 procedure analyse 注入在 MySQL 5.6.6 以上版本失效,赞一个。之前遇到类似问题一直没找到确切原因,这下明白了,原来是 analyse 函数的参数类型改成了 uint,导致无法再通过注入函数报错。这对实战中的版本判断很有参考价值。另外,想请教下楼主,在 5.6.6 之后的版本,如果遇到 limit 后的注入点,还有没有其他可行的利用思路?
回复 支持 反对

使用道具 举报

发表于 2026-6-19 19:00:00 | 显示全部楼层

Re: 再谈Mysql中limit后的注入

楼主的分析真的很透彻,从发现5.6.11下procedure analyse报错到翻阅源码找到根本原因,这种追根溯源的精神值得学习。原来问题出在5.6.6版本对analyse函数做了改写,两个参数都只能接受uint,导致之前巧妙的报错注入方法失效了。这个总结对做MySQL注入测试的人非常实用,感谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-7 05:11 , Processed in 0.037141 second(s), 20 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部