Joomla 1.5~3.4 session对象注入漏洞

更新时间:

 许可信息:  本文采用 自由转载-非商用-非衍生-保持署名 许可协议,作者alpha1e0,转载请注明作者或出处链接。

本文分析Joomla 1.5~3.4 session对象注入漏洞

1 漏洞原理

joomla在处理session时,会将User-Agent X-Forwarded-For存储到$_SESSION中,$_SESSION在加载的时候会反序列化,再加上其他特性最终导致对象注入。

exploit

以下的内容以joomla 3.2.1为例进行分析

1.1 session中存储User-Agent X-Forwarded-For信息

@libraries/joomla/session/session.php #L974

session

其中,$this->set会设置$_SESSION

session2

1.2 PHP<5.6.13 中session反序列化机制(session.serialize_handle=php时)

在注入session的过程中,我们使用以下payload

User-Agent: }__test|a:2:{s:4:"talk";a:2:{s:6:"target";s:3:"tom";s:7:"counter";i:100;}s:2:"kk";s:4:"vvvv";}\xd8\x34\xdf\x06

序列化之后变成了

__default|a:8:{s:15:"session.counter";i:1;s:19:"session.timer.start";i:1465956802;s:18:"session.timer.last";i:1465956802;s:17:"session.timer.now";i:1465956802;s:22:"session.client.browser";s:98:"}__test|a:2:{s:4:"talk";a:2:{s:6:"target";s:3:"tom";s:7:"counter";i:100;}s:2:"kk";s:4:"vvvv";}

可以看到,session的序列化数据中,有两个key-value对,_default和_test,很显然,session[_default]部分是不可能反序列化的,我们的拼接导致了session[_default]出错了,并且我们不可能构造正确的session[_default]

但是,在PHP<5.6.13版本中,当session中一个key-value反序列化出错后,PHP没有停止反序列化,而是继续下一个key-value的反序列化,而session[_test]是我们可以控制的,唯一的麻烦是我们需要截断(session[User-Agent]后还有很多内容)

1.3 session存储在mysql数据库中的截断技巧

通过官网介绍

“The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. ”

mysql在使用utf8的时候,一个字符的大小的上限为3字节,而当出现四个字节的字符时,是需要用使用utf8mb4编码,不使用的话,会将不识别的四字节的字符连同后面的字符串一同舍弃

例如,使用特殊字符 进行更新

UPDATE user SET name = 'alice特殊字符some ' WHERE id =1;

则name会被更新为alice,some会被丢弃。

而具体哪些4字节的utf8 word会造成截断需要做fuzzing找

在Joomla中使用 \xd8\x34\xdf\x06 这个utf8 word来做截断

1.4 执行链构造

通过搜索eval/assert/call_user_func可以找到用于构造执行链的类,例如在joomla中找到如下:

@libraries/joomla/database/driver/mysqli.php JDatabaseDriverMysqli类 #L83

JDatabaseDriverMysqli

disconnect的定义 #L200

这个类唯一的问题是call_user_func_array中的参数部分不能控制,因此没有太大价值,只能做POC

例如控制参数:

$this->disconnectHandlers = array("print_r");

这样可以打印$this,可以构造POC,例如以下的生成payload的代码

POC

@libraries/simplepie/simplepie.php SimplePie类 #L1544,init函数

可以看到,其中$this->cache_name_function$this->feed_url都可以控制

只是init反序列化时候不能调用,因此需要结合JDatabaseDriverMysqli使用,即:

$this->disconnectHandlers = array(array(SimplePie实例,"init"));

这里还有一个问题,SimpliePie不是自动加载的,因此需要想办法把SimplePie加载一下,这里使用

@/libraries/legacy/simplepie/factory.php JSimplepieFactory类 该类会自动加载,加载的过程中会加载SimplePie

SimplePie

结合以上所有内容就得到了构建对象注入的方法,poc如下:

总结,该漏洞非常精巧,需要同时满足以下条件:

  • User-Agent为检测直接存入$_SESSION
  • PHP<5.6.13 session处理的小问题
  • Mysql4字节urf8 word截断
  • 可以构造执行链

2 参考:

  • http://drops.wooyun.org/papers/11330
  • http://bobao.360.cn/learning/detail/2501.html
  • http://xteam.baidu.com/?p=177
  • http://lynahex.com/index.php/archives/PHP-Object-Injection.html

标签:

 打赏:  如果您觉得该文档有用,可以选择微信扫码打赏,谢谢
微信打赏码