Kelihos Analysis – Part 1
In the recent years I’ve noticed a shift in the malware economy from botnets to ransomware, which is likely due to the AV industry employing more aggressive tactics against botnets resulting in a drop in profitability. As I’ve said before: ransomware is about as interesting to me is watching oil dry and they’re so basic that they aren’t worth reversing, so I decided to look at something old but gold, Kelihos. Surprisingly I’ve never even looked at Kelihos before as it’s been around way longer than I’ve been reverse engineering, and every time I heard about it during my reversing days it was because it had been taken down…again. Well, last month a friend of mine was talking about how Kelihos was spreading again via Nuclear exploit kit, prompting me to contact the exploit pack guru @Kafeine, and request a recent sample.
Something interesting to note is that Kelihos spreads aggressively via exploit kits, rather than growing slowly over time through self propagation. This is why the many takedown attempts have had little effect as the botmaster can simple sets up new infrastructure and starts spreading again within a few a couple of days (Researchers had reported a new sample being spread less 24 hours after the most recent takedown).
The exploit payload is a small executable ~37kb in size, which has been packed with UPX then encrypted with a regularly updated crypter (to ensure it’s undetected to antiviruses). Once unpacked the loader is pretty simple, here’s a look at the main routine. What happens here is a block of dwords are copied from memory then one is picked by random. In order to find out what these dwords are, we need to take a look at the preceding block of code. Here it takes the dword, xors each of the 4 bytes with (byte_number – 91), then adds a period after each byte except for the last; as you can’t probably guess it’s building an IP address. The block contains between 70 and 80 IPs and the loader will try each IP in an attempt to download onprdfi.exe, until an attempt is successful (the file name changes from time to time but is always 11 bytes in length).
If the loader detects that connections may be being block, it will inject some shellcode into explorer which will try connecting to the same list of IPs again and if any connections are successful, it will call WSADuplicateSocket() and pass the socket handle back to the loader, which will then attempt to download the file (This method is likely designed to bypass basic firewalls by establishing the connection from a trusted process, instead of the loader’s one).
The full block of IPs can be found at address 0x0x404008 and decrypted using the following code: http://pastebin.com/WXkjjacG
Something i noticed while poking around with the loader is that the hardcoded IPs are not actually servers, most are residential IPs and some are even dynamic. Furthermore the HTTP server appears to be custom coded, but reports itself as Apache. A little test you can do is send some random text to the server using netcat, on a normal server we’d get “400 Bad Request”, but the Kelihos severs just close the connection without sending any data.
Here we can see a couple of thing, firstly it’s returning valid IPs for a non-existent domain, each request returns a different IP, and the TTL (time-to-live) is 0; This has all the characteristics of a fastflux nameserver.
Obviously in order for something to actually end up querying this server, it’d need a real DNS with the nameserver pointing to this IP, so can we find the fastflux domain? Well, yes we can. For this purpose I was able to use OpenDNS Investigate, a passive DNS lookup tool. If you’re not familiar with passive DNS, the basics are that the company runs a public DNS server which logs the results of any DNS lookup, so if a computer infected with kelihos resolved the fastflux domain and got this IP, there’d be a record of it in the database, let’s have a look.
Bingo! 5 domains have resolved to this IP and 3 of them have used it as a nameserver, suggesting it’s a double fastflux (both the nameservers and A records change with every query). Finally, by performing a passive lookup of one of the domains, we can see some of the IPs it’s resolved to in the past week.
That’s all for now, the next article will be in a couple of days and will look into the main binary and inner workings of the botnet. I’ve censored the domains because I don’t want to risk people reporting them as it’s not helpful to me or other researchers and has absolutely no effect on the botnet (if you need one for research email or DM me on twitter).
Shout-out to OpenDNS and Kafeine for their help with my research.