shopex 4.8.5密码取回处新生成密码可预测漏洞(解禁)

标签: 象牙塔 | 发表时间:2011-10-14 14:14 | 作者:aullik5 Sam
出处:http://hi.baidu.com/aullik5

    最近一年来很少写blog,主要原因是三个,一是一直以来在blog里说的,稍微带点技术的东西,因为可能未来在公司里用得上,所以不方便在blog上讲;二是最近转战微博了,也算是顺应潮流;三是最近一年多来,博文视点约我写了一本书,仅有的那么一点时间也要投入到写书大计中,实在没什么时间再写博客这种奢侈的东西。好在这本关于Web Security的书终于是快要写完了,在最近应该能够交稿,一共写了18章,第一次写书,没什么经验,还有很多不尽如人意的地方,但丑媳妇总得见公婆。

 

    未来可能时间会稍微多一点,其实最主要的原因是我的工作重心会从纷乱的项目中抽出来,往技术研究方面做些偏移,所以这个blog会慢慢的恢复更新。今天就先丢个小玩意上来吧,shopex的这个漏洞有点意思,虽然shopex的代码安全质量很有问题,但我们在此只关注这个有意思的地方,出于和谐的考虑,原文的POC代码也和谐掉了,见谅。

 

    我们知道弱伪随机数算法往往会带来很多安全问题,而程序员最容易犯的一个错误就是使用时间函数代替伪随机数算法,无形中使得本来容易犯错的随机数问题直接变成可预测的漏洞。

    在shopex 4.8.5中,密码取回没有使用发送激活链接到邮箱的方式,而是直接生成一个新的密码发送到用户邮箱中。这个设计本身就不够安全,而新生成的密码算法是这样的:

/core/shop/controller/ctl.passport.php中:

    function sendPSW(){

        $this->begin($this->system->mkUrl('passport','lost'));

        $member=&$this->system->loadModel('member/member');

        $data=$member->getMemberByUser($_POST['uname']);

        if(($data['pw_answer']!=$_POST['pw_answer']) || ($data['email']!=$_POST['email'])){

            $this->end(false,__('问题回答错误或当前账户的邮箱填写错误'),$this->system->mkUrl('passport','lost'));

        }

 

        if( $data['member_id'] < 1 ){

            $this->end(false,__('会员信息错误'),$this->system->mkUrl('passport','lost'));

        }

 

        $messenger = &$this->system->loadModel('system/messenger');echo microtime()."<br/>";

        $passwd = substr(md5(print_r(microtime(),true)),0,6);

 

        $pObj=$this->system->loadModel('member/passport');

        if ($obj=$pObj->function_judge('edituser')){

            $res = $obj->edituser($data['uname'],'',$passwd,$data['email'], '1');

            if ($res>0){

                $member->update(array('password'=>md5($passwd)),array('member_id'=>intval($data['member_id'])));

            }

            else{

                trigger_error('输入的旧密码与原密码不符!', E_USER_ERROR);

                return false;

            }

        }else{

            $member->update(array('password'=>md5($passwd)),array('member_id'=>intval($data['member_id'])));

        }

 

        $data['passwd'] = $passwd;

        $memberObj = &$this->system->loadModel('member/account');

        $memberObj->fireEvent('lostPw',$data,$data['member_id']);

 

        $this->end(true,__('邮件已经发送'),$this->system->mkUrl('passport','index'));

    }

 

    注意加粗的部分,新生成的用户密码实际上就是取了当前时间 microtime() 的md5值的前6位。

 

    但PHP 中microtime()的值除了当前服务器的秒数外,还有微秒数,比如:

 0.55452100 1315562338

    微妙数的变化范围在0.000000 -- 0.999999 之间,一般来说,服务器的时间可以通过HTTP返回头的DATE字段来获取,因此我们只需要遍历这1000000可能值即可。

    但我们要使用暴力破解的方式发起1000000次网络请求的话,网络请求数也会非常之大。可是shopex非常贴心的在生成密码前再次将microtime() 输出了一次:

        $messenger = &$this->system->loadModel('system/messenger');echo microtime()."<br/>";

    两次microtime()的调用间隔非常之短,使得我们破解的成本实际上非常低廉。至今仍然没有想明白shopex为什么要写这段代码,难道是开发留的后门?

 

    要成功利用这个漏洞需要满足以下条件:

 触发密码取回流程,这需要回答安全问题或者是用户注册邮箱填写正确;而shopex默认用户注册是只需要邮箱而不需要填写安全问题的

 

    在自动化验证新密码是否正确时,需要自动登录网站,而shopex的登录默认便是有验证码的。可是这个验证码的实现存在缺陷:

                if($_COOKIE["S_RANDOM_CODE"]!=md5($_POST['signupverifycode'])){

                    $this->splash('failed','back',__('验证码录入错误,请重新输入'),'','',$_POST['from_minipassport']);

                } 

    验证码的验证,实际上是比对两个值,一个是Cookie S_RANDOM_CODE的值,另一个是验证码的md5,因此通过一个小trick就能够绕过shopex的验证码机制:提交验证码为1234,并自定义cookie值为md5("1234"),这个验证码的校验将永远有效。

 

    结合上面这些,最终给出了我们的exploit:

[略]。。。。。。

 

测试如下:

D:\research\vulndb\shopex>python getpass.py target username email

(测试网站略)

 

在实际利用中,很多shopex小版本不返回微秒数,但能抓取到秒数。暴力破解微妙数的话,请求会过于频繁。在此不赘述了。

 

PS:此漏洞一月前已提交wooyun

http://www.wooyun.org/bug.php?action=view&id=2814

 

阅读全文
类别:象牙塔 查看评论

相关 [shopex 密码 新生] 推荐:

shopex 4.8.5密码取回处新生成密码可预测漏洞(解禁)

- Sam - 大风起兮云飞扬
    最近一年来很少写blog,主要原因是三个,一是一直以来在blog里说的,稍微带点技术的东西,因为可能未来在公司里用得上,所以不方便在blog上讲;二是最近转战微博了,也算是顺应潮流;三是最近一年多来,博文视点约我写了一本书,仅有的那么一点时间也要投入到写书大计中,实在没什么时间再写博客这种奢侈的东西.

oracle 忘记密码

- - Oracle - 数据库 - ITeye博客
Oracle一段时间不用了,再登录就登不上去,真乃怪哉,不止俺一人出现此问题,先不问为什么出现这个现象,解决这个问题应急先,网上搜罗解决办法,. ORA-01017 invalid username/password;logon denied" (密码丢失解决方案). 1、先确认是否输错 用户名和密码.

Amazon密码找回记

- lszhao - 白板报
【核心提示】越来越多的美国互联网服务公司使用电话作为终极的客服沟通方式,而这些呼叫中心往往建在印度,这意味着中国用户如果想解决技术难题,必须苦练口语和听力. 自从买了Kindle电子书,我成了亚马逊的忠实用户. 亚马逊虽然在使用条款中规定,电子书只针对美国用户销售,并且只接受美国信用卡,但实际操作中有简单的变通手段.

正确重置MySQL密码

- xxg - 火丁笔记
谁都不想弄丢家门钥匙,但不管多么小心,时间长了,这样的事情总会发生几次. MySQL密码也是一样,把它写在文档上不太安全,记在脑子里又难免会忘记. 如果你忘记了MySQL密码,如何重置它呢. 首先停止MySQL服务,然后使用skip-grant-tables参数启动它:. 此时无需授权就可以进入到MySQL命令行,使用SQL重置MySQL密码:.

小心输入Gmail密码

- Eneri - 张磊的blog
最近在使用gmail时,会遇到原本登录的情况下还会提示输入用户名密码的情况. 感觉蹊跷就检查了一下页面源代码,果然是钓鱼行为. 我用gmail都是直接点击Google工具栏的按钮,但在家里和公司的电脑都会被劫持,特别地,家里在用Mac公司是Windows,不可能同时中了一样的木马. 应该是运营商(两边的网络都是北京联通)做了手脚问题出在网络上.

密码背后的科学

- edith - Solidot
微软MVP Troy Hunt上月分析了索尼用户密码习惯,发现:用户使用的密码长度很短,多为6到10个字符;十分简单,不到1%的人使用非字母数字字符;可以预测,超过三分之一的密码是字典中的常见单词. 现在,他进一步研究了人们选择密码背后的依据.

“忘记密码”之后

- 非狐外传 - 互联网的那点事...
昨天把各大网站(Google、facebook、QQ、taobao、支付宝、百度、豆瓣、网易)找回密码的功能试用了一遍,大同小异,整体基本遵循如下流程:. 话术上Google使用的是“无法访问您的账户吗. ”,腾讯使用的是“找回密码”,其他均为“忘记密码. 个人认为Google的说法更为准确,QQ的“找回密码”操作其实是“重设密码”的过程,并非找回原来的密码.

密码管理规范

- cong - shell&#39;s home
    下面是贝壳自己总结的密码管理规范,大家可以参考一下. 网络密码通常很难暴力攻击,尝试速度受到网络限制,而且尝试一定次数后还可能被管理员发现. 而本地密码则相对比较容易攻击,我假定本地密码攻击可以达到每秒测试2^30个密码. 密码长度推定使用如下计算方式. 使用年数乘以攻击频率,得出攻击者在密钥使用期限内能尝试的最大次数.

有生命的密码

- Adam - Solidot
研究人员发明了一种新型密码,利用细菌传递机密信息,这种细菌会在特定条件下发光. 除了用于间谍活动外,这项技术可以让企业给农作物、种子,或其它有生命的物品编码秘密的身份信息. 美国国防部高级研究计划署(DARPA)几年前邀请研究人员提出不需要电的秘密信息编码的方法. 麻省塔夫斯大学的化学家David Walt和同事考虑使用细菌.

登录密码与HTTP Request

- - 博客园_首页
我们知道,在一些主流的浏览器中按F12,就会拉出一个查看web访问详细信息的窗口,在firefox中叫firebug,在chrome或者IE中,则叫developer tools,他们功能都大同小异,当然,比较重要的自然是查看http request与response, 幸运的是,这三个工具都把其放在一个叫Network的tab下面,虽然显示格式略有不同,但基本信息都是一样的.