1/12 By Rahul R December 2, 2022 KoiVM Loader Resurfaces With a Bang labs.k7computing.com/index.php/koivm-loader-resurfaces-with-a-bang/ We at K7 Labs recently found an interesting new .NET loader which downloads and executes KoiVM virtualized binary, which in turn drops Remcos RAT and Agent Tesla based on the availability of its C2. The samples under consideration uses hastebin URLs as its C2 server to download the next stage payloads. The overall flow of this multistage malware can be observed in the following flow diagram. https://labs.k7computing.com/index.php/koivm-loader-resurfaces-with-a-bang/ https://github.com/Loksie/KoiVM-Virtualization#koivm https://hastebin.com/about.md 2/12 Figure 1: Execution Flow The initial downloader is dropped through spam emails containing attachments of the names “New Orders.zip” or “Export Invoice – 8026137.zip”. The Zip contains a .NET executable with the same name as the Zip file and disguises itself as a calculator application. However, it is actually a multistage downloader. Figure 2: Original Name of Downloader Stage-1 (Downloader Analysis) The downloader initially starts to decode the C2 using an interesting decoding routine given below. 3/12 Figure 3: C2 decoding routine Each character of the C2 string is XOR’ed with the index value of the corresponding character to obtain the C2 address. We can easily mimic this in Python using the code given below. “”” Code to decode C2 URL’s “”” c2servers = "" decoded = r"huvsw?) (`hy\u007fioga>r}~;gw`7w{huwquISW\u000fLQRW[\u0013\u0005\u0004DL] [US[]\u001aVYZ\u0017K[L\u0013^_N5,7!1<)" for c in range(0, len(decoded)): c2servers += chr(ord(decoded[c]) ^ c) print(c2servers.replace(",", "\n")) Extracted C2’s: hxxps://hastebin[.]com/raw/nasijojiru hxxps://hastebin[.]com/raw/caqumubuyo Once the C2 address  is decoded, it sends a GET request to download the encoded 2 stage KoiVM Droppers. After receiving the response from the server, the downloader starts its multistage decoding routine. It base64 decodes the response and decompresses it in memory using the DeflateStream class. The resultant buffer is XORed with the hardcoded key in the stage-1 downloader “M4use” to get the final decoded stage-2 KoiVM dropper binaries. Figure 4: Payload decoding flow nd 4/12 Stage2 (Virtualized Droppers) Figure 5: KoiVM Dropper The stage-2 payload is highly obfuscated and virtualized with KoiVM. It is used along with ConfuserEx to virtualize the execution of the sample. It changes all the IL-Instruction to the byte format understandable only by the KoiVM Runtime.  As stated in KoiVM Readme, virtualization with KoiVM can be done in two ways 1. Virtualize only the methods which we select 2. Virtualize all the functions including ConfuserEx integrity protection The stage-2 dropper payloads had chosen the 2 option to virtualize all the functions, which made our analysis harder. Since Win32API and structs are accessed using PInvoke in C# and it can’t be virtualized or obfuscated, we were able to identify the API’s and correlate the behavior of this KoiVM dropper. The sample imports all the API’s which are required for Process Injection and In-memory execution. nd https://github.com/yck1509/ConfuserEx https://github.com/Loksie/KoiVM-Virtualization#:~:text=first%20one%20is%20certainly%20ridiculous%20as%20it%20will%20%22merge%22%20with%20cex%20and%20virtualize%20every%20single%20method%2C%20including%20protections%20from%20ConfuserEX%2C%20however%20note%20that%20this%20might%20KILL%20your%20performan 5/12 Figure 6: Imports accessed through PInvoke The encoded stage-3 payload is found in the resource section of the KoiVM binary. On analyzing the blob, we found an interesting string pattern which seems to be repeating. When Null bytes are XOR’ed with a key, the resultant value is the key itself. Since the 3 stage payload has many NULL bytes we are able to extract the XOR key used for decoding. Similarly, the KoiVM sample downloaded from the other hastebin URL (second C2 address) had a similar pattern. There are two different final 3 stage payloads which are dropped based on the C2 address accessed , of which the first binary is XOR decoded using the key “Jus3ify” and the second binary is XOR decoded using the key “Monito3“.  rd rd 6/12 Figure 7: Decoded stage-3 payloads The key can also be identified by debugging the KoiVM Runtime using dnSpyEx and stepping into the yielder function “SelectIterator” as shown in image below. We were able to view payload data and key as plaintext because all functions of KoiVM dropper binary are only virtualized and not the calls to string methods. https://github.com/dnSpyEx 7/12 Figure 8: XOR key in memory Figure 9: XOR decoded payload in memory Stage 3 Agent Tesla Using Detect it Easywe were able to identify that stage-3 payload is obfuscated with .Net Reactor, thus we used .NetSlayer to de-obfuscate the sample to analyze further. https://github.com/horsicq/Detect-It-Easy https://github.com/SychicBoy/NETReactorSlayer 8/12 Figure 10: Trying to de-virtualize using .NET Slayer The tool was not able to completely de-obfuscate the sample, for example we could see that the Agent Tesla binary has implemented control flow flattening, but the tool was not able to unflatten it. The strings are present in raw hex form using string interning. Figure 11: Control flow flattening implemented in Agent Tesla 9/12 The Agent Tesla malware has the capability to log keystrokes, steal browser cookies and crypto wallets and send it to C2. All the strings are saved as raw bytes by using string interning and they are accessed with respective index and length using a class method. Figure 12: Configuration stored using string interning On dumping the strings, we got a configuration file and confirmed it as Agent Tesla malware. Figure 13: Tesla Configuration Agent Tesla is an info stealing malware, which collects keystrokes, browser cookies, and system information. The collected data is sent as an attachment to a mail id – peterashley202@gmail[.]com. Remcos RAT  10/12 On viewing the strings from stage-2 payload (the KoiVM payload2 from the second hastebin URL), we were able to identify the final payload to be Remcos RAT which was confirmed by extracting the configuration from KoiVM payload2’s  resource section. Figure 14: Remcos Agent String The RC4 encrypted configuration of Remcos RAT is saved in the resource section as “SETTINGS”.  Figure 15: Remcos RAT encrypted config stored in resource The first byte in the configuration file is the length of RC4 key(n). The next n bytes are the RC4 key followed by the payload bytes. 11/12 Figure 16: Remcos Configuration Remcos RAT steals browser cookies, takes current window screenshots and sends it to the C2 present in Configuration. It establishes a listener connection with the C2 and waits for the attacker to send commands to execute. We at K7 Labs provide detection against latest threats and also for this newer variant of Loader. Users are advised to use a reliable security product such as “K7 Total Security” and keep it up-to-date so as to safeguard their devices. IOCs Filename MD5 Hash K7 Detection Name Stage1  Loader 908A565A9041D68A2FEA61329D4C42B4 Trojan- Downloader ( 00599fcf1 ) Stage2 (KoiVM) Tesla DropperRemcos Dropper 859E6D2588B14AA298F22F3E70043C69 3A62051DD210BC85C93BF343DCD8ACAD Trojan ( 0058ba9a1 ) Trojan ( 0058ba9a1 ) 12/12 Stage3 (Stealer) Agent Tesla Remcos RAT 77047DAC5FE6958A3C7C9DD1DE08C854 40B71E34E832DEACFFB9589F2BB87323 Spyware ( 0058f8971 ) Trojan ( 0053ac2c1 ) C2 hxxps://hastebin[.]com/raw/nasijojiru         – Agent Tesla hxxps://hastebin[.]com/raw/caqumubuyo  – Remcos RAT IP 172.111.234[.]110:5888