our researchers discovered a new and massive IoT Botnet, ‘IoTroop’. Due to the urgency of this discovery, we quickly published our initial findings in order to alert the cyber security community. Since then, we have had time to digest and dissect the propagating malware and share our findings with you.
The main findings are:
• The entire attack infrastructure has been uncovered.
• We have observed 2 sets of different infrastructures:
o The main set of servers and samples focused on infection and propagation.
o A smaller and different set used for 2nd stage payloads.
• The attackers have quick and flexible control of infected device via LUA scripting.
• The malware authors and operators are operating out of China.
Throughout the research, we found numerous indications that the authors and operators of this IoT Botnet are operating out of China. Of course, all these indications can be forged. However the sheer volume of evidence as well as locations, still leads us to conclude that these indications are true to a very high degree of probability.
We can also reveal that part of the C&C infrastructure was previously registered under the email ‘email@example.com’. This same email address was also used to register domains belonging to a Chinese APT Group dubbed ‘The Black Vine’. This is not strong enough to attribute this new botnet to the same group; however it does provide leads for future research.
The Main Infrastructure
Based on a system multiple different servers, each with its own role to play in the reconnaissance, exploitation and delivery of the malware payload, the entire botnet propagation infrastructure has been uncovered. The diagram below illustrates an in-depth view of the requests made and the functions of each server.
Diagram of Malware Propagation Infrastructure
IoTroop Malware Overview
The IoTroop malware is the main sample used in the campaign and is deployed as a first stage payload. It shares an extensive code base with the leaked Mirai source code which can be found in several online resources. The main differences we observed are:
- The C&C server has been completely redesigned to operate with a new backend. Additionally IoTroop’s C&C server is written in PHP while the original Mirai C&C server was written in GO.
- With the change of the C&C backend, the C&C communication protocol was changed as well. The entire C&C communication functionality found within IoTroop’s samples is brand new and unique to the IoTroop malware.
- A vulnerability scanning functionality has replaced the original brute forcing password functionality as presented by Mirai. This functionality has probably been added to enable the infection of a larger number of devices using fewer resources, while reducing the malware detection rates.
- The IoTroop malware does not contain any of the original Mirai DDoS functionalities; in fact it does not contain any DDoS functionality at all. While we haven’t seen any actual DDoS attacks, all DDoS related actions are being orchestrated and managed by the C&C backend and is downloaded as separate modules.
Malware Operation Details
We have detected several variants of samples used by the IoTroop malware containing very slight differences but containing the exact same functionality. Generally, all variants can be divided into two major categories correlating with the attacked device’s architecture – MIPS variants and ARM variants.
Once IoTroop executes its payload onto an infected device, the initial steps of operation are equivalent to those taken by Mirai. These include:
- Obfuscated string initialization
- Preventing reboot by the system`s watchdog service (By sending a specific IOCTL)
- Ensurse only a single instance of IoTroops is currently running
- Hide argv
- Hide process’s name
However, from this point of the control flow the IoTroop malware begins to execute its own unique functionality:
The device`s MAC address is retrieved and stored by sending IOCTL 0x8927 to the eth0, br0, eth1 and eth2 devices.
If the device the malware is currently running on runs the GoAhead embedded web server, the following shell command lines are executed:
- rm -f /tmp/ftpupload.sh \n
- ln -s /dev/null /tmp/ftpupload.sh \n
- rm -r /var/log \nThese actions are used to delete a previous shell script used by the WIFICAM exploit and to create a symbolic link to /dev/null, thus preventing any further attempts of using it, as well as clearing all log files to clear its evidence from the device.
Disabling Competitor Malware
IoTroop kills any open telnet processes open using port TCP/23.
It then continues to scan the device’s memory for the existing strings that are used by other IoT malware. If any of these strings are found, the process containing them is killed.
- REPORT %s:%s
- \x58\x4D\x4E\x4E\x43\x50\x46\x22 (The word ‘zollard’ Xored with 0x22)
Random IP’s are generated for the purpose of vulnerability scanning. The code responsible for generating the IP address is identical to Mirai’s code and is used to generate IP addresses with the following excluded subnet.
The malware conducts a set of vulnerability tests on each of the generated IP addresses. These tests locate vulnerabilities in any of the following devices and/or infrastructure:
The specific vulnerability scan traffic is the following:
|GET /cgi-bin/user/Config.cgi?.cab&action=get&category=AccountHost: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|GET /shell?echo+jaws+123456;cat+/proc/cpuinfo HTTP/1.1Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|JAWS Web Server
|“GET /upgrade_handle.php?cmd=writeuploaddir&uploaddir=%%27;echHost: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|GET /board.cgi?cmd=cat%%20/etc/passwd HTTP/1.1Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|GET /system.ini?loginuse&loginpas HTTP/1.1Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|POST /command.php HTTP/1.1Host: %d.%d.%d.%d
|GET /setup.cgi?next_file=netgear.cfg&todo=syscmd&curpath=/¤tsetting.htm=1&cmd=echo+dgn+123456 HTTP/1.1
Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|POST /apply.cgi HTTP/1.1Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
|POST /hedwig.cgi HTTP/1.1Host: %d.%d.%d.%d (Host: %d.%d.%d.%d:%d)
<?xml version=’1.0′ encoding=’UTF-8′?><postxml><module><servi
This is a sample of a PCAP taken from one of the vulnerability scans:
IoTroop’s C&C backend is composed of several components, each responsible for a unique purpose.
The reporting sever is used to collect a list of all devices who were found to be vulnerable by any of the infected devices.
Reporting servers are prefixed with the ‘f’ subdomain name. We were able to identify two active reporting servers at the time of our research:
- hl852.com (188.8.131.52)
- ha859.com (184.108.40.206)
Once a device has been found to be vulnerable, IoTroop sends its data to the reporting server in the following manner:
The following arguments are being used as part of this HTTP GET request:
The controller servers are used to control all infected devices, and are responsible for executing all second stage malicious payloads and updating the current malware.
Each of the infected devices constantly pulls for available commands from the controlling C&C server. At the time of the research we were able to identify two active control servers:
- ha859.com (220.127.116.11)
- hl852.com (18.104.22.168)The commands and arguments issued from the controller to the IoTroop client are sent in a JSON format. The retrieved data may be comprised of the following key-value tuples:
Once a command is received, it is parsed to locate either one of these values, namely looking for “code” as the action to conduct and the rest as arguments to supplement
it. As mentioned above, this can result in two execution paths – a plain download, or a download followed by execution. These are outlined next:
if a port exists and is equal to 80, than a string of the format “http://<ip><url_path>” is constructed, otherwise it sets it to be “http://<ip>:<port><url_path>”, using the values of “ip”, “port” and “path” as the data to place in the string.
If the name JSON value is a full path then the file will be downloaded and saved under this name. Otherwise it will be placed under the /tmp directory.
Before handling the constructed URL, the bot will attempt to kill all similar processes by name, issuing the command “killall <name>”, where the argument is taken from the aforementioned “name” key. Finally, the URL will be passed to a download function.
The download function will first check the status of the file using lstat to verify that it exists and is valid for subsequent reading action, following which the MD5 hash function will be applied on its contents.
Upon opening the file and reading it, a supposed reporting or logging string of the format “open:error\success” or “read:error\success” will be constructed depending on the status of each of the actions accordingly, however this string is never used, suggesting that the malware is still undergoing adjustments and is in a development phase.
The retrieved hash will be compared against one that is provided by the controller in the “md5” key, so as to verify that the version of the file on disk (if such indeed exists) differs from the one provided by the server.
If indeed the file versions differ, a new file will be generated with the permission “r-xrwxrwx” and a socket will be established to the destination server (containing the required file).
IoTroop will construct an HTTP GET request and write it to the socket, after which it will try to read its contents in chunks of 128 bytes (in the event the request succeeded). These will be written to the newly created file, and checked one more time against the MD5, provide by the controllers, to verify that the contents were retrieved properly.
To finalize communication, the bot will issue the string “FIN\n” to the controller.
The execution of the file will always follow a download. In such case, there are several options, depending on the value of the “runtype” and “runport” keys.
The former is checked for the existence of the “mysel” substring, which will cause the execution of the downloaded file with the same arguments as the current process. These will usually have the second argument set to be a device model, and the third argument as a TCP port. This kind of behavior may correspond to an event of software update to the bot, suggesting the possibility of it evolving further in the future.
In any other case, either the downloaded file is executed with the given “runtype” and “runport” as arguments, or only with “runtype”.
The latter scenario would correspond to an execution of an arbitrary module or plugin, which could well be the Slowloris DDoS utility (found on the build server), or any other application of the like. Either way, in order to spawn the new process, the command “/bin/sh sh -c <path_to_executable> <runtype> <runport>” will be used.
Throughout our research we found the following samples being used by the IoTroop malware at different stages of its control flow.
||Small backdoor that listens on TCP 8888 for raw shell commands, and executes them on the infected device.
||Mirai botnet, with default config. Seems to be used for debugging
||core of botnet, recruits new bots through vulnerability enumeration
||core of botnet, recruits new bots through vulnerability enumeration
||basic C implementation of a telnet client & serverhttps://github.com/qixiaohu/mini_telnet
||IoTroop malware dropper, downloads and executes the IoTroop sample (sa).
2nd Stage Payloads
We have noticed another set of related samples and C&C servers, also mentioned in a post from Qihoo 360, seemingly used for second stage payload.
These samples can be downloaded and executed by the IoTroop malware from the Download server. The samples are described in the following table:
These samples communicate with a different set of C&C servers to report infection and download commands. These servers are hard coded inside the samples in the form of domain / IP address sometimes with different ports, depending on the exact sample.
Lua-Integrated Malware AnalysisAccording to data collected from one of the reporting servers, there were around 4700 unique device infections reported to this server, mostly from IP addresses in South Korea.
These samples are compiled statically with the Lua interpreter, and the LuaSocket library., integrating Lua execution support with flexible network functionality. Additionally it contains code from the Mirai source, compiled in Debug mode, which is evident due to the existence of debug strings in the code. However, the Mirai code doesn’t seem to be utilized by the sample we analyzed, with the exception of one debug sub-string referenced by the code, and this is probably due to compiler optimization.
The existence of multiple debug strings, verbose outputs and the general state of the infrastructure, leads us to believe that these samples are still in testing or initial deployment phase. It is also evident the developers have an understanding of Lua’s interpreter internals, due to their usage of the interpreter’s internal functions.
The core part of the sample’s main function can be seen below:
The malware uses Lua interpreter’s internal functions to initialize the Lua engine, load the LuaSocket libraries and define some custom Lua global variables, some of which the attackers later reference in their Lua code.
Afterwards a function is pushed to the Lua engine stack and then defined as “attack”. This is equivalent to defining a function called “attack” in a LUA script. This string “attack” is taken as a substring from a debug string from the Mirai source code (this is probably an amusing artifact due to compiler optimization):
The malware then utilizes internal Lua functions in order to execute the following Lua script, which is embedded as a string inside the malware:
This script communicates with the hard coded C&C addresses of the malware and is actually the main payload. It starts by reporting the infection details to the reporting C&C (bbk80.com) using the global variables previously defined.
It then enters an infinite loop where it downloads Lua scripts from the command C&C (cbk99.com) and executes them. It works by downloading the “run.lua” file (a Lua script) from the C&C and passing it as an argument to the “attack” function that was previously defined in main. The “attack” function serves as a custom “eval” function, executing the script in a forked child process:
The malware will print an error string in Chinese if loading and/or execution of the script fails for some reason:
Currently the existing “run.lua” script on the C&C server simply prints the string “Just Test”:
We can see another Lua script left on the webserver named “run.bak.txt”, which looks like a data collection / update script. An excerpt is shown below:
The attackers can easily update the script and easily instruct the botnet to perform any task. This powerful setup gives the attackers flexible and dynamic control of infected devices, allowing them to easily target anything with custom, updateable attack code, and alter the malware’s behavior without updating the binary itself.