Special thanks to HuskyHacks and TCM Security!
Welcome! Today we are responding to an urgent email from the Incident Response team at Husky Incident Response Corporation, as we continue upon the journey laid out for us in our ‘Practical Malware Analysis and Triage’ contract, details of which can be found here.
The following is the email we received upon arriving at our desk this morning:
attached was a binary labelled ‘unknown.exe’; let's begin!
First up we will defang this binary by renaming ‘unknown.exe’ to ‘unknown.exe.malz’, so that nothing accidentally detonates on us before we are ready to have it do so. Following this let's grab the hash and check it against VirusTotal database, which we discover it does not turn up any results (tried SHA256, SHA1, and MD5). How exciting!
Time to perform some basic static analysis, beginning with a strings assessment.
Wow, 13.7K line items in here! Perhaps we can reduce that a little bit by seek and destroying duplicate line items:
That looks more manageable. Time to get into it then; parsing the document, the following strings stand out against the rest:
Loading it into PEStudio we see right away that this is a 64-bit Portable Executable
and digging further we discover several malicious imports and indicators as well as a handful of strings which we overlooked in our original strings analysis (notable that none of the strings we identified on our own are included here, it is good to check strings both ways) and confirmation that this is not a packed binary, based on the ratio between virtual and raw file size.
Time to test an initial detonation. Let's boot up a ProcMon (filtered on ‘Process Name is unknown.exe then Include’) , a TCPView, and a Wireshark, then arm the binary by renaming to ‘unknown.exe’, and push the big red button!
Okay! No action in TCPView, but a handful of action going on in ProcMon and Wireshark. The file, ‘unknown.exe' also deleted itself from the Desktop!
First let's look at Wireshark:
There is a URI requested, hxxp://239.255.255.250:1900
Now let's peek at ProcMon:
There is a lot of files being created, most notable are: History.IE5, INetCookies, UNKNOWN.EXE-BDAE6F3C.pf, unknown.exe.mun
and also two Registry Keys being created: ZoneMap, and Tcpip\Parameters
Filtering onto the Parent PID shows no results, so it is not spawning anything at this point.
Time to move on to basic dynamic analysis, let's boot RemNux, start up iNetSim and Wireshark over there, then re-unzip the file on Flare and run it again.
Right away TCPView shows some network activity, and Wireshark is popping off as well.
actually this thing is BLASTING network traffic. a new attempt to TCP/HTTP request every second with no sign of slowing down after several minutes. It is possible that it is continuing to retry connections that it is not finding, but since it has network access now it just keeps retrying instead of shutting down and deleting. Let's kill it by End Tasking in the Users sub-panel of Task Manager and parse some of our harvested data!
It appears to be requesting the URI hxxp://update.ec12-4-109-278-3-ubuntu20-04.local,
making a DNS request for hxxp://cdn.altimiter.local,
making a huge amount of GET requests including a 'post=' parameter which is encoded or encrypted. It is hard to tell how many it is built to make because we let it run for a while and it seemed to continuously re-attempt connections, so maybe this is just one item being repeated but having something changed within it each attempt and thus resulting in a separate hash/encoding result; it could also be a constant stream of data, sending some aspect of our machine's ongoings in realtime to the server? But WHAT IS THIS ENCRYPTION!?
Perhaps this is the exfiltration mechanism? Protected by a TLS certificate? Elsewhere in Wireshark we do find:
Trying to solve for this encoded/hashed looking series, we can run it through the Hashid (Kali tool), as well as online tools for hashes and encodings to no result.
One other thing we should take note of is that there is another GET request going out to the following website hxxp://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab?fb2bab0ba8a3d493 as well as . . ./authrootstl.cab?4479deed411ed404. A quick Google identifies that this is a Windows Update location that ‘automatically updates untrusted certificates’.
Dipping back into ProcMon, there is some new action happening as well! This definitely does not look good, WHAT ARE YOU DOING TO MATT'S CAT?!!
Heading over to investigate we can breathe a small sigh of relief, as at least this document does not contain our user account password! Which makes me think that this could be some type of a key for the binary itself?
Still there are no children spawned from unknown.exe, which simplifies things a little bit.
That said, let's progress into advanced static analysis by tossing unknown.exe into Cutter and navigating to ‘main’ view with Graph tab selected. Hmm, no obvious ‘main’ here, though there are a few ‘*.main’ around. Using the filter field at the bottom of the functions list parses these out for us:
Three of these look complex enough to give out some information: ‘dbg._tmainCRTStartup’, ‘sym.NimMainModule’, ‘sym.toKnownDomain . . .’
The Startup does not seem terribly informative, although the Main does provide more information to us.
Here we see it checking the Current Directory, and then doing something called ‘checkKillSwitch’ followed by a Jump If Not Equal. If JNE is true it goes right, but if JNE is false then it goes left and executes something called ‘houdini’. This seems interesting, let's look into that a bit further. The functions list contains a listing called ‘sym.houdini . . .’ though I don't see a lot of interesting stuff in here.. It is doing some various work with a handle, opening and renaming it. It also does a ‘echoBinSafe’ near the end. Googling these various functions it appears they are Nim functions, reading through the docs is not enlightening my understanding at all. If I had to guess I would say that, based on the name Houdini, this has something if not everything to do with the binaries self-deletion when not networked.
Moving back into the NimMainModule and following the other path we discover that the binary [do stuff] and winds up at another JNE; one side branching into the Houdini call the other branching into calls to ‘unpackResources’, ‘stealStuff’, and ‘popSafePoint’. If it does steal stuff then it Houdinis after, but if it doesn't steal stuff then it Houdinis.. This is correlating with our earlier theory: assuming that Houdini is a deletion module, then if it has no network it would delete right away; if it does have network then it would [do stuff] and harvest data. Before exfiltrating it could be imagined to check something to ensure its getaway path is clear, which if it is not then it deletes itself, but if it is then is exfiltrates and then deletes itself.
Parsing through some of the other functions in here leads to similar dead ends. I think we are getting a little bogged down in the minutiae here though.
After a few hours of poking and prodding, a certain amount of stuckness established itself. I decided to check out the help video provided by Husky, and found some great news: we discovered pretty much everything intended during this analysis!
The only thing that we missed was the encryption type, it was not TLS encrypted, but rather RC4 encrypted. Looking into RC4 determined that typical tools in fact would not identify this algorithm, but a special tool like Fireeye's Capa could have. There were also clues to this algorithm which could have been determined via Cutter or Floss, but not knowing that RC4 was even a thing, it was entirely overlooked during the process.
So what we have discovered today is that ‘unknown.exe’ is a binary that reaches out to a URL, using this URL's response or lack thereof, as a killswitch. Therefore no network, no execution; and no execution means self-destruction (Houdini is precisely what we theorized it was). In the case there is a callback from the killswitch, the binary then establishes a connection to a secondary server which it will exfiltrate to using an RC4 Stream Cipher to obfuscate the data (not technically encrypted since RC4 is deprecated), sending each chunk of data to the EvilServer by way of this GET request's post= parameter. Using this method the malware steals our precious cat, cosmo.jpeg from the Desktop -- the fiends! The attacker would then scrape this parameter out of their server logs, concatenate the data chunks, and use their RC4 key to decrypt it. This binary then deletes itself when the exfiltration is complete.
Now that we have some information on this thing, how can we write a YARA rule to catch it out in the wild? Some of the most notable static elements of this are: ‘MZ’ magic number, ‘nim’ string, ‘http://cdn.altimiter.local/feed?post=’ string, ‘SikoMode’ string, and ‘toRC4’ string (a couple of these came from a reparsing of Floss output; YARA can only handle static elements, so armed with the search criteria from the analysis, some of these were discovered within the Floss output while the initial go through missed them).
rule Siko_Mode_Sig {
meta:
last_updated = “2021-11-08”
author = “7R!XxSec”
description = “YARA rule for the SikoMode malware”
strings:
$PE_Magic_Number = “MZ”
$Nim_Mal = “nim”
$Kill_Server = “http://cdn.altimiter.local/feed?post=”
$Keyword = “SikoMode”
$Exfil_Stream = “toRC4”
condition:
$PE_Magic_Number at 0 and ($Keyword and $Nim_Mal) or $Nim_Mal and ($Kill_Server and $Exfil_Stream)
}
Wonderful! This looks great, let's get this rule back to the IR team so that they can start monitoring for and protecting from this tragic cat-stealing malware! We can do up the full report in the morning. Thanks for your help today!
Happy Hacking,
S.M.7R!Xx