{
	"id": "405f54ff-1a60-4f56-a8ed-7a502e0445fc",
	"created_at": "2026-04-06T00:18:24.788164Z",
	"updated_at": "2026-04-12T02:21:23.732737Z",
	"deleted_at": null,
	"sha1_hash": "c26d185f6f59a5662b598ac56f381c0f478c1668",
	"title": "MMD-0064-2019 - Linux/AirDropBot",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3500210,
	"plain_text": "MMD-0064-2019 - Linux/AirDropBot\r\nPublished: 2019-09-28 · Archived: 2026-04-05 16:00:08 UTC\r\nPrologue\r\nThere are a lot of botnet aiming multiple architecture of Linux basis internet of thing, and this story is just one of\r\nthem, but I haven't seen the one was coded like this before.\r\nLike the most of other posts of our analysis reports in MalwareMustDie blog, this post has been started from a\r\nfriend's request to take a look at a certain Linux executable malicious binary that was having a low (or no)\r\ndetection, and at that time the binary hasn't been categorized into a correct threat ID.\r\nThis time I decided to write the report along with my style on how to reverse engineering this sample, which is\r\ncompiled in the MIPS processor architecture.\r\nSo I was sent with this MIPS 32bit binary ..\r\n1\r\n2\r\ncloudbot-mips: ELF 32-bit MSB executable, MIPS, MIPS-I\r\nversion 1 (SYSV), statically linked, stripped\r\n..and according to its detection report in the Virus Total hash it is supposed to be a \"Mirai-like\" or Mirai variant\r\nmalware, (thank's to good people for uploading the sample to VirusTotal). But the fact after my analysis is saying\r\ndifferently, these are not Mirai, Remaiten, GafGyt (Qbot/Torlus base), Hajime, Luabots, nor China series DDoS\r\nbinaries or Kaiten (or STD like). It is a newly coded Linux malware picking up several idea and codes from other\r\nknown malware, including Mirai.\r\nThis sample is just one of a series of badness, my honeypots, OSINT and a given information was leading me into\r\n26 types of samples that are meant to pwned series of internet of thing (IoT) devices running on Linux OS, and\r\nthis MIPS-32 ELF binary one I received is just one of the flocks.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 1 of 32\n\nIf you see the filenames you can guess some of those binaries are meant to aim specific IoT/router platforms and\r\nnot only for several randomly cross-compiled architecture supported result. This type of binaries seem to be\r\nstarted appearing in the early August, 2019, in the internet.\r\nBelow is the additional list of the compiled binaries meant to run on several non-Intel CPU running Linux\r\noperating systems, they can affect network devices like routers, bridges, switches, and other the small internet of\r\nthings that we may already use on daily basis:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\nm68k-68xxx.cloudbot: 32-bit MSB Motorola m68k, 68020, version 1 (SYSV), statically linked\r\nhnios2.cloudbot: 32-bit LSB Altera Nios II, version 1 (SYSV), dynamically linked\r\nhriscv64.cloudbot: 64-bit LSB UCB RISC-V, version 1 (SYSV), dynamically linked\r\nmicroblazebe.cloudbot: 32-bit MSB Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), statically\r\nlinked\r\nmicroblazeel.cloudbot: 32-bit LSB version 1 (SYSV), statically linked,\r\nsh-sh4.cloudbot: 32-bit LSB Renesas SH, version 1 (SYSV), statically linked.\r\nxtensa.cloudbot: 32-bit LSB Tensilica Xtensa, version 1 (SYSV), dynamically linked.\r\narcle-750d.cloudbot: 32-bit LSB ARC Cores Tangent-A5, version 1 (SYSV), statically linked.\r\narc.cloudbot: 32-bit LSB ARC Cores Tangent-A5, version 1 (SYSV), dynamically\r\nlinked.\r\n(The hashes are all recorded in the \"Hashes\" section of this post)\r\nBinary Analysis\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 2 of 32\n\nSince I was asked to look into the MIPS sample so I started with it. The binary analysis is showing a symbol\r\nstriping result, but we can still get some executable section's information, compiler setting/trace that's showing\r\nhow it should be run, and some information regarding of the size for the section/program headers, but it's all just\r\ntoo few isn't it? Still this analysis is good for getting information we need for supporting dynamic analysis (if\r\nneeded) afterward. I personally love to solve malware stuff as statically as possible.\r\nI don't think I will get much information on the early stage (binary analysis) with this ELF binary, except what had\r\nalready known, such as cross-compiling result, not packed, and headers and entry0 are in place, so I'm good for\r\nconducting the next analysis step.\r\nFor file attributes I extracted them using forensics tools included in Tsurugi Linux commands, which are also not\r\nshowing special result too, except of what has been recorded from the infected box. So I was taking several checks\r\nfurther I run some several ELF pattern signatures I know, with running it against my collection of Yara rules and\r\nClamAV signature to match it to previous threat database that I have, and this is only to make me understand why\r\nseveral false-positive results came up in other Anti Virus product's detection. The malware yet is having several\r\ninteresting strings but they are still too generic to be processed to identify the threat without reading its assembly\r\nfurther.\r\nSo my \"practical binary analysis\" result for this MIPS binary is going to be it, nothing much.\r\nSome methods on MIPS-32 static analysis to dissect this sample with radare2:)\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 3 of 32\n\nSo this is the fun part, the binary analysis with radare2 ;). no cutter GUI, no fancy huds, just an old-schooler way\r\nwith command line, visual mode and graph in a r2shell.\r\nI think there is really no such precise step by step \"cookbook\" on how to to use radare2 during analyzing\r\nsomething, and basically radare2 is enriched in design coded by several coders for any kind of users to use it\r\nfreely with many flavor and options or purpose in binary analysis, once you get into it you'll just get use to use it\r\nsince radare2 will eventually adapting to your methods, and before you know it you are using it forever.\r\nMy line of work from day one is UNIX operating systems, I use radare2 since the name is \"radare\" compiled from\r\nFreeBSD ports in between years of 2006 to 2007, and I mostly use command line basis on every radare shell on\r\nmy VT100x/VT200x terminal emulation variants I use afterwards, this is kind of building my reversing forms\r\nwith radare2 until now. The command line base.\r\nBut first, let's make sure you are setting\"mips\" and \"32\" in radare2 environment of assembly architecture (arc) and\r\nbits for this binary, then try to recognize the \"main function\", which is in \"0x4016a0\" at the pattern/location that's\r\ndifferent than Intel basis assembly like shown in the picture below:\r\nNext, I may just run following commands to be sure that it can be reversed well. It is a simple command for only\r\nshowing how many Linux syscall is used, and this will work after the radare2 parse and analyze the binary to the\r\nanalysis database.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 4 of 32\n\nPS: If you know what you're doing, an simpler/easier way for the MIPS 32bit to seek where the syscall codes\r\nplaced is by grepping the assembly code with the hex value of \"0x0000000c\" like below, the same result should\r\ncome up:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 5 of 32\n\nIn my case on dealing with Linux or UNIX binaries, I have to know first what syscalls are used (that kernel uses\r\nfor making basic operations), \"syscall\" is used to request a service from kernel. Any good or bad program are\r\nusing those (if they need to run on that OS), so syscalls have to be there. For me, the syscalls is important and its\r\namount will tell you how big the work load will be, ..then the rest is up to you and radare2 to extract them, the\r\nmore of those syscalls, the merrier our RE life will be, without knowing these syscalls there's no way we can solve\r\nsuch stripped binary :)\r\nIn a Linux MIPS architecture, where assembly and register (reduced registers due to small space) is different than\r\nPC's Intel ones (MISP is RISC, Intel is CISC, RISC is for a CPU that is designed based on simple orders to act\r\nfast, many networking devices are on RISC for this reason). Linux OS in some MIPS platform can be configured\r\nto run either in big or in little endian mode too, you have to be careful about the endianness in reversing MIPS,\r\nlike this MIPS binary is using big endian, also binaries for SGI machines, but some machines like Loongson 3 are\r\njust like Intel or PPC works in little endian, several Linux OS is differing their package for supporting each\r\nendianness with \"mips\" (big) or \"mipsel\" (little) in their MIPS port. Information on the target machines for each\r\nsample can help to recognize the endianness used.\r\nIn MIPS the way \"syscall\" used is also have its own uniqueness. Basically, a designated service code for a syscall\r\nmust be passed in $v0 register, and arguments are passed in other registers. A simple way in assembly code to\r\nrecognize a syscall is as per below snipped code:\r\n1\r\n2\r\n3\r\nli $v0, 0x1\r\nadd $a0, $t0, $zero\r\nsyscall\r\nExplanation: The \"0x1\" is stored in the \"$v0\" register (it doesn't have to be assembly command \"li\" but any\r\ncommand in MIPS assembly in example \"addliu\", etc, can be used for the same effect), which means the service\r\ncode used to print integer. The next line is to perform a copy value from the register \"$t0\" to \"$a0\" (register where\r\nargument is usually saved).\r\nFinally (the third line) the syscall code is there, with these components altogether one \"syscall\" can be executed.\r\nWe can apply the above concept in the previously grep syscall result. The objective is to recognize the address of\r\nits syscall wrapper function for this stripped binary analysis purpose. For example, at the second result at\r\n\"0x004019d0\" there's a syscall number, and by radare2 you go to that location with seek (s) command and using\r\nvisual mode we can figure the function name in no time. I will show you how.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 6 of 32\n\nLet's fix the screen for it as per below so we can be at the same page:\r\nI marked the line where it is assigning \"0xfa2\" value to \"$v0\", and \"0xfa2\" is the number registered for \"fork\"\r\nsyscall in Linux MIPS 32bit OS, that's also saying 0xfa2 is syscall number of sys_fork (system call for fork\r\ncomnmand), if you scroll up a bit you can see the function name \"fcn.004019a0\", which is the \"wrapper\r\nfunction\" for this \"syscall fork\" or \"sys_fork\". The syscall command will accept the passed syscall number\r\nstored in \"$v0\" to be translated in the syscall table to pass it through the OS specific registered syscall name\r\nalongside with the arguments needed to perform the further desired syscall operation.\r\nNoted that the syscall number can always be confirmed in designated Linux OS in the file with the below formula,\r\nand more information on register assignment on MIPS architecture that explains syscalls calling conventions can\r\nbe read in ==\u003e[link].\r\n1 /usr/ include /{YOUR_ARCH}/asm/unistd_{YOUR_BIT}.h\r\nThe manual of syscall [link] is a good reference explaining syscall wrapper in libc. Quoted:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n\"Usually, system calls are not invoked directly:\r\ninstead, most system calls have corresponding C library wrapper\r\nfunctions which perform the steps required (e.g., trapping to kernel\r\nmode) in order to invoke the system call.\r\nThus, making a system call looks the same as invoking a\r\nnormal library function.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 7 of 32\n\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\nIn many cases, the C library wrapper function does nothing more than:\r\n* copying arguments and the unique system call number to the\r\nregisters where the kernel expects them;\r\n* trapping to kernel mode, at which point the kernel does the real\r\nwork of the system call;\r\n* setting errno if the system call returns an error number when the\r\nkernel returns the CPU to user mode.\r\nHowever, in a few cases, a wrapper function may do rather more than\r\nthis, for example, performing some preprocessing of the arguments\r\nbefore trapping to kernel mode, or postprocessing of values returned\r\nby the system call. Where this is the case, the manual pages in\r\nSection 2 generally try to note the details of both the (usually GNU)\r\nC library API interface and the raw system call. Most commonly, the\r\nmain DESCRIPTION will focus on the C library interface, and\r\ndifferences for the system call are covered in the NOTES section.\"\r\nUsing this method, in no time you'll get the full list of the syscall function's used by this malware as per following\r\ntable that I made for myself during this analysis:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 8 of 32\n\nThe rest is up to you on how to make it easy to name the strings for each \"syscall\" for your purpose, I go by the\r\nabove strings naming since it is fit to my RE platform, I suggest you refer to Linux syscall base on naming them\r\n[link].\r\nThe next step is, you may need to change all function name in radare2 according to this \"syscall table\". Using the\r\nvisual mode and analyze function name (afn) command is the faster way to do it manually, or you can script that\r\ntoo, radare2 can be used with varied of methods, anything will do as long as we can get the job's done. In my case\r\nI like to use these radare2 shell macro based on table I made for myself:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n:\r\ns 0x0402060; af; afn ____connect; pdf | head\r\ns 0x0401CF0; af; afn ____write; pdf | head\r\ns 0x04019B0; af; afn ____fork; pdf | head\r\n:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 9 of 32\n\nThe result is as per seen in the below screenshot:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 10 of 32\n\nUp to this way, we'll have all of the syscalls back in place :) Don't worry, you'll do this faster if you get used to it.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 11 of 32\n\nThe result looks cool enough for me to read the radare2 graph on examining how this MIPS binary further goes..\r\nThe next step is a generic way on reversing a stripped binary, by defining the functions that is not part of Libc but\r\nlikely coded by malware coder. For this task, you have to check the rest of the function and seek whether the\r\nXREF doesn't go to any of syscall wrapper functions, make sure that function itself is not the main() function,\r\ninit_proc() nor init_term() functions, and that goes to the below leftover list, just naming it to anything you think it\r\nis fit with to what it does.\r\nIn my case I named them this way:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 12 of 32\n\nThen we can put the correct function name into the binary using the same macro I showed you previously, then we\r\nare pretty much completed in making this binary so readable... hold on, but read it from where? Where to start?\r\nTo pick a good place to start to start reversing, this command will help you to pick some juicy spots, all the\r\nextractable strings will be dumped and we can pick one interesting one to start, and go up to build the big\r\npicture.:)\r\nActually symbols are giving us much better options, but right now we don't have anything else that is readable\r\nenough to start..\r\nYou can start to trace this binary from these text address reference and then go up to the call in the main function\r\nthat supports it. For example, by using the visual mode you can seek the XREF of each text to see how it is called\r\nfrom which function and you can trail them further after that. This isn't going to be difficult to read since you have\r\nall functions back in place.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 13 of 32\n\nThe picture below is showing how the \"air dropping\" is referred to the caller function.\r\nThat's it. These methods I shared are useful methodology in analyzing Linux MIPS-32 binary especially stripped\r\nones like the one I have now. I think you're good enough to go to complete your own analysis by yourself too.\r\nPlease just tried those methods if you don't have any other better ways and don't be afraid if other RE tools can't\r\nmake you read the MIPS-32 binary well, just fire the radare2 with the tips written above, and everything should\r\nbe okay :)\r\nWe go on with the malware analysis of this binary and its threat then..\r\nWhat does this MIPS-32 binary do?\r\nPractically. the MIPS binary is bot that is having a mission to infect the host it was dropped into (note: so it needs\r\na dropping scheme to go to the infected host beforehand), making a malicious process called \"cloudprocess\", send\r\nmessage of \"airdopping clouds\" through the standard output (that can be piped later on). It is recording its \"PID\"\r\nand fork its process for the further step. The message of \"airdropping clouds\" is the reason why I called this\r\nmalware as \"AirDropBot\" eventhough the coder prefer to use \"Cloudbot\", which there is also a legitimate good\r\nsoftware that uses that name too as their brand.\r\nUpon successful forking it will extract the what the coder so-called \"encrypted array\", it's ala Mirai table crypted\r\nkeywords in its concept, but it is different in implementation., I must guess that it could be originally coded to\r\navoid XOR operation which is the worst Mirai bug in the history :) but this \"encrypt_array\" is just ending up to\r\nan encoded obfuscation function :) - Anyhow the value from this \"decrypted\" coded is used for further malware\r\nprocess.\r\nThen the malware tries to connect to the C2 which its IP address is hard-coded in the binary, on a success\r\nconnection attempt to C2 server, it will parse the commands sent by the C2 to perform three weaponized functions\r\non the binary to perform TCP, and UDP DDoS attack with either using the specific hex-coded payload, or the\r\nlatter on is using a custom pattern so-called \"hex-attack\" that sends DoS packet in a hex escape strings format to\r\nthe targeted host.\r\nI will break it down to more details in its specific functions in the next sections.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 14 of 32\n\nThe \"encryption\" (aka the obfuscation)\r\nThe challenge was the \"encryption\" part, it was I used radare2 with ESIL to see the \"encrypted\" variables, as per\r\nsnipped below as PoC:\r\nThe decryption is by [shift-1] as per shown in the cascade loop shown in every encoded strings.\r\nIf we want to translate this decryoter scheme, it may look something like this (below), I break it up in 3 functions\r\nbut in assembly it is all in a function and cascaded to each strings to be decoded:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\nint encrypt_array()\r\n{\r\narray_splitter( \"xxxx\" );\r\narray_splitter( \"yyyy\" );\r\n:\r\n}\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 15 of 32\n\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\nint array_splitter( char *src)\r\n{\r\nstrcpy (var_char_buffer, src);\r\nchar_decrypter(var_char_buffer);\r\narray_counter++\r\nreturn ;\r\n}\r\nint char_decrypter( char *src2)\r\n{\r\nint i; strcpy (dstring, src2);\r\nfor ( i = 0; strlen (dstring) \u003e i; ++i )\r\nstrcpy (j, dstring);\r\nreturn j++\r\n}\r\nThe result for the \"decryption\" can be shown as per below, using ESIL with the fake stack can be used to emulate\r\nthis with the same result, so you don't need to get into the debug mode:\r\nThe last four strings:\r\n1\r\n2\r\n/proc/\r\n/maps\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 16 of 32\n\n3\r\n4\r\n5\r\n/cmdline\r\n/status\r\n/exe\r\n...are used for taking information (process name) from the infected Linux box, that will be used for the malware\r\nother functions like \"killing\" processes, etc. The other decrypted strings are used for infecting purpose (known\r\ncredentials for telnet operation), and also for other botnet operation related.\r\nUnderstanding the \"decrypter\" logic used is important because the same decrypter is used again to decode the C2\r\nsent commands to the active bots before parsed and executed.\r\nThe C2, its commands and bot offensive activity\r\nWhat happened after decryption (encrypt_array) of these strings is, the binary gets into the loop to call the\r\n\"connecting\" function per 5 seconds. If I try to write C code based on this stage it's going to be like below\r\nsnipcode:\r\nWithin each loop, when it calls \"connecting\" function it will try to connect the C2 which is defined a struct\r\nsockaddr \"addr\", pointing to port number (htons) 455 (0x1c7) and IP: \"179.43.149[.]189\".\r\nWhen connected to C2, it will listen and receive the data sent by C2, to perform decryption and then to send its\r\ndecryption result (as per previous logic) to the \"command parsing\" function, that's having \"cmd_parse\" sub-https://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 17 of 32\n\nfunction inside. The \"command parsing\" is delimiting received command with the white space \" \" for the\r\n\"cmd_parse\" to grep three possible keywords of \"udp\", \"tcp\", and \"hex\", which in next paragraph those\r\nkeywords will be explained further.\r\nBelow is the loop when the command from C2 is received (listened) inside the \"connecting\" function in radare2:\r\nNow we come into the offensive capability of this bot binary. The \"udp\" keyword will trigger the execution of\r\n\"udpattack\" function, \"tcp\" will execute \"tcpattack\" and so does the \"hex\" for executing the \"hexattack\"\r\nfunction. Each of the trigger keywords are followed by arguments that are passed to its related attack function, it\r\nemphasizes that a textual basis DoS attack command line starting with udp, tcp or hex, following by the targets or\r\noptional attack parameters are pushed from the C2 to the AirDropBots. Based on experience, the C2 CLI interface\r\nof recent DDoS botnets is having such interface matched to this criteria.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 18 of 32\n\nTCP and UDP is having the same payload packet in binary is as per below:\r\n...that is sent from tcpattack() and udpattack() in TCP and UDP different socket connection from the target sent\r\nby C2.\r\nThe hexattack is having a different payload that looks like this:\r\nOne last command is is \"killyourself\" (taken from decrypted table that was saved in a var) that will stop the\r\nscanning function fork with the flow more or less like this:\r\n1\r\n2\r\n3\r\n4\r\nresult = strstr (var_parsed_cmd, \"killyourself\" );\r\nif ( result )\r\n{ kill(scanner_fork_PID, 9);\r\nexit (0);\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 19 of 32\n\n5\r\n6\r\n}\r\nreturn result;\r\n..and the kill function above is executing \"kill -9\" by calling int kill(__pid_t pid, int sig).\r\nAs additional, in the older version, there is also another C2 command called: \"http\" that will execute \"httpattack\"\r\nfunction that is using HTTP to perform L7 DoS attack using the combination of User-Agents, but in this sample\r\nseries I don't see such function.\r\nIs there any difference between MIPS and other binaries?\r\nOh yes it has. The Intel and ARM version (or to binary that is having a scanner function) is interestingly having\r\nmore functions. If I go to details on each functions for Intel binary maybe I will not stop writing this post, so I will\r\nsummary them below with a pseudo code snips if necessary.\r\n1. The \"array_kill_list\" function\r\nThis function is used to kill process that matched to these strings:\r\nIt seems this is how the bot herder gets rid of the competitor if they're in the same infected Linux box.\r\nThis \"array_kill_list\" is accessed from killer() function that is being executed before going to \"connecting\" loop\r\nin the main for Intel version.\r\nThe killer function is having multiple capability to stop unwanted processes too, it will be too long to describe it\r\none by one but in simple C code and comments as per picture below will be enough to get the idea:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 20 of 32\n\n2. The scanner, the spreader via exploit\r\nThe bot herder is aiming Lynksys tmUnblock.cgi of a known router's brand, the vulnerability that has to be\r\npatched since published 5 years ago. For this purpose, in intel and ARM binaries right after killer() function it\r\nruns scanner() function, targeting randomized formed IP addresses, using a hard-coded \"payload\" data,\r\nspoofed its origin by faking the HTTP request headers (for \"tcp\" or \"http\" flood), which is aiming TCP port 8080\r\nwith the code translated from assembly to simplified C code looks like below:\r\nThis scanner is having four pattern of payloads which I quickly paste it below for your reference if you are either\r\nreceiving or researching this attack:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 21 of 32\n\nMaybe one of the thing that I may suggest for this bot's scanner functionality is what it seems like a spoof\r\ncapability. I examined into low level for code generation of about this part and found what the send syscall\r\nperformed when AirDrop bot make scanning with exploit is interesting :) please take a look yourself of what has\r\nbeen recorded as per below snipcodes:\r\nOn those \"scanner\" function supported binary, the spreading scheme is executed with targeting random generated\r\nIP addresses by calling sub-function \"get_random_ip\" right after the the C2 has been attempted to call, and is\r\nusing the same socket for multiple effort to infect Linksys CGI vulnerability. Below is the record in re-production\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 22 of 32\n\nthis activity:\r\n3. The \"singleInstance\" function\r\nThis is a code to make sure that there is no duplication of \"cloudprocess\" process that runs after a device getting\r\ninfected. It's a simple code to kill -KILL the PID of detected double instance. You can easily reverse and examine\r\nit by yourself.\r\nBelow is the example ARM-32 assembly code for this function with my comments in it just in case:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 23 of 32\n\nfor the right side of code, if I write that in C it's going to be something like this, more or less:\r\nBONUS: AirDropBot and the custom ELF packer case\r\nAs per other ELF badness produced by botnet adversaries in the internet, the AirDropBot is having binary that is\r\npacked with custom packer too.\r\nThe below file [link] is one good real example of AirDropBot ELF in packed mode, the VirusTotal detection is\r\nlike below:\r\nThis sample is spotted in the wild a while ago on trying to infect one of my honeytraps. The \"file\" result looks like\r\nthis:\r\n1\r\nx86.cloudbot: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically\r\nlinked, stripped\r\nThe binary is packed and by reading the assembly flow in the packer codes we can tell it is a UPX-like packer. It\r\nlooks like this:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 24 of 32\n\nIf you follow my presentation in R2CON2018 in the last part (the main course) about unpacking with radare2 for\r\nan unknown packer, the same method can be applied for you to get the OEP by implementing several \"bp\" on the\r\nunpacker processes. There are slides and video for that, use this link for some more information: [link]\r\nThat is exactly the method I applied to unpack this ELF.\r\nThen next, after you bp to part where packed code copied to the base memory defined in the LOAD0 section, I\r\nwill share \"my way to\" easily extract the unpacked ELF afterward:\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 25 of 32\n\nELF file headers is having enough information to be rebuilt, let's use it, assuming the header table is the last part\r\nof the ELF the below formula is more or less describing the size of the unpacked object:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\ne_shoff + ( e_shentsize * e_shnum ) = +/- file_size\r\n0x00013af8 + ( 0x0028 * 0x0013 ) = file_size\r\n? (0x0028 * 0x0013) + 0x00013af8|grep hex\r\nAnd.. there you go, this is my unpacked file: [link]\r\nNext, let's see the detection ratio of this packed binary in Virus Total after successfully unpacked (..well, at least it\r\nis two points higher than the packed one) :\r\nAnd the binary after unpacked is very much readable now..and BOOM! the C2 of this packed ELF is in\r\n185.244.25[.]200, 185.244.25[.]201, and 185.244.25[.]202 are revealed! :)) Now we know why the adversary\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 26 of 32\n\nwanted to pack their binary that bad.\r\nFor the addition, nowadays IoT botnet adversaries are not only packing the Intel binaries, but the embedded\r\nplatform's (some are RISC cpu too) Linux binary are often seen packed also with the custom packers. Like in this\r\nsimilar threat report I made [link], with the ELF binary for MIPS cpu (noted: big endian one), sample that was\r\nactually spotted inside of the house of a victim (in his MIPS IoT daily used device, I won't disclose it further). I\r\nanalyzed and unpacked it, to find that is not only \"UPX!\" bytes tampering that has been replaced.\r\nLet me quote it in here too about my suggested unpacking methods for embedded Linux binaries I wrote in the\r\nlinked post, as follows:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n\"There are other radare2 ways also for unpacking and extracting\r\nunpacked sample manually too.\r\nThe \" dmda \" is also useful to dump but it's maybe a bit hard effort to\r\nrun it on embedded system, or, you can fix the load0 and load1 that can\r\nalso be done after you grab \" OEP \", or, you can also break it in the exact\r\nrewriting process to the base address, but either ways, should be able\r\nto unpack it.\r\nFirst ones will consume workspace in the memory for performing it.. I\r\ndon't think RISC systems has much luxury in space for that purpose,\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 27 of 32\n\n10\r\n11\r\n12\r\nbut the latter one in some circumstance can be performed in ESIL mode.\"\r\nThe thing is you should master all of those methods, and only by that most of binary packing possibility in Linux\r\ncan be solved manually without depending on UPX or any automation tools.\r\n\"So don't worry, just fire your radare2, and everything will be just Okay!\" :D (my favorite motto)\r\nIn a short summary as the conclusion\r\nThis binaries are a DoS bot clients, a part of a DDoS botnet. It spread as a worm with currently aiming Lynksys\r\ntmUnblock.cgi routers derived by non MIPS built binaries that infects machines to act as payload spreader too. I\r\nmust warn you that I did not check the details in every 26 binaries came up during this investigation, but I think\r\nthe general aspect is covered.\r\nThese are malware for Linux platform, it has backdoor, bot functions and are having infection capability with\r\naiming vulnerability in routers CGI or telnet. The malware is coded with many originality intact, again, it is a\r\nnewly coded, it is not using codes from Mirai-like, GafGyt (Qbot/Torlus base), or Kaiten (or STD like), but I can\r\ntell that the development is not mature yet. I was about to name it as \"Cloudbot\" but it looks like there is a\r\nlegitimate software already using it so I switched to the \"Airdropbot\" instead due to the hardcoded message\r\nprinted on a success infection. This is a new strain of various library of IoT botnet, I hope that other security\r\nentities and law enforcer aware of what has just been occurred here, before it is making bigger damage like Mirai\r\nbotnet did before.\r\nDetection methods\r\nBinary detection\r\nFor the binary signature method of detection. The unpacked version will hit just fine. But since the AirDropBot\r\nwas developed to support many embed platform from various CPU and \"endianness\" type, to detect it precisely\r\nyou may need to code several signatures. However, if you see the typical functions of their binary carefully, so it is\r\nyes, one generic rule can be generated and applied. For that I PoC'ed it myself to develop a bit complex Yara rules\r\nto detect them all and to recognize which binary that is having the scanner and not.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 28 of 32\n\nThe snippet code and scan example is as per screenshot below.\r\nTraffic detection\r\nFor the traffic detection, there are two methods that you can apply as detection: (1) The Initial Connection and\r\nactivities of AirDropBot does right after the success infection, or (2) the DoS traffic, I am explaining both as\r\nfollows.\r\nThe Initial connection detection is related to the nature of this malware, which is connecting to C2 and performing\r\nscanning for vulnerabilities aiming random IP in 8080. I can suggest a nice Suricata or Snort rule can be coded for\r\nconnection that's aiming TCP/455 (C2 connection port), but the C2 port can be changed by the adversaries too on\r\ntheir next campaign, but that's not going to be easy for them to prepare all of those varied binaries and C2 port\r\nchanges immediately (smile). The other way is to focus on the scanner payloads as per described in some of\r\npictures above, the Surucata rules to detect them will last longer IF the same vulnerability is still being aimed.\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 29 of 32\n\nThe other detection is by using the AirDropBot's hardcoded flood packets, which I was in purpose whoring them\r\nin the attached pictures above too. This way you may be able to recognize the DoS traffic activity performed by\r\nthis threat in the future DDoS incidents. Sucicata and Snort rules are supported for this purpose.\r\nThe bad actors and his gang are still at large and reading this blog post too :) , I am sorry I can not share the\r\ngeneric scanning code I made in here, but the screenshots I provided are enough for fellow reversers to recognize\r\nand implement these detection methods to filter these series of AirdropBot activities. The rest is OpSec.\r\nHashes and IOC information\r\nThe hashes are listed as per below and IOC has been posted to MISP and OTX for all blue-teamer community to\r\nbe noticed.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n../bins/aarch64be.cloudbot | 417151777eaaccfc62f778d33fd183ff\r\n../bins/arc.cloudbot | d31f047c125deb4c2f879d88b083b9d5\r\n../bins/arcle-750d.cloudbot | ff1eb225f31e5c29dde47c147f40627e\r\n../bins/arcle-hs38.cloudbot | f3aed39202b51afdd1354adc8362d6bf\r\n../bins/arm.cloudbot | 083a5f463cb84f7ae8868cb2eb6a22eb\r\n../bins/arm5.cloudbot | 9ce4decd27c303a44ab2e187625934f3\r\n../bins/arm6.cloudbot | b6c6c1b2e89de81db8633144f4cb4b7d\r\n../bins/arm7.cloudbot | abd5008522f69cca92f8eefeb5f160e2\r\n../bins/fritzbox.cloudbot | a84bbf660ace4f0159f3d13e058235e9\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 30 of 32\n\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n../bins/haarch64.cloudbot | 5fec65455bd8c842d672171d475460b6\r\n../bins/hnios2.cloudbot | 4d3cab2d0c51081e509ad25fbd7ff596\r\n../bins/hopenrisc.cloudbot | 252e2dfdf04290e7e9fc3c4d61bb3529\r\n../bins/hriscv64.cloudbot | 5dcdace449052a596bce05328bd23a3b\r\n../bins/linksys.cloudbot | 9c66fbe776a97a8613bfa983c7dca149\r\n../bins/m68k-68xxx.cloudbot | 59af44a74873ac034bd24ca1c3275af5\r\n../bins/microblazebe.cloudbot | 9642b8aff1fda24baa6abe0aa8c8b173\r\n../bins/microblazeel.cloudbot | e56cec6001f2f6efc0ad7c2fb840aceb\r\n../bins/mips.cloudbot | 54d93673f9539f1914008cfe8fd2bbdd\r\n../bins/mips2.cloudbot | a84bbf660ace4f0159f3d13e058235e9\r\n../bins/mpsl.cloudbot | 9c66fbe776a97a8613bfa983c7dca149\r\n../bins/ppc.cloudbot | 6d202084d4f25a0aa2225589dab536e7\r\n../bins/sh-sh4.cloudbot | cfbf1bd882ae7b87d4b04122d2ab42cb\r\n../bins/sh4.cloudbot | b02af5bd329e19d7e4e2006c9c172713\r\n../bins/x86.cloudbot | 85a8aad8d938c44c3f3f51089a60ec16\r\n../bins/x86_64.cloudbot | 2c0afe7b13cdd642336ccc7b3e952d8d\r\n../bins/xtensa.cloudbot | 94b8337a2d217286775bcc36d9c862d2\r\nSalutation \u0026 Epilogue\r\nI would like to thank to @0xrb for his persistence trying to convince me that this binary is interesting. It is\r\ninteresting indeed, and as promised, this is the analysis I did after work, writing this in 8hours more non-stop.\r\nThank's also for other readers who keep on supporting MMD, and as team, we appreciate your patience in waiting\r\nfor our new post.\r\nThank you pancake and Radare2 teams who keep on making radare2 the best RE tools for UNIX (All of the\r\nradare2 reversing was done in FreeBSD OS, thank you for your great support to FreeBSD!), and also I thank\r\nTsurugi DFIR team for your great forensics tools. For these open source security frameworks I still keep on\r\nhelping with tests and bug reports.\r\nOkay, I will rest and will wordsmith some miserable jargon parts of the post later, maybe I will add detail that I\r\ndidn't have much time to write it now, or, to correct some minor stuff. In the mean time, enjoy the writing, please\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 31 of 32\n\nshare with mention or using #MalwareMustDie hashtag. This post is a start for more posts to come.\r\nA tribute to the newborn radare2 community in Japan \"r2jp\", that we established in 2013 together with\r\n\"pancake\" on AVTokyo workshop in Tokyo, Japan.\r\nThis technical analysis and its contents is an original work and firstly published in the current MalwareMustDie\r\nBlog post (this site), the analysis and writing is made by @unixfreaxjp.\r\nThe research contents is bound to our legal disclaimer guide line in sharing of MalwareMustDie NPO research\r\nmaterial.\r\nMalware Must Die!\r\nSource: https://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nhttps://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html\r\nPage 32 of 32\n\n  https://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html    \nPS: If you know what you're doing, an simpler/easier way for the MIPS 32bit to seek where the syscall codes\nplaced is by grepping the assembly code with the hex value of \"0x0000000c\" like below, the same result should\ncome up:      \n   Page 5 of 32   \n\n  https://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html     \nUp to this way, we'll have all of the syscalls back in place :) Don't worry, you'll do this faster if you get used to it.\n   Page 11 of 32",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://blog.malwaremustdie.org/2019/09/mmd-0064-2019-linuxairdropbot.html"
	],
	"report_names": [
		"mmd-0064-2019-linuxairdropbot.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434704,
	"ts_updated_at": 1775960483,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/c26d185f6f59a5662b598ac56f381c0f478c1668.pdf",
		"text": "https://archive.orkl.eu/c26d185f6f59a5662b598ac56f381c0f478c1668.txt",
		"img": "https://archive.orkl.eu/c26d185f6f59a5662b598ac56f381c0f478c1668.jpg"
	}
}