LokiBot After a Decade: An Analysis of a Recent LokiBot Campaign
In Norse mythology, Loki, the god of mischief, has powerful and deceptive transformation abilities. True to its namesake, the malware LokiBot has appeared in numerous variants and payload formats since its discovery more than a decade ago. In this blog, we take a closer look at a multi-stage LokiBot sample from a recent campaign.
Introduction
LokiBot, one of the oldest infostealers that are still active today, was first advertised in May 2015 on an underground forum by vendors nicknamed ‘lokistov’ and ‘carter.’ Since then, it has been modified several times, with spikes in a multitude of advertised versions after the source code leaked in 2018. The code forks were extended by Android support (originally Windows-only), as well as remote access and keylogging capabilities.

Figure 1. First LokiBot advertisement. Source: GitHub.
LokiBot targets credentials from over a hundred software products, such as browsers, cryptocurrency wallets, password managers, email, and FTP clients.
Owing to its affordability, extensive capabilities, and accessibility to low-skilled cybercriminals, LokiBot ranked among the most prominent infostealers globally from 2019 to 2022. Despite reduced activity in recent years, LokiBot remains to be a notable tool in the threat landscape.
Technical Analysis

Figure 2. LokiBot’s execution chain.
Delivery
The analyzed sample was distributed as an email attachment as part of a malspam campaign, which is the standard and the most often reported initial vector for LokiBot. The attachment was a script file written in the JScript language. By default, once the file is double-clicked, it will be read and executed by the Windows Script Host (wscript.exe) program on Windows-based systems.
First Stage: JScript Attachment
As seen in Figure 3, the script file is obviously obfuscated. The obfuscation technique is based on interleaving decryption/decoding subroutines with decoy (often nested) functions and variables, each named with a hexadecimal number.

Figure 3. Obfuscated JScript attachment.
Figure 4 depicts a main subroutine of the same script deobfuscated by an iterative use of the open-source webcrack tool. The initial payload’s primary function is to decode a long Base64-encoded PowerShell script, save it to the C:\Temp folder with a random filename (appended with a datetime stamp), and execute it using the powershell.exe interpreter.

Figure 4. Deobfuscated JScript main function.
All these operations are performed via the ActiveX library, enabling interaction with the operating system. Notably, if the defined timeout (e.g., 50s) after the execution is reached, the associated processes are terminated, and files are deleted as part of the evidence removal.

Figure 5. Deobfuscated JScript clean-up function.
Second Stage: PowerShell Loader
The previously mentioned PowerShell script is a simple .NET assembly loader. Firstly, it performs XOR decryption of a long character string with a hard-coded key, resulting in a Base64-encoded .NET assembly.
Then, the assembly is reflectively loaded with the [System.Reflection.Assembly]::Load function and the control flow is redirected to a designated method - MEN.EXECUTE.LAUNCH().
The following two parameters indicate that further malware staging is passed to the invoked method:
-
The full path of the Microsoft ASP.NET compiler
-
A long byte array
Relevant code excerpt:
# Step 1: Decrypt XOR layer$encryptedPayload = 'BCMCIiQiPyQ1NypxdHcRNFxcXSI...<truncated>'$decryptedData = Decrypt-XORPayload -EncodedData $encryptedPayload -Key "Pussecretvk456"if ($decryptedData) { $binaryAssembly = [System.Convert]::FromBase64String($decryptedData) $targetExe = 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe' [Byte[]]$payloadData = (77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0,184,...<truncated>) $callArguments = [object[]]@($targetExe, $payloadData) # Execute assembly method $result = Execute-AssemblyMethod -AssemblyBytes $binaryAssembly ` -ClassName 'MEN.EXECUTE' ` -FunctionName 'LAUNCH' ` -Arguments $callArguments}
Dedicated to hunting and eradicating the world's most challenging threats.
Third Stage: .NET Injector
The loaded .NET assembly is protected with a well-known open-source ConfuserEx, for which deobfuscation tools are readily available.
Analysis of the decompiled assembly shows a static class constructor that assigns multiple delegates with addresses of chosen kernel32.dll functions, before control flow is passed to the actual LAUNCH() method.
The set of exported API functions is characteristic of a malware infection as they are commonly used in process injection:
-
CreateProcessA
-
VirtualAllocEx
-
WriteProcessMemory
-
SetThreadContext
-
ResumeThread
Proceeding with the analysis, calls to the relevant Windows API functions were substituted with a simple code that dumps passed parameters, so the process injection flow can be easily reconstructed.

Figure 6. Excerpt from the patched decompiled .NET loader.
As shown in the output of the patched assembly (Figure 7), a new aspnet_compiler.exe process is spawned. Subsequently, a memory region is allocated within the process and populated with data.
Inspection of the byte chunks passed to WriteProcessMemory reveals that they correspond to sections of the PE file that were previously supplied as the byte-array parameter to the LAUNCH method.

Figure 7. WinAPI parameters dumping.
Final Stage: LokiBot
The code injected in the previous stage constitutes the final LokiBot payload — a 32-bit PE executable compiled with the 2015 version of MSVC. Like most LokiBot samples, it includes an "x" data section (see Figure 7) that contains 3DES-encrypted command-and-control (C2) endpoint addresses.

Figure 8. LokiBot executable.
API Hashing
A static analysis of the file reveals an unusually small import table. Rather than importing the required APIs directly, the malware resolves the addresses of the needed functions at runtime using an API hashing technique.

Figure 9. Import table of the executable.
Using this technique, the sample first locates the target DLL, either by invoking LoadLibraryW or by walking the PEB. It then iterates through the library’s export table, calculating a hash for each exported function name until it identifies the one whose hash matches the precomputed value of the desired API.

Figure 10. API address resolution function.
LokiBot uses a simple custom hash function, which is based on repeatedly applying byte right-shift and XORing with a fixed hard-coded number.

Figure 11. Python implementation of LokiBot hash function. Source: GitHub.
Since LokiBot's hashing algorithm has been well documented, hashes corresponding to Windows API function names have been cataloged in the open-source HashDB database. The API hash values used in a given sample can be resolved in radare2 (after installing the HashDB CLI tool) with the following one-liner:
pd -4 @@= `axt resolve_hashed_api~[1]` | grep -E -o 'push 0x[a-f0-9]{8}' | awk '{print $2}' | sort | uniq | xargs -I{} hashdb get --hex lokibot {} >> resolved-hashes.txt

Figure 12. Resolved API hashes.
Main Function
Before executing its main functionality, the sample creates a mutex to ensure that only a single instance of LokiBot is running on the system. For the mutex name, it computes the MD5 hash of the MachineGuid value found in the registry.

Figure 13. Mutex-based verification.
After completing its initialization routines, the sample enters its main execution phase, during which it harvests credentials, exfiltrates the collected information, establishes persistence, and communicates with the C2 server to obtain further commands.

Figure 14. LokiBot’s main functionality.
Persistence
LokiBot copies itself to the %AppData% directory, using a filename generated by the same method used for the mutex. Then, it creates a registry key with a name of C2 URL and value pointing to the copied executable. This in fact is a broken persistence mechanism.
As reported by researcher @d00rt, new LokiBot samples generated with custom builders have a patched decryption subroutine that always returns a configured C2 address. As a result, when the malware attempts to establish persistence, it calls the function that returns an incorrect result instead of the intended one: Software\Microsoft\Windows\CurrentVersion\Run.

Figure 15. Broken registry persistence.
Credential Theft
LokiBot implements a dedicated credential-harvesting subroutine for each targeted software product. It iterates through an array of pointers to these functions, invoking each one in turn and storing the collected data in a local buffer. Once all credentials have been gathered, the buffer is compressed with aPLib and transmitted to the C2 server.

Figure 16. Loop calling credential stealing functions.
C2 Instructions
After completing the data theft phase, the malware enters a loop, waiting for further instructions from the C2 server. Every minute, it sends an HTTP request containing information about the infected system and spawns a separate thread to process the server's response and execute any received commands.

Figure 17. Loop listening for commands.
IoCs
-
Filename: gruijvdsdbcmcvbtryedfhpoibbedflokjqnb.js
-
SHA256: c099f965144bccd0b590f946659fc3c0747c54aef505b6caaca9078712f455fb
-
SHA256: 64c7dd0a3a3ae49977ac05913d3878000cce14e5d8c1ee05b782bdfd648bde91
-
SHA256: ad10ff9043d6f327045943635fcbd0c5918acb79dc998db92ee4c7dee5224710
-
SHA256: 4c9f271242f61f1a31b8146305e9a7ed512c521445d4f7a7a901e301307add3d
-
SHA256: 5864a697bd7b339f56b05405f29a097cd027cafdcc4e63c2aaeccccbf930605f
-
IP: 158.94.211.95
-
Domain: kbfvzoboss.bid
-
Domain: alphastand.trade
-
Domain: alphastand.win
-
Domain: alphastand.top
-
URL: http://158.94.211.95/kelly/five/fre.php
-
URL: http://kbfvzoboss.bid/alien/fre.php
-
URL: http://alphastand.trade/alien/fre.php
-
URL: http://alphastand.win/alien/fre.php
-
URL: http://alphastand.top/alien/fre.php
About the Author
Dawid is Security Researcher at LevelBlue. Follow Dawid on LinkedIn.
ABOUT LEVELBLUE
LevelBlue secures what's next with intelligence-led security delivering visibility and speed to stop threats faster. As the world’s largest and most analyst-recognized pure-play managed security services provider, our AI-powered managed services and cyber expertise across managed, advisory, and incident response services help clients operate with confidence. Learn more about us.
https://www.levelblue.com/resources/blogs/internal-blog/how-to-create-a-blog-post/