Hik or hack? (NOT) IoT Security Using Hikvision IP Cameras
In the modern world, we are surrounded by “smart” devices, in one form or another representing a small computer. From the point of view of integration with modern equipment, whether it is consumer electronics and smart homes, medical and banking equipment, entertainment systems and industrial equipment - all these are embedded systems ( embedded devices ).
Smart gadgets are very tightly integrated into our lives, and their number is growing from year to year due to their low cost, convenience and ease of use, including via the Internet . However, behind a number of pluses there are cons that are invisible at first glance to the average user.
In one of the reportsThe “face-to-face” NeoQUEST-2017 considered an extensive class of embedded devices - IP cameras, and discussed general approaches to the analysis of embedded software. In this article, we will dwell in more detail on the study of the Hikvision DS-2CD2432F-IW camera , its firmware and the protection mechanisms from embedding and modification used by the manufacturer.
We go to the web-interface and study the functionality: we find out the software version, activate network services (SSH, SNTP, FTP, ...). We got the camera with a rather old firmware 5.3.0. Naturally, from version to version, the vendor patches not only the device’s functionality, but also security problems. At the time of writing, the newest firmware for this camera has version 5.4.5.
To view live video from the camera, a browser plugin is required. One of the plugins is stored on the camera itself - download it, maybe it will come in handy for us.
We connect via SSH to the device and see the CLI with a certain set of commands with which you can find out the current camera settings, set your own and learn much more information about the device than through the web interface.
We check the commands and with the help of one of them we learn information about the OS, the OS kernel, processor architecture, file system, RAM sizes, physical memory partitions, etc.
An important skill for a researcher is the ability to search for information - after all, most likely someone has already done this before you. Answers to many questions can be found on thematic forums or simply in search engines. For example, we’ll go to a forum dedicated to various cameras, registrars, etc.
We’re a little surfing and find how to “fall through” even deeper, namely in the root-shell, where the commands “cut” in the CLI and the file system are available!
The very access to the root-shell will allow us to get lists of open ports and processes, extract executable files from the file system for examination, and launch our own files. You can import / export both using the SD card.
Even at the stage of getting to know the camera, the RS232 tab was seen in the web interface . The forum immediately showed the trade about how this interface can be used.
By connecting the UART to the camera and setting the necessary parameters for minicom , we get the opportunity to read the entire log of the camera’s download, stop the device’s boot and “fail” in the bootloader! We see that the log is quite large, and it displays the launched processes, passed checks (so far unknown to us), errors and other system information.
Boot itself and its commands are equally interesting, allowing you to read and write data to the device’s physical memory, update the camera via a tftp server (if you suddenly turned it into a "brick"), and get even more detailed information about the camera’s insides.
After a little study of the camera itself, we proceed to the study of the firmware image. Download the image, note that the firmware is an unknown file with the extension “.dav”. We are trying to see something in the hex editor.
As a rule, any firmware image most likely starts with a header that contains metadata about the image itself and about the supported device. From the previous figure, we see something similar to the title. Let's try to “feed” the binwalk firmware file . In the first ~ 130 thousand bytes nothing was found, and this suggests that, most likely, this block is encrypted.
We go to “smoke” the already mentioned forum and stumble upon it . It turns out that the header of the firmware file is really byte-by-byte encrypted. Block encryption is implemented based on the XOR operation. Operation key = "BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE". Before each subsequent xor, the key is cyclically shifted left by byte. We are writing a small script to decrypt the header. So far, as a result, we get, presumably, the names of some files and a set of unknown bytes.
Let's try to compare the available information (size and version of the image, binwalk`a log, etc.) with unknown data in the header. For example, you can see the size of the image or the offset of the .gz archive that binwalk also detected. In order of bytes, we can conclude that this is little-endian.
Recall the browser plug-in, which we downloaded at the dating stage. Its name appears in the title. Immediately after its displacement, we see its size in the image.
It is already known that the structure associated with files contains the file name (32 bytes), its offset (4 bytes) and size (4 bytes). 4 more bytes of information remain unknown until the next structure. This is most likely a checksum. It remains to find out by what algorithm it is calculated. Since the length is only 4 bytes, we can safely say that this is not the result of some popular hash function (MD5 (), SHA * ()). It can be assumed that CRC32 () is used. We try - by, the amounts do not converge.
After several assumptions, a curious dependence was noticed: the larger the file size, the larger its checksum. This prompted the idea to add sequentially bytes in one of the files. Indeed, the checksum calculation algorithm is quite simple and is a sequential addition of bytes. The header checksum is calculated in the same way - it is located at the very beginning, next to its size.
The decrypted header contains information:
A detailed heading structure is presented below:
Now that the header structure is completely known, it is not difficult to write a script that parses the header and decompresses the image into separate files (links to the sources of programs that unpack the original firmware image and build a new image - at the end of the article!). And here we will carefully study them!
We examine the files that are part of the image. It becomes clear from the name about the appointment of some, but for now it remains only to guess ... A file with the extension “.img” immediately catches your eye, most likely it is an image of the file system. Mount it right away. “Feed” binwalk and see the “.gz” archive, but only with 64 bytes, which means the image has its own header.
As a rule, the header of the image of the file system contains the checksum of the image, its size and the load address in the RAM of the device. In our case, the CRC32 checksum (). Also added "magic bytes" KDMR (RMDK, ramdisk magic). The remaining header bytes are filled with zeros.
Already by name, we can assume that the script is launched when the device is turned on. Having studied it, we understand that it creates the necessary directories, unpacks archives, copies files, starts binary files, removes unnecessary ones, loads kernel modules, mounts the necessary partitions, creates symbolic links - all this happens in RAM.
It would seem that lib_so.tar.gz - an archive with dynamic libraries is not noticeable, but inside the archive among the libraries the executable binary file daemon_fsp_app was lost. It is strange that it was placed in this archive, although the rest of the binaries were simply concatenated with the rest of the files in the image. Well, have to revert it!
It turned out that this binary file decrypts, starts and deletes, leaving it hanging in the processes, one of the files in the firmware, namely, davinci.tar.gz. This is the most interesting file - the encrypted executable file davinci, which implements the basic logic of the device. It “manages” the web server and checks the imported image of the new firmware.
The checksums of files, their offsets and sizes, the number of files in the firmware, the size of the image and its version, the class of the compatible device, the checksum and size of the header, the header of the file system image and, of course, “magic bytes” are checked. It is not so difficult to get around these checks if you analyze the structure of each file. This will allow you to modify the image or build your own.
The manufacturer disguised davinci as a compressed tar.gz archive, but in fact there is a completely different nested doll (see the figure below)! The binary file is packed into a tar archive, compressed using the lzma algorithm and encrypted using the AES symmetric block encryption algorithm: block size - 128 bits, key size - 256 bits, encryption mode - ECB, and also added a header with "magic bytes", which and checked during decryption.
The encryption key is generated using the EVP_BytesToKey () key generation function , where MD5 () is used in two passes, the passphrase is “R0sslV53cryptor0” and the salt is “HangZhou”. For different classes and series of devices, this key will be different, the series of the camera we are examining is R0.
The file is encrypted in the same way as the davinci binary file, but it differs only in the encryption key and in that decryption is already done by davinci itself. The key is different due to the fact that another passphrase is used to generate it - “h @ k8807H $ Z5998”. It can be found “inside” the davinci binary file, in the same place as the HangZhou salt.
According to the structure of the decrypted file shown in the figure below, we can say that this is the second image header - it also contains metadata, the file name, its offset, size and checksum. The main difference is the checksum calculation algorithm - here is the usual SHA () (not to be confused with SHA1 () and other SHA () algorithms), and the encryption algorithm of the file itself. This file, like the header, is checked by davinci.
The remaining files in the image are not as interesting as the above. Their brief description is presented in the table below.
What can I say? Most embedded devices are manufactured in China, and manufacturers are trying to save on the work of programmers and hardware, as a result of which this hardware has extremely limited computing resources. As a result, poorly implemented security mechanisms to prevent modification of the original software (or even their complete absence).
Moreover, the manufacturer can independently lay backdoors . And if hacking a smart kettle is unlikely to cause significant damage (although this can be argued based on the assertion that a potentially smart kettle can even “put” the Pentagon’s site ), then an attack on more significant embedded systems can entail serious effects.
The lack of automatic updates for most devices completely undermines their safety - an ordinary person does not follow the news in the field of information security until it affects him personally or until everyone speaks about it. It is unlikely that a housewife will get in to download a new firmware for her camera from a Chinese site.
Devices may not be updated for years. As a result of this, attackers exploit an accessible loophole in their personal interests, starting from banal surveillance of the “victim” and ending with the creation of botnets .
One can only hope that in the future manufacturers will be more responsible for the safety of their products, which are increasingly being poured into our lives, introducing modern and reliable mechanisms for protecting them from modification and substitution of software, for example, electronic digital signatures .
During the study, programs were written to unpack the original firmware image and build a new image in Python. The unpacker divides the image into separate files included in its composition. The assembly takes into account those fields that are checked when downloading to the device, which allows you to modify any of the files in the image (without adding a new file to the image) and assemble a new firmware file. Assembly requires an unpacked image.
Smart gadgets are very tightly integrated into our lives, and their number is growing from year to year due to their low cost, convenience and ease of use, including via the Internet . However, behind a number of pluses there are cons that are invisible at first glance to the average user.
In one of the reportsThe “face-to-face” NeoQUEST-2017 considered an extensive class of embedded devices - IP cameras, and discussed general approaches to the analysis of embedded software. In this article, we will dwell in more detail on the study of the Hikvision DS-2CD2432F-IW camera , its firmware and the protection mechanisms from embedding and modification used by the manufacturer.
Acquaintance
We go to the web-interface and study the functionality: we find out the software version, activate network services (SSH, SNTP, FTP, ...). We got the camera with a rather old firmware 5.3.0. Naturally, from version to version, the vendor patches not only the device’s functionality, but also security problems. At the time of writing, the newest firmware for this camera has version 5.4.5.
To view live video from the camera, a browser plugin is required. One of the plugins is stored on the camera itself - download it, maybe it will come in handy for us.
We connect via SSH to the device and see the CLI with a certain set of commands with which you can find out the current camera settings, set your own and learn much more information about the device than through the web interface.
We check the commands and with the help of one of them we learn information about the OS, the OS kernel, processor architecture, file system, RAM sizes, physical memory partitions, etc.
Search for information
An important skill for a researcher is the ability to search for information - after all, most likely someone has already done this before you. Answers to many questions can be found on thematic forums or simply in search engines. For example, we’ll go to a forum dedicated to various cameras, registrars, etc.
We’re a little surfing and find how to “fall through” even deeper, namely in the root-shell, where the commands “cut” in the CLI and the file system are available!
The very access to the root-shell will allow us to get lists of open ports and processes, extract executable files from the file system for examination, and launch our own files. You can import / export both using the SD card.
Even at the stage of getting to know the camera, the RS232 tab was seen in the web interface . The forum immediately showed the trade about how this interface can be used.
By connecting the UART to the camera and setting the necessary parameters for minicom , we get the opportunity to read the entire log of the camera’s download, stop the device’s boot and “fail” in the bootloader! We see that the log is quite large, and it displays the launched processes, passed checks (so far unknown to us), errors and other system information.
Boot itself and its commands are equally interesting, allowing you to read and write data to the device’s physical memory, update the camera via a tftp server (if you suddenly turned it into a "brick"), and get even more detailed information about the camera’s insides.
Firmware structure
Header
After a little study of the camera itself, we proceed to the study of the firmware image. Download the image, note that the firmware is an unknown file with the extension “.dav”. We are trying to see something in the hex editor.
As a rule, any firmware image most likely starts with a header that contains metadata about the image itself and about the supported device. From the previous figure, we see something similar to the title. Let's try to “feed” the binwalk firmware file . In the first ~ 130 thousand bytes nothing was found, and this suggests that, most likely, this block is encrypted.
We go to “smoke” the already mentioned forum and stumble upon it . It turns out that the header of the firmware file is really byte-by-byte encrypted. Block encryption is implemented based on the XOR operation. Operation key = "BA CD BC FE D6 CA DD D3 BA B9 A3 AB BF CB B5 BE". Before each subsequent xor, the key is cyclically shifted left by byte. We are writing a small script to decrypt the header. So far, as a result, we get, presumably, the names of some files and a set of unknown bytes.
Let's try to compare the available information (size and version of the image, binwalk`a log, etc.) with unknown data in the header. For example, you can see the size of the image or the offset of the .gz archive that binwalk also detected. In order of bytes, we can conclude that this is little-endian.
Recall the browser plug-in, which we downloaded at the dating stage. Its name appears in the title. Immediately after its displacement, we see its size in the image.
It is already known that the structure associated with files contains the file name (32 bytes), its offset (4 bytes) and size (4 bytes). 4 more bytes of information remain unknown until the next structure. This is most likely a checksum. It remains to find out by what algorithm it is calculated. Since the length is only 4 bytes, we can safely say that this is not the result of some popular hash function (MD5 (), SHA * ()). It can be assumed that CRC32 () is used. We try - by, the amounts do not converge.
After several assumptions, a curious dependence was noticed: the larger the file size, the larger its checksum. This prompted the idea to add sequentially bytes in one of the files. Indeed, the checksum calculation algorithm is quite simple and is a sequential addition of bytes. The header checksum is calculated in the same way - it is located at the very beginning, next to its size.
The decrypted header contains information:
- about the image itself: about its version, assembly, size;
- about the device;
- about files in the firmware: name, offset, size and checksum.
A detailed heading structure is presented below:
Now that the header structure is completely known, it is not difficult to write a script that parses the header and decompresses the image into separate files (links to the sources of programs that unpack the original firmware image and build a new image - at the end of the article!). And here we will carefully study them!
hroot.img
We examine the files that are part of the image. It becomes clear from the name about the appointment of some, but for now it remains only to guess ... A file with the extension “.img” immediately catches your eye, most likely it is an image of the file system. Mount it right away. “Feed” binwalk and see the “.gz” archive, but only with 64 bytes, which means the image has its own header.
As a rule, the header of the image of the file system contains the checksum of the image, its size and the load address in the RAM of the device. In our case, the CRC32 checksum (). Also added "magic bytes" KDMR (RMDK, ramdisk magic). The remaining header bytes are filled with zeros.
initrun.sh
Already by name, we can assume that the script is launched when the device is turned on. Having studied it, we understand that it creates the necessary directories, unpacks archives, copies files, starts binary files, removes unnecessary ones, loads kernel modules, mounts the necessary partitions, creates symbolic links - all this happens in RAM.
davinci.tar.gz
It would seem that lib_so.tar.gz - an archive with dynamic libraries is not noticeable, but inside the archive among the libraries the executable binary file daemon_fsp_app was lost. It is strange that it was placed in this archive, although the rest of the binaries were simply concatenated with the rest of the files in the image. Well, have to revert it!
It turned out that this binary file decrypts, starts and deletes, leaving it hanging in the processes, one of the files in the firmware, namely, davinci.tar.gz. This is the most interesting file - the encrypted executable file davinci, which implements the basic logic of the device. It “manages” the web server and checks the imported image of the new firmware.
The checksums of files, their offsets and sizes, the number of files in the firmware, the size of the image and its version, the class of the compatible device, the checksum and size of the header, the header of the file system image and, of course, “magic bytes” are checked. It is not so difficult to get around these checks if you analyze the structure of each file. This will allow you to modify the image or build your own.
The manufacturer disguised davinci as a compressed tar.gz archive, but in fact there is a completely different nested doll (see the figure below)! The binary file is packed into a tar archive, compressed using the lzma algorithm and encrypted using the AES symmetric block encryption algorithm: block size - 128 bits, key size - 256 bits, encryption mode - ECB, and also added a header with "magic bytes", which and checked during decryption.
The encryption key is generated using the EVP_BytesToKey () key generation function , where MD5 () is used in two passes, the passphrase is “R0sslV53cryptor0” and the salt is “HangZhou”. For different classes and series of devices, this key will be different, the series of the camera we are examining is R0.
_cfgUpgSecPls
The file is encrypted in the same way as the davinci binary file, but it differs only in the encryption key and in that decryption is already done by davinci itself. The key is different due to the fact that another passphrase is used to generate it - “h @ k8807H $ Z5998”. It can be found “inside” the davinci binary file, in the same place as the HangZhou salt.
According to the structure of the decrypted file shown in the figure below, we can say that this is the second image header - it also contains metadata, the file name, its offset, size and checksum. The main difference is the checksum calculation algorithm - here is the usual SHA () (not to be confused with SHA1 () and other SHA () algorithms), and the encryption algorithm of the file itself. This file, like the header, is checked by davinci.
The remaining files in the image are not as interesting as the above. Their brief description is presented in the table below.
Description of files in the image
To summarize the sad results ...
What can I say? Most embedded devices are manufactured in China, and manufacturers are trying to save on the work of programmers and hardware, as a result of which this hardware has extremely limited computing resources. As a result, poorly implemented security mechanisms to prevent modification of the original software (or even their complete absence).
Moreover, the manufacturer can independently lay backdoors . And if hacking a smart kettle is unlikely to cause significant damage (although this can be argued based on the assertion that a potentially smart kettle can even “put” the Pentagon’s site ), then an attack on more significant embedded systems can entail serious effects.
The lack of automatic updates for most devices completely undermines their safety - an ordinary person does not follow the news in the field of information security until it affects him personally or until everyone speaks about it. It is unlikely that a housewife will get in to download a new firmware for her camera from a Chinese site.
Devices may not be updated for years. As a result of this, attackers exploit an accessible loophole in their personal interests, starting from banal surveillance of the “victim” and ending with the creation of botnets .
One can only hope that in the future manufacturers will be more responsible for the safety of their products, which are increasingly being poured into our lives, introducing modern and reliable mechanisms for protecting them from modification and substitution of software, for example, electronic digital signatures .
PS
During the study, programs were written to unpack the original firmware image and build a new image in Python. The unpacker divides the image into separate files included in its composition. The assembly takes into account those fields that are checked when downloading to the device, which allows you to modify any of the files in the image (without adding a new file to the image) and assemble a new firmware file. Assembly requires an unpacked image.