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.jpeg
http://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.jpeg
and read its content - Read the
passwrd.txt
file DNS resolution through the hosts file
andGET /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?
SikoMode
is the key that we found in thepasswrd.txt
file.
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.