一哥新发的漏洞,还是蛮屌的: http://www.wooyun.org/bugs/wooyun-2016-0210850。分析补丁( http://www.phpwind.net/read/3709549 )加上一些风闻,我得知利用的是哈希长度扩展攻击。之前CTF中经常出境的MD5 Length Extension Attack,终于在实战中露了一次面。
今晚基本没睡觉,一直在调试这个漏洞,虽说不知道一哥后续getshell用的是什么方法,但我这个文章基本把该漏洞的原理讲清楚了。至于getshell的话,等漏洞公开了再看看吧。
0x01 漏洞点分析
phpwind逻辑太冗杂了,一看就是java程序员开发的。
补丁文件修补了src/windid/service/base/WindidUtility.php的appKey函数。之前的appKey函数如下:
public static function appKey($apiId, $time, $secretkey, $get, $post) { // 注意这里需要加上__data,因为下面的buildRequest()里加了。 $array = array('windidkey', 'clientid', 'time', '_json', 'jcallback', 'csrf_token', 'Filename', 'Upload', 'token', '__data'); $str = ''; ksort($get); ksort($post); foreach ($get AS $k=>$v) { if (in_array($k, $array)) continue; $str .=$k.$v; } foreach ($post AS $k=>$v) { if (in_array($k, $array)) continue; $str .=$k.$v; } return md5(md5($apiId.'||'.$secretkey).$time.$str); }
0x02 寻找已知哈希
public function showFlash($uid, $appId, $appKey, $getHtml = 1) { $time = Pw::getTime(); $key = WindidUtility::appKey($appId, $time, $appKey, array('uid'=>$uid, 'type'=>'flash', 'm'=>'api', 'a'=>'doAvatar', 'c'=>'avatar'), array('uid'=>'undefined')); $key2 = WindidUtility::appKey($appId, $time, $appKey, array('uid'=>$uid, 'type'=>'normal', 'm'=>'api', 'a'=>'doAvatar', 'c'=>'avatar'), array()); $postUrl = "postAction=ra_postAction&redirectURL=/&requestURL=" . urlencode(Wekit::app('windid')->url->base . "/index.php?m=api&c=avatar&a=doAvatar&uid=" . $uid . '&windidkey=' . $key . '&time=' . $time . '&clientid=' . $appId . '&type=flash') . '&avatar=' . urlencode($this->getAvatar($uid, 'big') . '?r=' . rand(1,99999)); ... }
这里调用了WindidUtility::appKey生成key,并将这个key放入了url中。其实这个功能是前台用户头像上传,我们来到 http://10.211.55.3/phpwind/index.php?m=profile&c=avatar&_left=avatar 右键源码即可查看到当前的key:
$get = some_sort(array('uid'=>$uid, 'type'=>'flash', 'm'=>'api', 'a'=>'doAvatar', 'c'=>'avatar')); $post = some_sort(array('uid'=>'undefined')); md5( md5($apiId.'||'.$secretkey) . time() . $get . $post )
在哈希长度扩展攻击中,我们是不需要知道这个secret的值的,只需要知道它的长度,上面这个字符串的长度很好算,md5固定32位,time时间戳10位,get和post两个数组也是固定的。
所以,经过计算,uid=2的用户获得的secret长度为55位。
0x03 进行扩展攻击
public function beforeAction($handlerAdapter) { parent::beforeAction($handlerAdapter); $charset = 'utf-8'; $_windidkey = $this->getInput('windidkey', 'get'); $_time = (int)$this->getInput('time', 'get'); $_clientid = (int)$this->getInput('clientid', 'get'); if (!$_time || !$_clientid) $this->output(WindidError::FAIL); $clent = $this->_getAppDs()->getApp($_clientid); if (!$clent) $this->output(WindidError::FAIL); if (WindidUtility::appKey($clent['id'], $_time, $clent['secretkey'], $this->getRequest()->getGet(null), $this->getRequest()->getPost()) != $_windidkey) $this->output(WindidError::FAIL); $time = Pw::getTime(); if ($time - $_time > 1200) $this->output(WindidError::TIMEOUT); $this->appid = $_clientid; }
我们看到,这里计算出 WindidUtility::appKey($clent['id'], $_time, $clent['secretkey'], $this->getRequest()->getGet(null), $this->getRequest()->getPost()) 的结果,与传入的windidkey进行比较,如果不相等,则函数报错。我们需要先构造出 1464044063adoAvatarcavatarmapitypeflashuid2uidundefined,才能够在后面增加我们需要的GET 和POST值。所以,我传入time=1464044063,而 adoAvatarcavatarmapitypeflashuid2uidundefined作为一个GET数组的键传入。这样,在appKey函数构造的过程中,就可以人为构造出secret,然后后面的内容就是可以利用的padding,如下图(s是未知的key,t是获取md5时的时间戳,R就是 adoAvatarcavatarmapitypeflashuid2uidundefined):所以,我们构造出类似如下的数据包:此时后端进行的加密如下:MD5( key + 1464048076 + adoAvatarcavatarmapitypeflashuid2uidundefined + %80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%B8%02%00%00%00%00%00%00 + sort(a=get&c=app&m=api&id=1) ) 我之前获取的secret如下:MD5( key + 1464048076 + adoAvatarcavatarmapitypeflashuid2uidundefined ) 正好满足哈希长度扩展攻击的条件,成功绕过beforeAction中的验证。0x04 获取敏感信息 + 修改管理员密码 + getshell我绕过了beforeAction的验证,其实效果类似于绕过了discuz中UC_KEY的验证过程。拿到了UC_KEY,就可以构造为任意用户做其权限(甚至是管理员权限)下的很多事情。
比如,获取敏感信息:获得所有系统配置信息(包括cookie加密的密钥):我写了一个脚本用来生成payload,我就不公开了。看懂的人自然会写,看不懂的人好好琢磨琢磨:另外,利用该方法可以修改所有系统配置、增删改APP、增删改查用户、修改用户密码等等。phpwind有个奇怪的逻辑,其管理员分为『创始人』和『管理员』,而创始人如果要登录后台,需要一个保存在文件中的账号密码,而管理员登录后台需要的是数据库中的账号密码。这个漏洞只能修改数据库中的账号密码,所以无法修改创始人的后台账号,但管理员权限也就够了,配合我之前发的phpwind后台getshell( http://www.wooyun.org/bugs/wooyun-2010-0175815 ),即可完美拿下。
http://www.wooyun.org/bugs/wooyun-2010-0175815
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论