# KoiVM Loader Resurfaces With a Bang **[labs.k7computing.com/index.php/koivm-loader-resurfaces-with-a-bang/](https://labs.k7computing.com/index.php/koivm-loader-resurfaces-with-a-bang/)** By Rahul R December 2, 2022 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](https://github.com/Loksie/KoiVM-Virtualization#koivm) [based on the availability of its C2. The samples under consideration uses hastebin URLs](https://hastebin.com/about.md) 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. ----- 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. ----- 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 2nd 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 ----- ## 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](https://github.com/yck1509/ConfuserEx) byte format understandable only by the KoiVM Runtime. As stated in KoiVM [Readme, virtualization with KoiVM can be done in two ways](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) 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 2nd 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. ----- 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 3rd 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 whichrd 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“. ----- Figure 7: Decoded stage-3 payloads [The key can also be identified by debugging the KoiVM Runtime using dnSpyEx and](https://github.com/dnSpyEx) 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. ----- 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](https://github.com/horsicq/Detect-It-Easy) **[Reactor, thus we used .NetSlayer to de-obfuscate the sample to analyze further.](https://github.com/SychicBoy/NETReactorSlayer)** ----- 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 ----- 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** ----- 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. ----- 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 859E6D2588B14AA298F22F3E70043C69 Trojan ( DropperRemcos 3A62051DD210BC85C93BF343DCD8ACAD 0058ba9a1 ) Dropper Trojan ( 0058ba9a1 ) ----- **Stage3 (Stealer)** Agent Tesla Remcos RAT ## C2 77047DAC5FE6958A3C7C9DD1DE08C854 40B71E34E832DEACFFB9589F2BB87323 Spyware ( 0058f8971 ) Trojan ( 0053ac2c1 ) hxxps://hastebin[.]com/raw/nasijojiru – Agent Tesla hxxps://hastebin[.]com/raw/caqumubuyo – Remcos RAT ## IP 172.111.234[.]110:5888 -----