During some exploration of my own home router, I discovered some processes for which I couldn’t locate the executable, at least not at the place it was mentioned it should be.
The process informations were pointing to /sbin/ifwatch-if but actually loaded executable sat in /dev/netslink/ .
That path was also present in my mount info, what was another proof of compromise to me.
I’ve gathered a copy of these and passed them through VT with detection rate of 0.
Qemu and strace quickly stopped working, because some nasty debugger hooks that are used to avoid me going into that path.
These were the indicators of my first ‘Real World’ case : Undetected, maybe unknown family of malware, quite complex and using advanced techniques to avoid disassembly and emulation.
So I started digging out the 4 executables and 2 data files were in that folder.
.net_bn , .net_tn, .net_rf, .net_dl were statically compiled arm binaries.
The elf headers were stripped and section headers absent so objdump couldn’t help me getting the disassembly.
Strings were almost absent in most of the executables, except for the .net_bn file, that was actually to huge to analyze completely for now.
However some strings caught my attention.
The interesting part comes from the path and indicates the usage of staticperl : http://search.cpan.org/~mlehmann/App-Staticperl-1.43/bin/staticperl
Other strings captured from the other executables :
Yee1Ahwv Ciecoqu7 ZohHoo5i ZieH8yie Zip0miib
Some are used in the communication protocols that I will cover later.
That made the case actually very interesting and different from the easy strings & objdump cases that are solved in 5 minutes.
I’ve searched around for these limited amount of strings and had no results on VT , Google, KernelMode.
Before digging deeper into the executables I took a look at the 2 data files present.
One of those contained little strings but was mainly scrambled data. The other file was containing lot of strings, but these were apparently all mixed and scrambled too.
Somewhere in the middle of all these strings were some names of libraries CBOR::XS, Compress::LZF and by greping those out of the strings it was possible to rebuild an unpacking algorithm to decompress and extract the .net_pl file into multiple source files.
Perl Packages containing the core of the botnet.
And another folder with perl scripts that helped me a lot with the rest. Thank you guys !
The source was minified and not clearly readable but perltidy did a great job restoring this to a readable format.
A couple of minutes later I had clear readable source of the botnet and another new scrambled mysterious file called !whisper.
From the code it was possible to understand what the .net_cf file was used for.
I still remember that beautiful moment where that list of scrambled code appeared as an array of values. port, id, secret :-), speedtest, time on/offline, ipchange count, start count, etc.
A lot of nice info but what I was looking for are ip addresses or domain names and till now none of these showed up.
Part of the config contained an array with scrambled entries, I tried a couple of conversion but none of them did it, so I went back to the source code and looked for places accessing that particular part of the config and there it was, the conversion method to go from scrambled data to ip :port.
I said that there was one of these arrays but actually there are 2 one called ‘seeds’ and another one ‘hpv’. That hpv was also to find in the source file names and will be subject to later analysis
So now I have scripts to unpack the net_pl file, read the settings of net_cf file and extract ip:port of the seeds and clients. That’s cool. But not enough to take it down so lets continue.
A couple of hours later I took a fresh copy of this file and I had totally different ips showing up. I can admit some ip rotation but not that much, so I decided to restart the router over and over and collect these files.
This gave me 100+ seeds and some 3000+ clients. The strangest part is that there was not a lot of duplication in the files, and that made me think that this is actually much bigger than it looked like in the first place.
Next step is to dig deeper in the code, analyze the communication protocol and decode the !whisper file.