# Analyzing a VIDAR Infostealer Sample J **blog.jaalma.io/vidar-infostealer-analysis/** [← Home](https://blog.jaalma.io/) ## Introduction While reviewing samples submitted to Any.Run, I came across a [binary that appeared to](https://app.any.run/tasks/8449e90f-586d-44e6-a277-f2be9aa0a2ca/) inject into a target process before performing some suspicious HTTP requests. After further analysis, this binary was found to be consistent with the VIDAR infostealer. This article aims to explain exactly how the infostealer works, the loader chain, what it attempts to steal, and how it exfiltrates data stolen from the host in a short time without leaving a trace. Since this sample already had a dynamic, sandbox run within Any.Run, I decided to download a copy and attempt to reverse engineer it with the aim of understanding more about how it worked, what it was designed to do, and to attempt to identify the malware family. The sample being analyzed in this post has the following file hashes: **MD5: 9BB9FD7110158BEA15B3EB3881C52606** **SHA1: F545BF2A5E310ED8E9A8F553DA11B5C03D859A79** **SHA256: F2FEEFF2C03FE54E6F8415390CFA68671576D4CA598C127B5C73B60864E7372B** The entire infection chain and malware operation can be summarized at a high level by this diagram: ----- ## About VIDAR Although this is not unique to the VIDAR malware family, this infostealer performs a smashand-grab approach to harvesting data by harvesting as much data from the host and exfiltrating as quickly as possible. Public reporting shows that delivery mechanisms for the [VIDAR infostealer include fake software installers,](https://www.secureblink.com/cyber-security-news/tutorial-videos-on-you-tube-help-spread-vidar-and-raccoon-malware) [Windows 11 installers and even](https://www.zscaler.com/blogs/security-research/vidar-distributed-through-backdoored-windows-11-downloads-and-abusing) malicious Microsoft help files delivered via phishing. Since the service provided to the customers of VIDAR exists only to facilitate payload configuration, generation and C2, it is left to the customer to get the malware on to systems; whether themselves or via a third-party malware distribution service. An example of such a [malware distribution service is a group Microsoft tracks as DEV-0569, who leverage](https://www.microsoft.com/en-us/security/blog/2022/11/17/dev-0569-finds-new-ways-to-deliver-royal-ransomware-various-payloads/) techniques such as malvertising, phishing etc. to distribute BATLOADER; a separate malware designed to deliver additional payloads, including VIDAR, ROYAL ransomware and COBALT STRIKE. ## Loader Analysis ----- Based on the sandbox run, the binary appears to spawn a child process instance of ``` AppLaunch.exe, which is a legitimate binary and part of the .NET framework. The suspicious ``` activity performed by the malware then appears to originate from this legitimate process, which is a good indicator that some form of process injection is occurring. ## Initial Assessment The binary being analyzed has the following characteristics: **MD5: 9BB9FD7110158BEA15B3EB3881C52606** **SHA1: F545BF2A5E310ED8E9A8F553DA11B5C03D859A79** **SHA256: F2FEEFF2C03FE54E6F8415390CFA68671576D4CA598C127B5C73B60864E7372B** **Compiled Timestamp: Fri Dec 23 14:09:41 2022 UTC** **Linker: Linker GNU linker ld (GNU Binutils)** The executable itself has very few imports, which indicates that there is some form of obfuscation going on to conceal the malware’s true purpose and functionality. ## First Stage Loader This first loader works by XOR decrypting at runtime both the second stage malware, and an additional loader shellcode, which loads the final stage payload. It then stores a pointer to the decrypted loader shellcode in the register edx, that was previously made executable using VirtualProtect. Next, it pushes the parameters to be passed to the loader function (consisting of a pointer to the decrypted second stage payload and a filepath to the injection target) on to the stack before executing it with a call edx instruction. ----- ## Second Stage Loader The second stage loader performs the process injection to load the final stage payload into memory. In this case, it used a process hollowing but not really approach to injecting the VIDAR binary into an AppLaunch.exe process. The process injection method uses the following sequence of API calls: ``` NtCreateUserProcess VirtualAlloc VirtualAllocEx WriteProcessMemory ResumeThread ``` Firstly, NtCreateUserProcess is called with the following arguments to spawn the process injection target in a suspended state. ----- ``` NtCreateUserProcess is an undocumented function, however more information about this ``` [function can be found here, and has been well documented by security researchers. For the](https://captmeelo.com/redteam/maldev/2022/05/10/ntcreateuserprocess.html) purposes of this loader, two important arguments are passed: ``` CreateThreadFlags, which is set to 0x01, and corresponds to starting the process in a ``` suspended state. ``` ProcessParameters, which is a RTL_USER_PROCESS_PARAMETERS structure, and within it ``` the image path C:\Windows\Microsoft.NET\Framework\v4.0.30319\AppLaunch.exe is provided. Next, the loader calls both VirtualAlloc and VirtualAllocEx to allocate a region in the memory space of the target process for the final payload to be injected. **VirtualAlloc Arguments** **VirtualAllocEx Arguments** As per the documentation for these functions, both calls pass in the same arguments. The only difference being that VirtualAlloc is not provided a lpAddress pointer, which results in the function returning a pointer to the allocated memory region, whereas the hProcess argument provided to VirtualAllocEx is 0x009C. Aside from those differences, the arguments provided to both functions are the same: ``` dwSize: 0x67000, which corresponds to 421888 bytes. flAllocationType: 0x03000, which corresponds to both committing and reserving the ``` address range in one step. ``` flProtect: 0x40, which corresponds to read, write and execute (RWX) permissions. ``` ----- These API calls serve to allocate a region in memory for the target AppLaunch.exe process that is readable, writable and executable, which allows the loader to finally write the bytes for the finaly payload into this memory region within the target process using ``` WriteProcessMemory. Finally, the injected process is then resumed from its suspended state ``` using ResumeThread, which allows it to execute the injected payload. ## Dumping the Injected Payload Dumping the injected payload was straight forward using x32dbg. All that was needed was a breakpoint to be set to pause execution when the malware reaches the WriteProcessMemory call. ``` bp WriteProcessMemory BOOL WriteProcessMemory( [in] HANDLE hProcess, [in] LPVOID lpBaseAddress, [in] LPCVOID lpBuffer, [in] SIZE_T nSize, [out] SIZE_T *lpNumberOfBytesWritten ); ``` **WriteProcessMemoryArguments** The arguments passed to WriteProcessMemory correspond to the following: ``` hProcess: 0x009C, which is the same process handle passed into the previous VirtualAllocEx function call. lpBaseAddress: 0x00400000, which corresponds to the image base address in which ``` the process memory is written. ``` lpBuffer: 0x02EA0000 nSize: 0x67000, which corresponds to the same 421888 bytes. ``` The argument of interest is lpBuffer, which is the pointer to the memory region containing the bytes to be written to the memory space of the new process. ----- As shown, this memory region starts with a MZ header and DOS string, which means this memory region must contain the binary that is being injected into AppLaunch.exe. The final stage executable payload can then be retrieved by dumping the memory region to disk. ## Realigning the Dumped PE When viewing the dumped executable in PEBear, or CFF Explorer, both programs were unable to determine the presence of any imports used by the binary. This is actually because the PE recovered from memory was in a mapped format. This caused a misalignment of section offsets within the raw executable on disk and therefore resulted in a misaligned import address table (IAT). [This video explains the concept far better than I can.](https://www.youtube.com/watch?v=WthvahlAYFY) Fortunately, we can edit the section table to unmap the sections within the executable and realign the IAT. By setting the raw address offsets to be equivalent to the virtual address offsets, and modifying the section sizes accordingly. ----- Now the executable has been correctly aligned, the module and function imports are now readable. Since we now have an unmapped exectable, it is possible to reverse engineer and analyze the resulting payload. In this case, the reconstructed executable is written in C++. ## VIDAR Infostealer Analysis Once the dumped payload has been realigned and otherwise fixed to become a valid portable executable, the second stage executable has the following characteristics: **MD5: 47a6959ac869f65dd31e65b1c80fa8b2** **SHA1: f9d9ecf59523c202bca9ac4364b2a2042f116f32** **SHA256: 1521e9e7b06676a62e30e046851727fe4506bdf400bcf705a426f0f98fba5701** **Compiled Timestamp: Mon Dec 19 12:33:40 2022 UTC** **Compiler: Microsoft Visual C/C++** **Linker: Microsoft Linker 10.0 - (Visual Studio 2010)** ### Encrypted Strings & Module Imports The VIDAR malware stores some of its strings, and module imports in a base64-encoded, RC4 encrypted format. By combining the different functions in the binary, along with the decrypted and decoded strings, we arrive at a full list of browser extensions targeted by the malware. These are mainly cryptocurrency wallets, but also include two factor authentication (2FA) extensions, and other password managers. Before doing anything else, VIDAR first calls a built-in routine to base64-decode and RC4 decrypt each string before writing it into a memory region. A pointer to each string and module import can then be referenced by the malware to use them ----- The malware leverages the BCryptDecrypt API call to decode base64, and a custom-coded RC4 decryption function. **Cryptocurrency wallets and 2FA browser extensions and applications targeted by** **VIDAR** ----- ``` TronLink MetaMask BinanceChainWallet Yoroi NiftyWallet MathWallet Coinbase Guarda EQUALWallet JaxxLiberty BitAppWallet iWallet Wombat MewCx GuildWallet RoninWallet NeoLine CloverWallet LiqualityWallet Terra_Station Keplr Sollet AuroWallet PolymeshWallet ICONex Harmony Coin98 EVER Wallet KardiaChain Trezor Password Manager Rabby Phantom BraveWallet Oxygen (Atomic) PaliWallet BoltX XdefiWallet NamiWallet MaiarDeFiWallet WavesKeeper Solflare CyanoWallet KHC TezBox Temple Goby Authenticator Authy EOS Authenticator GAuth Authenticator Tronium Trust Wallet ``` ----- ``` Exodus Web3 Wallet Braavos Enkrypt OKX Web3 Wallet Sender Hashpack Eternl GeroWallet Pontem Wallet Petra Wallet Martian Wallet Finnie Leap Terra Microsoft AutoFill Bitwarden KeePass Tusk KeePassXC-Browser Bitwarden Ethereum\Ethereum\ Electrum\Electrum\wallets\ ElectrumLTC\Electrum-LTC\wallets\ Exodus\exodus\conf.json,window-state.json \Exodus\exoduswallet\passphrase.json,seed.seco,info.seco ElectronCash\ElectronCash\wallets\default_wallet MultiDoge\MultiDoge\multidogewallet Jaxx_Desktop_Old\jaxx\Local Storage\file__0localstorage Binance\Binance\app-store.json Coinomi\Coinomi\wallets\ *wallets *config wallet_path SOFTWARE\monero-project\monero-core,\Monero\ ``` Also encrypted in the binary are the SQL queries used to harvest data stored in web browsers: **SQL queries used by VIDAR to harvest browser data** ``` SELECT origin_url, username_value, password_value FROM logins SELECT name, value FROM autofill SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted FROM credit_cards SELECT target_path, tab_url from downloads SELECT url FROM urls SELECT HOST_KEY, is_httponly, path, is_secure, (expires_utc/1000000)-11644480800, name, encrypted_value from cookies ``` In addition, one of the encrypted strings, C:\ProgramData\ is the staging directory used by the malware when it downloads additional libraries and stages data for exfiltration. This staging directory appears to be consistent across all VIDAR samples. ----- ### Retrieving C2 Servers The malware stores its C2 servers in an unencrypted format within the binary: ``` hxxps://t[.]me/traduttoretg hxxps://steamcommunity[.]com/profiles/76561199445991535 hxxp://5.75.253[.]16:80 ``` Interestingly, the VIDAR malware leverages legitimate services to host C2 configuration data. For example, the Telegram and Steam profile links contain IP addresses, whereas the ``` 5.75.253[.]16 appears to be consistent with threat actor infrastructure. This way, the ``` malware operators can contiunously cycle C2 servers and have the malware beacon back to each new IP address so long as the social media profiles hosting the C2 IP address remain active. ----- This particular VIDAR sample uses the string grundic to identify where on the webpage the C2 address is, and grabs the string up until the ending | character. ### Initial C2 Callback ----- Once the malware has retrieved a C2 IP address from one of the social media profiles hardcoded within the binary, it then submits a HTTP GET request containing the profile ID of the affiliate. Since the VIDAR malware is sold as an infostealer-as-a-service where the [cybercriminal gains access to a control panel to configure and generate the malware, this ID](https://any.run/malware-trends/vidar) is used to retrieve the configuration data set by the VIDAR customer. In this sample, the profile ID is 1375. **VIDAR configuration retrieved** ``` 1,1,1,1,1,36bfd46626a0b531909b016919dd1fbd,1,1,1,1,0,Default;%DOCUMENTS%\;*.txt;50;tr ue;movies:music:mp3;desktop;%DESKTOP%\;*.txt:*.doc:*.docx:*.xlsx:*.xlsm:*.xls:*.pptx; 950;true;movies:music:mp3:exe; ### Downloading Additional Libraries ``` To be able to perform its full credential harvesting tasks, the VIDAR malware must download additional DLL libraries to extend its capability. For example, to interact with web browsers or use SQLite3. In previous samples, the download of these additional libraries was achieved by sending a HTTP GET request to the C2 server for a ZIP file named with random alphanumeric characters. In an apparent change of technique, or configuration, this sample retrieves the additional libraries by downloading a resource from the C2 server named update.zip. Nevertheless, once the ZIP file containing the DLLs is downloaded, it is extracted and the DLL binaries are saved to the C:\ProgramData staging directory. The resource update.zip contained the following DLLs: ``` MD5 (freebl3.dll) = ef2834ac4ee7d6724f255beaf527e635 MD5 (libcurl.dll) = 37f98d28e694399e068bd9071dc16133 MD5 (mozglue.dll) = 8f73c08a9660691143661bf7332c3c27 MD5 (msvcp140.dll) = 109f0f02fd37c84bfc7508d4227d7ed5 MD5 (nss3.dll) = bfac4e3c5908856ba17d41edcd455a51 MD5 (softokn3.dll) = a2ee53de9167bf0d6c019303b7ca84e5 MD5 (sqlite3.dll) = e477a96c8f2b18d6b5c27bde49c990bf MD5 (vcruntime140.dll) = 7587bf9cb4147022cd5681b015183046 ``` ----- ## Data Exfiltration The harvested data is then sent back to the C2 server using a HTTP POST request. ----- **HTTP POST body** ``` ------1531306219445135 Content-Disposition: form-data; name="profile" 1375 ------1531306219445135 Content-Disposition: form-data; name="profile_id" 1700 ------1531306219445135 Content-Disposition: form-data; name="hwid" d8d914bc22c31291311131-90059c37-1320-41a4-b58d-816d-806e6f6e6963 ------1531306219445135 Content-Disposition: form-data; name="token" 36bfd46626a0b531909b016919dd1fbd ------1531306219445135 Content-Disposition: form-data; name="file" UEsDBBQAAgAIAMSYl1XqxfupygAAAJMB...[truncated base64-encoded ZIP file] ------1531306219445135- ``` ----- Interestingly, the token 36bfd46626a0b531909b016919dd1fbd matches the string contained within the initial config downloaded from the C2 server. The data harvested from the host is stored within the ZIP file in the POST request body. **Directory structure of the ZIP file** ``` /History/Mozilla Firefox_qldyz51w.default.txt /Cookies/Google Chrome_Default.txt /History/Google Chrome_Default.txt /passwords.txt /information.txt /Files/Default.zip /Files/desktop.zip /screenshot.jpg ``` It is important to note that this is not an exhaustive list of what the ZIP file exfiltrated from every system will look like. It will depend on both the stealer configuration set by the threat actor during the payload generation stage, and the software present on the compromised system. For example, the sample analyzed in this writeup included routines for stealing Discord tokens, data from Telegram and even FTP and SCP clients. ### Cleanup Operations Once the data has been succesfully harvested and exfiltrated, the malware then deletes itself and any created files from the host with the following command: ``` "C:\Windows\System32\cmd.exe" /c timeout /t 6 & del /f /q "C:\Windows\Microsoft.NET\Framework\v4.0.30319\AppLaunch.exe" & exit ``` ----- -----