{
	"id": "19b9f9ee-e2b0-45f9-968f-aa7a75cb8fcd",
	"created_at": "2026-04-06T00:11:58.045558Z",
	"updated_at": "2026-04-10T13:12:48.733285Z",
	"deleted_at": null,
	"sha1_hash": "fc28ed0a53094672002530b90120f7a8278d0591",
	"title": "A Case of Vidar Infostealer - Part 2",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1344060,
	"plain_text": "A Case of Vidar Infostealer - Part 2\r\nPublished: 2022-05-18 · Archived: 2026-04-05 18:09:08 UTC\r\nHi, welcome to the Part 2 of my Vidar infostealer analysis writeup. In part 1 of this post, I covered detailed\r\ntechnical analysis of packed executable dropped by initial stager by extracting and exploring embedded shellcode\r\nwhich is unpacking and self-injecting final payload. This part focuses on detailed static analysis of final injected\r\npayload: unpacked Vidar infostealer, defying anti-analysis techniques employed by malware (string decryption,\r\ndynamically loading DLLs and resolving APIs), automating analysis and finally uncovering stealer’s main\r\nfunctionality through deobfuscated/decrypted strings.\r\nSHA256: fca48ccbf3db60291b49f2290317b4919007dcc4fb943c1136eb70cf998260a5\r\nVidar in a Nutshell\r\nThe Vidar Stealer is popular stealer written in C++ and has been active since October 2018 and seen in numerous\r\ndifferent campaigns. It has been utilized by the threat actors behind GandCrab to use Vidar infostealer in the\r\nprocess for distributing the ransomware as second stage payload, which helps increasing their profits. The family\r\nis quite flexible in its operations as it can be configured to grab specific information dynamically. It fetches its\r\nconfiguration from C2 server at runtime which dictates what features are activated and which information is\r\ngathered and exfiltrated from victim machine. It also downloads several benign supporting dlls (freebl3.dll,\r\nmozglue.dll, msvcp140.dll and nss3.dll) to process encrypted data from browsers such as email credentials, chat\r\naccount details, web-browsing cookies, etc., compresses everything into a ZIP archive, and then exfiltrates the\r\narchive to the attackers via an HTTP POST request. Once this is done, it kills its own process and deletes\r\ndownloaded DLLs, working directory contents and main executable in an attempt to wipe all evidence of its\r\npresence from the victim’s machine.\r\nTechnical Analysis\r\nI’ll start analysis by loading this executable directly in IDA to look for important strings, IDA’s strings window\r\nshow some intersting plaintext and base64 encoded strings stored in .rdata section\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 1 of 22\n\nif I quickly decode few base64 strings in Cyberchef, it results in junk data giving a clue that strings are possibly\r\nencrypted before they were base64 encoded\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 2 of 22\n\nnext I’ll check for encryption algorithm but KANAL fails to detect any potential algorithm for string encryption as\r\ngiven in figure below\r\nso let’s start digging it statically to see how string encryption actually works in this case, for this purpose I’ll\r\ndouble click a base64 encoded string randomly to see where it’s been used by finding its Xrefs which takes us to\r\nsub_423050 routine\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 3 of 22\n\nthis routine seems to be processing most of the base64 encoded strings and storing result for each processed string\r\nin a global variable, apart from first two variables which seem to be storing plaintext values for possible\r\ndecryption key and domain, let’s rename this routine to wrap_decrypt_strings\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 4 of 22\n\nsub_422F70 in wrap_decrypt_strings routine can be seen from figure above to be repititively called with base64\r\nstrings, has been Xref’d for ~400 times, it can be assumed it is processing encrypted strings and can be renamed to\r\ndecrypt_strings for our convenience as shown in the figure below\r\nfurther exploring decrypt_strings by loading the executable in x64dbg, debugging unveils that first two calls to\r\nsub_4011C0 routine are just copying values of key and base64 encoded encrypted string to local variables, next\r\nroutine sub_422D00 is decoding base64 string, stores decoded hex value to a local variable and returns address of\r\nthis local variable\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 5 of 22\n\nbase64 decoded hex string can also be verified in cyberchef\r\nlater it calculates length for base64 decoded hex string and allocates buffer equivalent of that length on heap, next\r\ntwo calls to sub_401330 routine are allocating two buffers on heap for key and base64 decoded hex string\r\nrespectively before it proceeds to finally decrypt data using sub_422980, quick decompilation of code for this\r\nroutine results in three well recognized RC4 loops\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 6 of 22\n\nstring decryption can be confirmed by following Cyberchef recipe\r\ndecompiled version of decrypt_strings routine sums up all the steps described above\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 7 of 22\n\nonce processing for wrap_decrypt_strings completes, it continues to process next routine from _WinMain, a\r\nquick overview of sub_419700 this routine reveals that it makes extensive use of global variables which were\r\ninitialized in wrap_decrypt_strings apart from two calls to sub_4196D0 and sub_4195A0 routines respectively\r\nwhich can further be explored by debugging\r\nin the figure above, routine sub_4196D0 is parsing PEB structure to get base address for Kernel32.dll loaded in\r\nmemory by accessing _PEB -\u003e PEB_LDR_DATA -\u003e InLoadOrderModuleList structures respetively, next routine\r\nsub_4195A0 being called is taking two parametes: 1). kernel32.dll base address 2). address of a global variable\r\ndword_432204 (LoadLibraryA) in first call and dword_432438 (GetProcAddress) in second call\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 8 of 22\n\nwhere sub_4195A0 is parsing kernel32.dll’s header by navigating from IMAGE_DOS_HEADER -\u003e\r\nIMAGE_NT_HEADER -\u003e IMAGE_OPTIONAL_HEADER.DATA_DIRECTORY -\u003e\r\nIMAGE_EXPORT_DIRECTORY.AddressOfNames to retrieve export name and compare it with value of API\r\ncontained by input parameter value which in this case is LoadLibraryA\r\nif both strings match, it returns API’s address by accessing value of\r\nIMAGE_EXPORT_DIRECTORY.AddressOfFunctions field, resolved address is stored in dword_432898\r\nvariable while second call to sub_4195A0 resolves GetProcAddress, stores resolved address to dword_43280C\r\nwhich is subsequently used to resolve rest of API functions at runtime. I wrote an IDAPython script here which is\r\nfirst decrypting strings from wrap_decrypt_strings, resolving APIs from sub_419700 routine, adding comments\r\nand giving meaningful names to global variables storing resolved APIs to properly understand code flow and its\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 9 of 22\n\nfunctionality. decrypt_strings routine from IDAPython script is finding key, locating ~400 base64 encoded\r\nencrypted strings, base64 decoding strings and using key to decrypt base64 decoded hex strings, adding decrypted\r\nstrings as comments and renaming variables as shown in figure below\r\nresolve_apis routine from script is resolving ~100 APIs from 11 libraries from sub_419700 routine\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 10 of 22\n\nafter resolving APIs, next routine sub_41F4A0 checks if victime machine is part of CIS (Commonwealth of\r\nIndependent States) countries which include Armenia, Azerbaijan, Belarus, Georgia, Kazakhstan, Kyrgyzstan,\r\nMoldova, Russia, Tajikistan, Turkmenistan, Ukraine, and Uzbekistan, it retrieves language ID for current user by\r\ncalling GetUserDefaultLangID API and compares returned result with specified location codes\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 11 of 22\n\nwhere 0x43F corresponds to Kazakhstan, 0x443 to Uzbekistan, 0x82C to Azerbaijan and so on, it continues\r\nperforming its tasks if user’s language ID doesn’t fall in the above mentioned category, otherwise it’ll stop\r\nexecution and exit, next routine sub_41B700 performs windows defender anti-emulation check by compareing\r\ncomputer name to HAL9TH and user name to JohnDoe strings\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 12 of 22\n\nonce all required checks are passed, sub_420BE0 routine is called which consists of stealer’s grabbing module, it\r\nprepares urls and destination path strings where downloaded dlls from C2 server are to be stored before\r\nperforming any other activity\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 13 of 22\n\nit downloads 7 dlls under C:\\Programdata\\\r\nnext it creates its working directory under C:\\Programdata, name of directory is randomly generated 15 digit\r\nstring like C:\\ProgramData\\920304972255009 where it further creates four sub-directories (autofill, cc, cookies\r\nand crypto) which are required to be created to store stolen data from browser, outlook, cryptocurrency wallets\r\nand system information gathering modules\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 14 of 22\n\ndifferent types of browsers are being targeted to steal autofill, credit card, cookies, browsing history and victim’s\r\nlogin credentials, this module is equipped with advanced stealing and encryption techniques\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 15 of 22\n\nit further queries registry about SMTP and IMAP servers with confidential data and password, gathers data about\r\nconnected outlook accounts (if any) and finally dumps all the data to outlook.txt file in its working directory\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 16 of 22\n\nlater it scans for .wallet, .seco, .passphrase and .keystore files for ~30 cryptocurrency wallets on their installed\r\npaths and copies scanned files to “crypto” in working directory\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 17 of 22\n\nVidar creates an HTTP POST request for C\u0026C (http://himarkh.xyz/main.php) server in order to download\r\nconfiguration for grabbing module at runtime, parses downloaded configuration and proceeds to gather host,\r\nhardware and installed software related info\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 18 of 22\n\nwhich is stored in system.txt file according to the specified format as shown in figure below\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 19 of 22\n\nthe same routine also captures screenshots which is stored as “screenshot.jpg” inside working directory\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 20 of 22\n\nimmidiately after that a zip file with “_8294024645.zip” name format is created and stolen contents from working\r\ndirectory are compressed (file is compressed using Zip2 encryption algorithm as identified by KANAL)\r\nthe compressed file is now ready to be exfiltrated to its C\u0026C server in another POST request\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 21 of 22\n\nafter exiting from recursive grabbing module, it deletes downloaded DLLs and files created in working directory\r\nbeing used to dump stolen data and information in order to remove its traces from victim machine\r\neventually it prepares a command “/c taskkill /pid PID \u0026 erase EXECUTABLE_PATH \u0026 RD /S /Q\r\nWORKING_DIRECTORY_PATH\\* \u0026 exit” which gets executed using cmd.exe to kill the running infostealer\r\nprocess and to delete remaining directories created by this process and the process itself.\r\nThat’s it for Vidar infostealer’s in-depth static analysis and analysis automation! see you soon in another blogpost.\r\nSource: https://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nhttps://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/\r\nPage 22 of 22\n\nencrypted strings, strings as comments base64 decoding and renaming strings variables and using key as shown in to decrypt base64 figure below decoded hex strings, adding decrypted\nresolve_apis routine from script is resolving ~100 APIs from 11 libraries from sub_419700 routine\n   Page 10 of 22",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://xer0xe9.github.io/A-Case-of-Vidar-Infostealer-Part-2/"
	],
	"report_names": [
		"A-Case-of-Vidar-Infostealer-Part-2"
	],
	"threat_actors": [],
	"ts_created_at": 1775434318,
	"ts_updated_at": 1775826768,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fc28ed0a53094672002530b90120f7a8278d0591.pdf",
		"text": "https://archive.orkl.eu/fc28ed0a53094672002530b90120f7a8278d0591.txt",
		"img": "https://archive.orkl.eu/fc28ed0a53094672002530b90120f7a8278d0591.jpg"
	}
}