0x1. 什么是WDCP

wdcp (WDlinux Control Panel) 是一套用PHP开发的Linux服务器管理系统,旨在易于使用和管理Linux服务器,通过web后台就可以管理服务器和虚拟主机。和国外的cPanel类似。虚拟主机的小能手。

2014年9月26,wdcp官网公布该漏洞,http://www.wdlinux.cn/bbs/thread-37476-1-1.html 而且可以看到最新版本是wdcp_v2.5.11(20140926)

该漏洞影响版本:wdcp_v2.5.11版本以下。

0x2. 漏洞分析

简单分析下wdcp这个漏洞。由于wdcp是经过编码加密的,所以得解密后分析代码。我简单写了一个解密wdcp整个文件的代码,用的时候只需修改下wdcp的目录。

wdcp_decode.php

<?php
/*
Authou: JoyChou
Date: 2014年12月7日14:50
*/
error_reporting(0);

function wdcp_decode($filename) {

    if (!file_exists($filename)) {
        return false; //文件名不存在
    }
        
    $data = unpack('C*', substr(file_get_contents($filename), 9));
    $key = array(0xB8, 0x35, 0x6, 0x2, 0x88, 0x1, 0x5B, 0x7, 0x44, 0x0);
    $j = count($data);
    foreach($data as $k => &$v) {
            $v = $key [ 2 * ($j % 5) ] ^ ~$v;
            // $v = sprintf('%u', $v);
            $v &= 0xFF;
            $v = pack('C*', $v);
            -- $j;
    }

    return gzuncompress(join('', $data));
}


function Traversal_Files($path = '.'){

    if (!is_dir($path)) {
        echo '参数不是目录';
        return false;
    }
    // //opendir()返回一个目录句柄,失败返回false
    if ($current_dir = opendir($path)) {
        while (false !== ($file = readdir($current_dir))) { // readdir获取当前目录的文件名喝目录名以及. ..
            $sub_dir = $path . DIRECTORY_SEPARATOR . $file;  // DIRECTORY_SEPARATOR \或者/
            if ($file == '.' || $file == '..') {
                continue;
            }
            else if (is_dir($sub_dir)) {
                echo "<h3> Directory Name  $file </h3>";
                Traversal_Files($sub_dir); //如果是目录,进行递归判断。
            }
            else{
                 $file_ext = substr($file, strrpos($file,".")+1);

                 if ($file_ext == 'php' || $file_ext == 'PHP') {
                    //echo $sub_dir . '<br>';
                    file_put_contents($sub_dir . '_decode', wdcp_decode($sub_dir));
                    unlink($sub_dir); 
                    rename($sub_dir . '_decode', $sub_dir);
                 }
            }
        }
    }

    closedir($current_dir); 
}


// 在这修改wdcp目录即可
Traversal_Files("D:\web\cms\wdcp\wdcp_v2.5.11\www\wdlinux\wdcp");


?>

在网上下了一个wdcp_v2.5.7版本,解码后分析add_user.php

require_once "../inc/common.inc.php";
if (isset($_POST['Submit_add'])) {
    $user=chop($_POST['user']);
    $password=chop($_POST['password']);
    $dbname=chop($_POST['dbname']);
    check_user($user);
    check_string($password);
    check_string($dbname);
    create_db_user($user,$password,$host);
    grant_db_user($user,$host,$dbname);
    mysql_add_user($user,$password,$host,$dbname,$rtime);
    optlog($wdcdn_uid,"增加mysql数据库 $user",0,0);
    str_go_url("数据库用户增加成功!",0);
}

毫无违和感,很粗暴的直接在数据库里增加用户,require的../inc/common.inc.php也没有做任何的登录限制。如果$_POST[‘dbname’]为空,默认的数据库是information_schema,当然要利用就得指定我们想要的数据库,一般是mySQL数据库。而且在mySQL目录下还有一个user_add.php,代码如下,和add_user.php最大的区别是它包含了login.php进行了登录验证。你肯定会猜不透为什么有了user_add.php还需要add_user.php。恩,我也猜不透。

user_add.php 关键代码

require_once "../inc/common.inc.php";
require_once "../login.php";
//require_once "../inc/admlogin.php";
//if ($wdcp_gid!=1) exit;


if (isset($_POST['Submit_add'])) {
    $user=chop($_POST['user']);
    $sid=intval($_POST['sid']);
    $password=chop($_POST['password']);
    $dbname=chop($_POST['dbname']);
    $host=chop($_POST['host']);
    if ($dbname=="0") go_back("选择的数据库有错!");
    check_user($user);
    //system_name_check($user,0);
    //check_string($password);
    check_passwd($password);
    check_string($dbname);
    system_name_check($user,0);
    //check_exists_dbname($dbname);
    //system_name_check($dbname,1);
    create_db_user($user,$password,$host);
    grant_db_user($user,$host,$dbname);
    mysql_add_user($user,$password,$host,$dbname,$rtime);
    optlog($wdcp_uid,"增加mysql数据库用户 $user",0,0);
    str_go_url("数据库用户增加成功!",0);

0x3. 漏洞利用

该漏洞好无脑,跳广场舞的大妈都会搞站了。

测试环境:

  • 版本: wdcp_v2.5.10,最新 wdcp_v2.5.11(20140926)

漏洞url:http://www.hackme.com:8080/mysql/add_user.php,可以看到用户名拿有一个6-15个字符,其实对长度的限制是大于3小于30. 由于要指定mysql数据库,所以用hackbar提交POST数据,提交的数据是Submit_add=xxoo&user=xxoo&password=xxoo&dbname=mysql

2

而且lanmp一键安装的站在wdcp同级目录会有phpmyadmin,所以用phpmyadmin登录,可以看到用刚新增的xxoo用户登录成功。
3

登录成功后,就可以看到mysql数据库user表里面的root密码,wdcp密码(都是mysql5加密)。
4

如果wdcp密码丢cmd5没解出来,root密码解出来,那用phpmyadmin登录root,拥有wdcp数据库的权限后,再解wdcp密码的md5。再拥有wdcp后台密码和mysql数据库root密码后,权限也是掉掉的。

一般拿到wdcp密码后,登录wdcp,在后台的“系统管理”==>“运行命令”,可以随意执行非useradd|userdel|usermod|passwd|rc\.d|init\.drm|dd|sudo以及/dev/|mkfs命令的命令。一般执行wget命令,下载远程恶意文件或者后门,chmod修改权限,运行自己的后门。这个命令修改的代码在/syc/cmd.php中。而且此时是root权限,有了root权限,在linux下面就可以任意操作了,达到任意命令执行。

5

0x4. 漏洞修复

  • 删除add_user.php(这个文件确实也没用),或者升级最新版v2.5.11
    在最新的wdcp_v2.5.11版本中,add_user.php内容解码只有9个字节,16进制是0A 20 20 20 20 20 20 20 20 T_T 想想也醉了,还不如删掉。
  • 或者添加include login.php,然后再编码回去。

相关链接

  1. http://tkxxd.net/thread-1843-1-1.html
  2. http://www.wdlinux.cn/bbs/thread-37476-1-1.html