资讯专栏INFORMATION COLUMN

齐博CMS HMAC+Cookie注入漏洞分析

DangoSky / 539人阅读

摘要:前言首先声明这不是,具体齐博版本就不说了,后面应该有人也发现这个漏洞并且发出来了。那时候对当时的齐博系列进行完整的分析和代码审计,漏洞不少,挑几个有意思的发出来。任意长度最终密文则为由于网络传输字符关系,齐博这里对进行了一次操作。

前言

首先声明这不是0day,具体齐博版本就不说了,后面应该有人也发现这个漏洞并且发出来了。

本文为笃行日常工作记录,文章是大概14年国庆节写的,一直未公开。那时候对当时的齐博系列进行完整的分析和代码审计,漏洞不少,挑几个有意思的发出来~。

一.HMAC简介

HMAC 是密钥相关的哈希运算消息认证码( Hash-based Message Authentication Code),HMAC 运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。

详细介绍自己google吧。

https://en.wikipedia.org/wiki...

二.齐博CMS HMAC解析

见文件inc/function.inc.php 中的mymd5 函数

/**
*加密与解密函数
**/
function mymd5($string, $action = "EN", $rand = ""){ //字符串加密和解密
         global  $webdb;
$secret_string = $webdb[mymd5].$rand."5*j,.^&;?.%#@!"; //绝密字符串,可以 任意设定
if  (!is_string($string)){
                $string  =  strval($string);
}
if ($string == = "") return "";
if ($action == "EN") $md5code = substr(md5($string), 8, 10); else{
$md5code = substr($string, -10);
$string = substr($string, 0, strlen($string) - 10);
}
//$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string);
$key = md5($md5code.$secret_string);
$string = ($action == "EN" ? $string : base64_decode($string)); $len = strlen($key);
$code = "";
for ($i = 0; $i < strlen($string); $i++){
                $k  =  $i%$len;
                $code  .  =  $string[$i]  ^  $key[$k];
}
$code = ($action == "DE" ? (substr(md5($code), 8, 10) == $md5code ? $code : NULL) : base64_encode($code)."$md5code");
       return  $code;
}

开发人员把加密和解密的算法都合起来在了一起。这里的交换密钥如下(附带 rand 随机变量),且系统安装时候也会随机产生参数$webdb[mymd5]data/config.php:

$secret_string    = $webdb[mymd5].$rand."5*j,.^&;?.%#@!"

结算构成的密文信息结构如下如下:

|任意长度密文|固定10字节hashcode|

总体加密过程概括如下:

Data = 原文
Key = $webdb[mymd5].$rand."5*j,.^&;?.%#@!"
HashKey = md5( Data + Key )
HashKey1 = substr( md5(Data),8,10 ) 固定 10 位的 hashcode,签名用。
EncryptData = HashKey^Data    任意长度
最终密文则为
EncryptData+hashcode
由于网络传输字符关系,齐博这里对 EncryptData 进行了一次 base64encode 操作。
实际得到的是 base64encode(EncryptData)+hashcode

总体解密过程如下:

Data = 密文
Key = $webdb[mymd5].$rand."5*j,.^&;?.%#@!"
DataReal = base64decode( substr( Data, 0, len(Data) – 8 )) 取出真正的密文,并且还原成二进制 HashKey = md5(DataReal + Key)
HashKey1 = substr(Data,-8 ) 固定 10 位的 HashKey1,取最后 10 位。
OriginalData = HashKey^ DataReal    还原密文,并不是逆向解密。
最终一步 HashKey1 校验 如果 md5(OriginalData) 等于 HashKey1 那么则认为这个消息是有效的那么最终明文为
OriginalData

整个交换的过程中对于用户来说密钥 Key 是不可见的,根据明文和密文是不可能直接还原出整个加密的算法,用户对计算出 10 位 HashKey1 的签名也是未知的,总体安全性比较高,要暴力破解枚举则要 16^10 次方的数量级。

三.齐博类 HMAC 算法爆破的可能性

经过分析,次算法可能存在一个极大的安全隐患就是计算EncryptData 引入的是 Data 的长度,在长度较短的时候可以进行暴力枚举。

$len = strlen($key);
$code = "";
for ($i = 0; $i < strlen($string); $i++){
         $k  =  $i%$len;
         $code  .  =  $string[$i]  ^  $key[$k];

如果我们构造原文Data = ‘ly’ 那么 HashKey1 则可以固定成 c6555942cb ,那么整个加密串应该是 EncryptDatac6555942cb 的形式。只要让算法满足 substr( md5(HashKey ^ Data),8,10) 等于 c6555942cb 即可。

又有:

Data = EncryptData^HashKey
EncryptData =HashKey ^ Data

我们的明文只有 2 位,那么能构造的 EncryptData 是 00~FF 规模为 16^2 数量相当可观,那么暴力枚举规模就转换成了 16^len(Data) 复杂度。

四.齐博前台认证 COOKIES 注入

齐博系统在COOKIE 中使用了 HMAC,COOKIE 产生和使用其实都是服务端做的工作,其实没有第一章所说的明显的客户端/服务端模式交换密钥,这里的场景是广义的 C/S模式,类似UC_Client/UC_Server,在业务逻辑上的C/S 模式并非物理的 C/S 模式。进入整理,看文件 admin/global.php

/*用户登录*/
if ($_POST[loginname] && $_POST[loginpwd]) {
//省略省略
login_logs($_POST[loginname], "成功登录,保密了"); $_COOKIE[Admin] = "$rs[uid]	".mymd5($rs[password]); setcookie("Admin", $_COOKIE[Admin], 0, "/");
}
if ($ForceEnter == 1){
$groupdb = @include(ROOT_PATH."data/group/3.php"); $Apower = ($groupdb[allowadmindb]);
}elseif(!$userdb){
         include  "./template/login.htm";
exit; }
else{
//同步前台登录
$md5code = mymd5("$lfjdb[uid]	$lfjdb[username]	$lfjdb[password]", "E N", $onlineip);
}
setcookie("adminID", $md5code, $timestamp + 1800, "/");
}

在验证登录的后,多次使用了 HMAC 算法对 cookie 进行加密典型的有 $_COOKIE[adminID]$_COOKIE[admin]

再看文件 inc/function.inc.php

//同步后台登录
if ($_COOKIE["adminID"] && $detail = mymd5($_COOKIE["adminID"], "DE", $onlin eip)){
unset($_uid, $_username, $_password);
list($_uid, $_username, $_password) = explode("	", $detail);
$lfjdb = $db->get_one("SELECT * FROM {$pre}memberdata WHERE uid="$
_uid" AND username="$_username""); }

由上文可知 $_COOKIE[adminID]的明文形式是

uid username password
三个参数由 tab 分割。

那么 list($_uid, $_username, $_password) = explode(" ", $detail); 之后就把结果保存到 $_uid , $_username$_password如果前后参数个数不同,那么 那个参数就会为空。

下面进行查库

$lfjdb = $db->get_one("SELECT * FROM {$pre}memberdata WHERE uid="$_uid" AND username="$_username"");

如果我们构造 uid = “1’#”那么查询语句实际就变成了 SELECT * FROM {$pre}memberdata WHERE uid=1满足条件,前台登录成功,前台登录认证就这一出。

由于 COOKIE 采用了密文交换,那么我们就不用关心 单引号被转移的问题,真是太棒了,当然这个 uid 一定要存在,一般创始人 uid 基本=1结合上文,我们只要构造出一个解密后的 COOKIE[adminID] = “1’#”即可。那么根据暴力分析一章,我们要构造的 EncryptData 长度为 3范围 000~fff总计 16^3=4096 规模,相当可观。

计算出 hashcode 为 cdb8c28d5d

ps:md5(1’#) =a425ef44cdb8c28d5d434b2a1343205e

那么我们只要枚举 base64_encode( 000~fff) + cdb8c28d5d。

最重要的一点我们发现在认证登录的时候传入了$onlineip 变量,可能导致 key 变动,不能暴力,看代码 inc/function.inc.php

if ($_SERVER["HTTP_CLIENT_IP"]){
$onlineip = $_SERVER["HTTP_CLIENT_IP"]; }elseif($_SERVER["HTTP_X_FORWARDED_FOR"]){
} else{
}
$onlineip = $_SERVER["HTTP_X_FORWARDED_FOR"];
$onlineip  =  $_SERVER["REMOTE_ADDR"];

那么我们直接构造固定的HTTP_X_FORWARDED_FOR 参数即可。
并且 http 请求提交登录认证页面,并根据返回值判断。

其实前台可以直接getshell不过不在我们讨论范围内。

最后 ending…如有不足请指点,亦可留言或联系 fobcrackgp@163.com.
本文为笃行原创文章首发于大题小作,永久链接:齐博CMS:HMAC+COOkie注入漏洞分析

https://www.ifobnn.com/qibocmshmac.html

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30648.html

相关文章

  • 齐博cms漏洞分析

    摘要:原理分析还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴漏洞发生在页面中。并且与此同时,齐博并未对进行过滤操作。漏洞利用这里还是以文件中的变量为例。 ** 0x01 原理分析 **还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴:https://security.alibaba.com/...漏洞发生在/inc/common.inc.php页面中。首先看这个函数:s...

    SHERlocked93 评论0 收藏0
  • 齐博cms漏洞分析

    摘要:原理分析还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴漏洞发生在页面中。并且与此同时,齐博并未对进行过滤操作。漏洞利用这里还是以文件中的变量为例。 ** 0x01 原理分析 **还是很早之前爆出来的漏洞,现在拿出来学习一下,参考阿里巴巴:https://security.alibaba.com/...漏洞发生在/inc/common.inc.php页面中。首先看这个函数:s...

    NoraXie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<