For the past several months, VDOO’s security research teams have been undertaking broad-scale security research of leading IoT products, from the fields of safety and security. In most cases, the research was carried out together with the device vendors for the sake of efficiency and transparency.
As part of this research, VDOO researchers found zero-day vulnerabilities in devices of several vendors. These vulnerabilities were disclosed to the vendors, in accordance with responsible disclosure best practices, and will be shared gradually after the disclosure periods are concluded.
One of the vendors for which we found vulnerable devices was Hikvision. Our team discovered a vulnerability in Hikvision security cameras. Exploiting the discovered vulnerability, an adversary who successfully obtains the IP address of the camera can remotely execute code with root privileges on the camera (via LAN or internet). VDOO has responsibly disclosed this vulnerability (CVE-2018-6414) and engaged with Hikvision’s security team to solve the matter.
To the best of our knowledge, this vulnerability was not exploited in the field, and therefore, did not lead to any concrete privacy violation or security threat to Hikvision customers. The Hikvision team acted promptly to patch this vulnerability and to push the patched version to the vulnerable products.
The camera runs a Linux operating system. The davinci process includes many of the camera’s functionalities, including the web-server, and runs with user-id 0 privileges (the user id is named ‘admin’, but it effectively gives root privileges as the uid is 0). The camera’s web-interface is based on the Embedthis appweb 3 web server with some code added by Hikvision to it. The web server has some special pages to control the settings of the camera, that were added by Hikvision. Usually, these special pages run only after HTTP authentication passes, but a few of them do not require authentication.
In the code that takes care of a request to one of the pages that does not need HTTP authentication, there is a non-secure call to sscanf which can, when using a specially crafted request, lead to a buffer overflow, which in turn can corrupt memory and lead to arbitrary code execution or crash the process.
This vulnerability allows an adversary to execute a piece of code of their choice in the camera’s firmware.
When a user logs in using the login web page, a POST request is sent which can also contain GET parameters.
In the code parsing a specific GET parameter, there is a call to __isoc99_sscanf. The__isoc99_sscanf function behaves like the known scanf function, but instead of reading its input from stdin, it gets the input from a string. In this case, the input is the string holding the request’s query string:
The function’s format string is comprised of the parameter’s name, followed by “=%s”. This means the function expects the string to start with the parameter’s name followed by ‘=’, and then reads any string after that into a stack-based variable named “s1” in the figure above. This allows us to write as many bytes as we want to the stack, since there is no limit on the %s. The only limit that exists is the limit that the web-server applies to the whole URI, including the query string.
The web-server’s limit is applied first, before any of the logic behind the pages happens, as seen in the appweb 3 source code (as can be seen on github: https://github.com/embedthis/appweb-3/blob/master/src/http/request.c):
The value that the Hikvision camera assigns to maxUrl can be found by looking at the relevant functions:
When comparing the pseudo-code to the original code, it is easy to understand that “v3” stands for conn->http->limits, and that the value is in offset 48. When finding the function that initializes the values we will see that the value is set to 0x400 (which is different from the values that are found in the original appweb 3 source code):
When subtracting the length of the URI with the GET variables from 0x400, we get the limit of the payload that is possible to use in the variable’s value. We still need to subtract one more byte from this value, since the length of the URI is checked for equality too. Now, we can check what we can do with the available bytes.
Going back to the vulnerable function, we will observe the stack frame and check the offset of the “s1” variable in it. In this specific firmware, the variable is located at an offset close enough to the beginning of the stack, meaning we can overflow until the beginning of the stack frame. However, in some of the other firmware versions we checked, the variable was located at lower addresses on the stack and that wouldn’t allow us to reach all the way to the beginning of the stack frame. In such cases, the vulnerability may still be partially exploitable by overwriting variables that reside on the stack frame.
Since the return-address to the calling function is located at the beginning of the stack frame, by overwriting it, we can control which code will run next (when our function returns).
Since the attack is based on a %s sscanf format specifier, we can neither use any whitespaces in our attack nor NULL characters. This fact limits us, since all addresses in the code section start with a NULL byte. However, we used commonly known techniques to overcome this limitation.
An important thing that aids in exploiting this vulnerability is the fact that while ASLR is in use for the loaded shared libraries, it is not in use for the main binary of the firmware. Thus, it is possible to know exactly where the code resides, allowing us to jump to a code piece of our choice. We can also see that there is no use of stack canaries, meaning we can safely overwrite the stack’s contents without it ever being checked.
After having all that, we need to choose an address to jump to. As an example, similarly to the Foscam PoC, we chose to jump to a piece of code that resets the device’s credentials, allowing us to log into the device as an administrator. Then, as the device administrators, we are able to control any setting, including the ability to upgrade the device with custom firmware.
Given the risk this vulnerability poses, we decided not to publish a PoC in order to protect users who haven’t upgraded their devices from malicious attacks.
Recommendations for Device Makers
We would like to relate to some bad architectural practices that were found in the cameras analyzed in this research, that make it easier for an attacker to discover and exploit vulnerabilities. We encourage device makers to take the below recommendations into consideration.
- Usage of unsafe functions. sscanf is a potentially unsafe function, especially when used with %s or %. sscanf can be replaced by sscanf_s in a supporting API or can be used safely by adding length specifiers (which should be used carefully by making sure the specifier is smaller than the buffer length). The best practice is to not use any of the unsafe versions of the functions even if at a specific case it is safe, since using them regularly can lead to using them in an unsafe manner by mistake. Specifically, it is recommended not to use the sscanf at all. Other potentially unsafe functions found in the firmware include strcpy (can be replaced by strncpy), strcat (can be replaced by strncat), sprintf (can be replaced by snprintf) and more.
- Missing ASLR for main binary. ASLR is implemented and turned on already in the Linux OS running on the device, and the only change needed to be done is to make the main binary compatible with it by adding the “-pie -fPIE” flag to GCC. With this feature an attacker cannot guess the address of the functionality he wants to jump to.
- Missing stack canaries. This is a very simple and important security feature that can be turned on by adding the “-fstack-protector-all” flag to GCC. With this feature the executable will crash when it recognizes that the stack was compromised. That would lead to a short denial of service, but at least it won’t allow an attacker to run code of his choice. It is important to note that this feature can lead to performance degradation since a stack canary is checked for every function. If this performance degradation makes it impossible to use, it is possible to control the creation of stack canaries and set them to be put only on functions that have high potential to be vulnerable to stack-based buffer overflows. That can be done by using the “-fstack-protector” flag together with
- URL parameters should be sanitized to contain only ASCII printable characters. This, in combination with ASLR, would make it harder to exploit such vulnerabilities reliably.
- The firmware file is encrypted using a symmetric encryption. That allows an attacker to open the firmware for research.
- The firmware file is not digitally signed. This allows an attacker to repack a malicious firmware. Vendors should consider signing their firmware, to protect from this threat.
- In the firmware we researched there is use of appweb 3, specifically an old version of it – which has not been maintained for a long time. As stated on https://www.embedthis.com/appweb/download.html, this version, together with a few newer versions, is designated “end-of-life”, meaning that it will get no security patches.
- Almost all the logic of the device is contained in one binary. When everything is in one binary there is less privilege separation, and it increases the attack surface. For example, a possible denial of service vulnerability in any of the device’s functionalities will crash the main process, and with it – many of the device functionalities will suffer, instead of only crashing a process responsible for a specific logic. Separating the logic of the camera to different binaries could have also made it harder to exploit code execution vulnerabilities, as there was less available code in the process’ memory to jump to.
VDOO is a technology-driven company that strives to change the reality of unprotected connected devices. VDOO is building a line of products to support device manufacturers in embedding security into their connected devices at the development stage and enable post-development security.
In addition to developing products and services, VDOO invests significant efforts in a wide scope research of connected devices. Security cameras is one focus area of this research.
VDOO research goal is to contribute knowledge and tools to mitigate risks, as well as encourage the devices’ manufacturers to implement the right security for their products. We at VDOO believe that an appropriate implementation of the security essentials will dramatically decrease the chances of exploiting vulnerabilities on the device.
This is the third report from our series of researches focused on video surveillance equipment.
Ori Hollander, VDOO