Malware Analysis [#4] —Eternity Project — Eternity Stealer

https://www.flaticon.com/free-icons/infinity

The Eternity Project is a malware toolkit sold as a malware-as-a-service (MaaS) that offers customize malware features beside the core functionalities, the threat actors distributes their service through an anonymous Tor marketplace and Telegram channels as “Eternity Group” . Each malware item in the toolkit is individually priced:

  • Eternity Stealer — $260 annual subscription.
  • Eternity Miner — $90 annual subscription.
  • Eternity Worm — $390.
  • Eternity Ransomware — $490.
  • Eternity Clipper — $110.
  • Eternity DDoS Bot — (Still in development).

I would like to mention that this is a detailed technical analysis so it will be a bit long 😅, and I hope you find it beneficial, and if you have any notes please consider contacting me or comment on the article, now let’s start analyzing Eternity Stealer.

Eternity Stealer Malware:

I got the sample of the malware from “Malware Bazaar” and it’s the first sample seen on the site:

General Info:

The malware sample is .NET 32bit executable heavily obfuscated 😡 so our task will be will be a bit difficult, after using de4dot things were cleaned a little but still full of obfuscation so I had to work on it more:

before using de4dot
After using de4dot

through out the code there are two methods (DS and SSD) that are being called repeatedly to deobfuscate strings, and when looking at the class that these methods belongs to, we find that it has methods to handle obfuscation and deobfuscation, methods that point to obfuscated and non-obfuscated strings, and others:

deobfuscation functions
pointers functions

Analyzing Obfuscation Methods:

DS Method:

  • Takes two string arguments.
  • Remove the first and last character from second string argument then decode from base64 and the result will be used as a secret key in the AES decryption.
  • Decode the first string argument from base64 and use it as IV in the AES decryption.
  • After decryption it returns UTF8 string.

SSD Method::

  • Takes a string and long arguments.
  • Convert the string argument to char array.
  • Use a for loop to convert both arguments to and int32 and then check if the two argument Combined are between 0 and 256 and if it is it will sub first argument from the second argument and convert it to char, then convert uppercase char to lowercase and lowercase to uppercase.
  • Reverse the char array and return it as a string.

SSE Method::

This method is the reverse of “SSD” method which mean that it’s an obfuscation class:

Main Method:

The main method start by decrypting and deobfuscating a string using methods (DS,SSD) and the result from them is “quwqsgpmly”, this string will be used to create a (name object/Mutex) by using a method called “PerformMutexCheck()”. This method will decrypt and deobfuscate a string to get (“”) double quotes then get command line arguments using “GetCommandLineArgs()” and convert them to lower case and use the double quotes as separator argument with command line string in “string.Join()”.

Then it decrypt and deobfuscate a string again to get “— debug” string and use it in “string.Contain()” to see if it’s was executed with debug string , and if it failed, it will create a Mutex with the string value “quwqsgpmly”, and if creating the mutex failed it will exit.

Note: the feature of Anti-Repeat is not a core functionality, it’s added based on buyer choice.

Then it calls “PerformSelfDestruct()” method and again it performs the same check used in the previous method to see if it was executed with (“ — debug”) string, if not it will continue to prepare a self destruct by using (“AppDomain .CurrentDomain”) class.

The application domain is an isolated environment where applications execute and it’s represented by AppDomain object, and it help provide isolation, unloading, and security boundaries for executing managed code.

The CurrentDomain property is used to obtain an AppDomain object that represents the current application domain or thread. By getting the current domain it set up three events and if one of these events occurs it will call “HandleSelfDestruct()” function, the events are:

  • UnhandledException (Occurs when an exception is not caught).
  • ProcessExit(Occurs when the default application domain’s parent process exits).
  • DomainUnload(Occurs when an AppDomain is about to be unloaded).

The (“HandleSelfDestruct”) function checks if the file exist in the path and if it is, it will start a new process with argument:

  • chcp 65001 .
  • ping 127.0.0.1 .
  • DEL /F /S /Q /A \”{0}” “C:\path\to\file.exe” .
  • CreateNoWindow.
  • UseShellExecute

The chcp is used to to switch the character encoding in the Windows console to UTF-8. While ping used here just as sleeping method and this is the only assumption I have for it, then it will delete the file and below is description of the arguments used with “del” command:

cme.exe
procmon.exe

Next it sets three properties of “ServicePointManager” Class :

  • Expect100Continue: Gets or sets a Boolean value that determines whether 100-Continue behavior is used. The HTTP 100 Continue informational status response code indicates that everything is OK and that the client should continue with the request or ignore it if it is already finished. The malware here gave it “1“ by getting the size of float which is 4 bytes then subs 3 from it, the result is 1 which means true.
  • DefaultConnectionLimit: Gets or sets the maximum number of concurrent connections allowed by a “ServicePoint” object. The value of this property is 9999, also by getting the size of float and add 9995 to it.
  • SecurityProtocol: Gets or sets the security protocol used by the “ServicePoint” objects managed by the “ServicePointManager” object. The security type protocol is “Tls12” which has the value 3072 as mentioned in MS documents, the same process again get the size of float then add 3068.

Note:through the malware you will face the technique of using the size of float to set up integer values.

After that it start to add delegates to delegates. A delegates in C# contains the reference to several methods and you can call them when needed. So you can create number of methods as you need and attach it to delegate, and at runtime, an event gets fired and delegate dynamically call the functions and show the result. Here we have 4 delegates:

  • HandleAccount.
  • HandleCookie.
  • HandleAutoFill.
  • HandleCreditCard.

HandleAccount delegate:

The HandleAccount delegate is able to get or set:

  • Hostname.
  • Username.
  • Password.
  • Application.
  • Profile.

HandleCookie delegate:

The HandleCookie delegate is able to get or set:

  • Name.
  • Path.
  • Value.
  • HostKey.
  • ExpiresUTC.
  • Application.
  • Profile.

HandleAutoFill delegate:

The HandleAutoFill delegate is able to get or set:

  • Name.
  • Value.

HandleCreditCard delegate:

The HandleCreditCard delegate is able to get or set:

  • Number.
  • Holder.
  • CardName.
  • ExpYear.
  • ExpMonth.
  • Application.
  • Profile.

After that it calls a method named “Create” that takes 2 bool arguments and the result of this method will be stored in an array named “array”. Before we got into the method we can see from the if statement below it that array length should be bigger than 10240 as seen in the screenshot:

Create Method:

At the beginning of this method it start to collect these information about the machine:

  • Executable Path.
  • Start Date.
  • Stub Version.
  • Stub Location.
  • Username.
  • ComputerName.
  • OSName.
  • UILang.
  • Hardware.
  • CPUName.
  • GPUName.
  • RAMAmount.
  • DiskSize.
  • Model.
  • Manufacturer.
  • ScreenResolution.
  • Geolocation.

After that it uses a memory stream that was created before collecting the data to write it to a file named “Information.txt” as bytes.

Then creates a list of objects type thread, and adds 9 threads to the list with their delegates that represent the methods to be invoked when each thread start:

Below is what each thread is doing without following the workflow between threads, also the names of the threads was given to it by the malware writer:

Thread[0] (System)

1- Enumerate Vault credentials:

  • Using “vaultcli.dll” which is a command-line equivalent to the Credential Manager, the functions called from this dll:
  • Defines if it will use VAULT_ITEM_WIN7 or VAULT_ITEM_WIN8 struct.
  • The data collected is:

- Windows Secure Note.

- Windows Web Password Credential

- “Windows Credential Picker Protector.

- Web Credentials.

- Windows Credentials.

- Windows Domain Certificate Credential.

- Windows Domain Password Credential.

- Windows Extended Credential.

  • The result will be written in a file named “System\Vault.txt”.

2- Enumerate “Credential Manger” credentials:

Credential Manger is a locker where Windows stores log-in credentials, usernames, passwords, and addresses. The informations collected will be stored in file named “System\Credman.txt” and it is:

- Windows Credentials.

- Certificate-Based credentials.

- Generic Credentials.

3- Enumerate Network Credentials:

  • Executing the command (“netsh wlan show profile | findstr All”) to list profiles configured on the system.
  • Executing the command (“netsh wlan show profile name=\”) if the previous step succeeded.

4- Take a screenshot and name it “Screenshot.png”.

Thread[1] (Gaming)

1- Enumerate Steam Files:

  • Get Steam directory by opening registry key “Software\Valve\Steam”.
  • If it succeed it will retrieves the value associated with the specified name “UvgcoRcvj”.
  • Get a file list from the directory with search pattern “ssfn*” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file data in the Steam directory with specification in the previous step will be stored in “Gaming\Steam\<file name>” file.
  • Get a file list from the directory with search pattern “config\*vdf” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file in the Steam directory with specification in the previous step will be stored in “Gaming\Steam\eqphki <file name>” file.

2- Enumerate Twitch Files:

  • Get an array of directories in the current system with search pattern “Twitch*” and use a search option with value (0) to includes only the current directory in a search operation.
  • Get a file list from each directory with search pattern “Electron9\Cookies” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored in “Gaming\<directory name>\Fmfduspo:\<file name>” file.

3- Enumerate OBS Files:

  • Set up path to the OBS directory “C:\Users\<user>\AppData\Roaming\obs-studio\basic\profiles”.
  • Get a file list from the directory with search pattern “*.*” and use a search option with value (1) to Includes the current directory and all its subdirectories in a search operation. This option includes reparse points such as mounted drives and symbolic links in the search.
  • Each file with the specification in the previous step will be stored in the “Gaming\ObsStudio\<directory name>\<file name>” file.
  • Set up path to the OBS directory “C:\Users\<user>\AppData\Roaming\slobs-client\Local Storage\leveldb”.
  • Get a file list from the directory with search pattern “*.|??” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored in the “Gaming\StreamlabsOBS\Local Storage\leveldb\<file name>” file.

Thread[2] (FTP)

1- Enumerate FTP FileZilla Files:

  • search for these files “sitemanager.xml” “recentserver.xml” in this path “C:\Users\<user>\AppData\Roaming\Filezilla\” .
  • The data from these files will be stored in “FTP\FileZilla\Servers.txt”.

2- Enumerate FTP WinSCP Credentials:

  • Open registry subkey “Software\Martin Prikry1\WinSCP 2\Sessions” to get the session.
  • Get the values of “HostName”, “UserName” and “Password” for each session.
  • Decrypt the password for each session.
  • The credentials will be stored in “FTP\WinSCP\Servers.txt”.

3- Enumerate CoreFTP Credentials:

  • Open registry subkey “Software\FTPWare\CoreFTP\Sites” to get sites.
  • Get the values of “Host”, “Port”, “User” and “PW” for each site.
  • Decrypt the password with key “hdfzpysvpzimorhk”.
  • The credentials will be stored in “FTP\CoreFTP\Servers.txt”.

4- Enumerate Snowflake Credentials:

  • Get file “session-store.json” from Snowflake path “C:\Users\<user>\snowflake-ssh\” and parse it to get the values of hosts, ports, usernames, passwords and folders, the password in snowflake stored in clear text.
  • The credentials will be stored in “FTP\Snowflake\Servers.txt”.

Thread[3] (VPN)

1- Enumerate NordVPN Credentials:

  • Get path to NordVPN Directory “C:\Users\<user>\AppData\Local\NordVPN”.
  • Search for “user.config” file in all directories.
  • Decrypt the data from base64.
  • The credentials will be stored in “VPN\NordVPN\Account.txt” file.

2- Enumerate EarthVPN Credentials:

  • Open registry key “Software\EarthVPN”.
  • Get “SavePass” value.
  • The credentials will be stored in “VPN\EarthVPN\Account.txt” file.

3- Enumerate WindscribeVPN Credentials:

  • Open registry key “Software\Windscribe”.
  • Get subkey names (Installer, Windscribe, Windscrib2).
  • Get “userId ”, “authHash” values form “Windscribe” subkey.
  • Get “userId ”, “authHash” values form “Windscribe2” subkey.
  • The credentials will be stored in “VPN\WindscribeVPN\Account.txt” file.

4- Enumerate AzireVPN Credentials:

  • Get path to AzireVPN directory “C:\Users\<user>\AppData\Local\AzireVPN”.
  • Search for file “token.txt” and read data from the file.
  • The credentials will be stored in “VPN\AzireVPN\Account.txt” file.

Thread[4] (Browsers)

1- Enumerate Browsers Information:

  • Browsers:

( Chrome - FireFox - Cyberfox - K-Meleon - Pale Moon - BlackHawk - Waterfox- IceCat - SeaMonkey - SlimBrowser - Thunderbird - PostboxApp(Email app)- 360Chrome - Avast Secure Browser - 7Star - Amigo - Brave-Browser- Citrio - CentBrowser - Chedot - Blisk - GhostBrowser - Chromodo- CoCoc - Comodo - Coowon - Elements Browser - Epic Privacy Browser- Chormium - Chrome SxS - Chrome Beta - Kinza - Iridium - Kometa- Atom - ChromePlus - Maxthon3 - Edge - Nichrome - Opera GX- Opera Stable - Orbitum - QIP Surf - UCBrowser - Xpom - Xvast- SuperBird - QQBrowser - Sputnik - Torch - Uran - Vivaldi - Yandex Browser -liebao - SalamWeb)

  • Enumerated Information:

( Profiles - Passwords - Cookies - Credit Cards - Tokens - AutoFill - Bookmarks- Extension Files).

Thread[5] (Messengers)

1- Enumerate Telegram Credentials:

  • Get Telegram process name.
  • Get Telegram directory “C:\Users\<user>\AppData\Roaming\Telegram Desktop\tdata” if it did not find it it will open registry key “Software\Classes\tdesktop.tg\DefaultIcons1” and get directory path.
  • Get a file list from the directory with search pattern “*s” and use a search option with value (0) to includes only the current directory in a search operation.
  • Get a list of all directories.
  • Get a file list from each directory with search pattern “map?” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file found will be written as “Messengers\Telegram\<file name>” file .

2- Enumerate Discord Credentials:

  • Get two sets of regex:
  • Create array list with (Discord — Discord PTB — Discord Canary)
  • Get file “C:\Users\<user>\AppData\Roaming\Discord\Local State” which holds an encrypted key, and convert it from base64.
  • Get directory “C:\Users\<user>\AppData\Roaming\Discord\Local Storage\leveldb”.
  • Get a file list from the directory with search pattern “*.l??”.
  • Get directory “C:\Users\<user>\AppData\Roaming\Discord PTB\Local Storage\leveldb” and do the same steps above.
  • Get directory “C:\Users\<user>\AppData\Roaming\Discord Canary\Local Storage\leveldb” and do the same steps above.
  • The credentials will be stored in “Messengers\Discord\Tokens.txt” file.

3- Enumerate Pidgin Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\.purple”.
  • Get file “accounts.xml”.
  • The credentials will be stored in “Messengers\Pidgin\Accounts.txt” file.

4- Enumerate Outlook Credentials:

  • Open Subkeys:

- “Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676”.

- “Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\ Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676”.

- “Software\Microsoft\Windows Messaging Subsystem\Profiles\9375CFF0413111d3B88A00104B2A6676”.

- “Software\Microsoft\Office\16.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676”.

  • Get (“IMAP Password”, “POP3 Password”, “HTTP Password”, “SMTP Password”) and decrypt the passwords.
  • The credentials will be stored in “Messengers\Outlook\Accounts.txt” file.

5- Enumerate FoxMail Credentials:

  • Open subkey “SOFTWARE\Classes\Foxmail.url.mailto\Shell\open\command” to get FoxMail directory path.
  • Get file “C:\FoxMail7.2\Storage” to enumerate credentials.
  • Decrypt credentials.
  • The credentials will be stored in “Messengers\FoxMail\Accounts.txt” file.

6- Enumerate MailBird Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Local\Mailbird\Store”.
  • Get file “Store.db” from the directory, which is in SQLite format.
  • Get Table named “OAuth2Credentials” from the file for enumeration.
  • The credentials will be stored in “Messengers\MailBird\Accounts.txt” file.

7- Enumerate Viber Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\ViberPC”.
  • Enumerate directory and subdirectoies for files with search pattern “*.db”.
  • The files will be stored as “Messengers\Viber\<directory name>\<file name>”.

8- Enumerate WhatsApp Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\WhatsApp\Local Storage\leveldb”.
  • Enumerate directory and subdirectoies for files with search pattern “*.|??”.
  • The files will be stored as “Messengers\WhatsApp\Local Storage\leveldb\<file name>”.

9- Enumerate Signal Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Signal”.
  • Get file “config.json
  • Get subdirectory “sql”.
  • Config file will be stored as “Messengers\Signal\config.json”.
  • Database file will be stored as “Messengers\Signal\sql\db.sqlite”.

10- Enumerate RamBox Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\rambox”.
  • Get file “config.json”.
  • Get subdirectory “Partitions”.
  • Config file will be stored as “Messengers\Rambox\config.json”.
  • For each Partition directory it get “Cookies” file
  • Cookies files will be stored as “Messengers\Rambox\<directory name>\Cookies”.
  • Get path to directory “C:\Users\<user>\AppData\Roaming\rambox\Partitions\Local Storage\leveldb”.
  • Enumerate directory with search pattern “*.|??”.
  • Each file will be stored as “Messengers\Rambox\Partitions\<directory name>\Local Storage\leveldb\<file name>”.

Thread[6] (Wallets)

1- Enumerate Binance Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Binance”.
  • Get a file list from the directory with search pattern “*-stor*.json” and use a search option with value (0) to includes only the current directory in a search operation.
  • The search pattern will get “app-store.json” and “simple-storage.json”.
  • The credentials will be stored as “Wallets\Binance\<file name>”.

2- Enumerate Monero Credentials:

  • Open registry subkey “SOFTWARE\ monero-project\monero-core”.
  • Get wallet directory path from the subkey.
  • Get all files with search pattern “*.*” .
  • Files will be stored as “Wallets\MoneroCore\<directory name>\<file name>”.

3- Enumerate Bitcoin Credentials:

  • Open registry subkey “SOFTWARE\ Bitcoin\Bitcoin-Qt”.
  • Get wallet directory path.
  • Get files with search pattern “*wallet*dat” .
  • Files will be stored as “Wallets\BitcoinCore\<file name>”.

4- Enumerate Dash Credentials:

  • Open registry subkey “SOFTWARE\Dash\Dash-Qt”.
  • Get wallet directory path.
  • Get files with search pattern “*wallet*dat” .
  • Files will be stored as “Wallets\DashcoinCore\<file name>”.

5- Enumerate Doge Credentials:

  • Open registry subkey “SOFTWARE\Dogecoin\Dogecoin-Qt”.
  • Get wallet directory path.
  • Get files with search pattern “*wallet*dat” .
  • Files will be stored as “Wallets\DogecoinCore\<file name>”.

6- Enumerate Litecoin Credentials:

  • Open registry subkey “SOFTWARE\Litecoin\Litecoin-Qt”.
  • Get wallet directory path.
  • Get files with search pattern “*wallet*dat” .
  • Files will be stored as “Wallets\LitecoinCore\<file name>”.

7- Enumerate Electrum Credentials:

  • Search for directory with search pattern “*Electr*
  • Search each directory for file “@lkcfd
  • If it finds the file it will get the value of “recently_open” element.
  • Each file will be stored as “Wallets\<directory name>\<file name>”.

8- Enumerate Exodus Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Exodus\exodus.wallet\”.
  • Search for file “exodus.conf.json”.
  • File will be stored as “Wallets\Exodus\exodus.wallet\exodus.conf.json”.
  • Get a file list from the directory with search pattern “*.seco” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file will be stored as “Wallets\Exodus\exodus.wallet\<file name>”.

9- Enumerate Atomic Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\atomic\Local Storage\leveldb”.
  • Get a file list from the directory with search pattern “*.|??”.
  • Each file will be stored as “Wallets\Atomic\Local Storage\leveldb\<file name>”.

10- Enumerate TONWallet Credentials:

  • Checks if “SOFTWARE\TONWallet” registry exist.
  • Search for “data” directory.
  • Look for “tonlib_log.txt” file in it.
  • Checks if “db” directory exist in TON Wallet directory.
  • Files in “db” directory will be stored as “Wallet\TonWallet\<file name>”.
  • Checks if “lib” directory exist in TON Wallet directory.
  • Files in “lib” directory will be stored as “Wallet\TonWallet\<file name>”.
  • Get file name “salt”.
  • The file will be stored as “Wallet\TonWallet\salt”.

11- Enumerate Jaxx Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\com.liberty.jaxx\IndexedDB\file_0.indexeddb.leveldb.
  • Get all files in the directory and store it as “Wallets\JaxxClassic\<file name>

12- Enumerate Coinomi Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Local\Coinomi\Coinomi\wallets.
  • Get a file list from the directory with search pattern “*.wallet” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file in the directory will be stored as “Wallets\Coinomi\<file name>”.

13- Enumerate Daedalus Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Daedalus Mainnet\wallet”.
  • Get a file list from the directory with search pattern “*.sqlite” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored in the “Wallets\Daedalus\<file name>” file.

14- Enumerate Zcash Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Zcash”.
  • Get a file list from the directory with search pattern “*wallet*dat” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored in the “Wallets\Zcash\<file name>” file.

15- Enumerate Guarda Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Guarda\Local Storage\leveldb”.
  • Get a file list from the directory with search pattern “*.|??” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored in the “Wallets\Guarda\Local Storage\leveldb\<file name>” file.

16- Enumerate Wasabi Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\WalletWasabi\Client\Wallets”.
  • Get a file list from the directory with search pattern “*.json” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored as “Wallets\Wasabi\<file name>” file.

Thread[7] (PasswordManagers).

1- Enumerate BitWarden Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\Bitwarden”.
  • Get a file list from the directory with search pattern “data*.json” and use a search option with value (0) to includes only the current directory in a search operation.
  • Each file with the specification in the previous step will be stored as “PasswordManagers\BitWarden\<file name>” file.

2- Enumerate KeePass Credentials:

  • Get path to file “C:\Users\<user>\AppData\Roaming\KeePass\KeePass.config.xml” which is for versions before “2.51.1”.
  • Load xml file and get element “ConnectionInfo” which holds path to the database file “Database.kdbx”.
  • Store the file as “PasswordManagers\KeePass2\databases”.
  • get element “KeyFilePath” which holds path to the key file.
  • Store the file as “PasswordManagers\KeePass2\keys”.
  • Get path to file “C:\Users\<user>\AppData\Local\KeePassXC\keepassxc.ini”.
  • Initialize regex string “LastDatabases=(.*?)\n” to parse some information.
  • Store the data as “PasswordManagers\KeePassXC\<filename>”.

3- Enumerate NordPass Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Roaming\NordPass”.
  • Get a file list from the directory with search pattern “*.conf”.
  • Each file with the specification in the previous step will be stored as “PasswordManagers\NordPass\<file name>” file.

4- Enumerate 1Password Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Local\1Password\data”.
  • Get a file list from the directory with search pattern “*.sqlite”.
  • Each file with the specification in the previous step will be stored as “PasswordManagers\1Password\data\<file name>”.

5- Enumerate RoboForm Credentials:

  • Get path to directory “C:\Users\<user>\AppData\Local\RoboForm\Profiles”.
  • Get a file list from the directory with search pattern “*.rfo”.
  • Each file with the specification in the previous step will be stored as “PasswordManagers\RoboForm\<file name>”.

Thread[8] (Grabber)

The Grabber thread will create a 20 search pattern:

- scan - electrum - metamask - wallet - phrase - recover - secrete - security

- code - seed - nft - backup - coin - key - pass - парол - .txt - .kdbx

- . rdp - .pdf .

if any of the search pattern match a file in these locations:

  • Desktop.
  • Documents.
  • AppData\Roaming\DropBox.
  • AppData\Roaming\OneDrive.

it will be stored as:

Grabber\<Drive name>\Users\<user>\<path>\<file name>

Back to Main method:

The “Create” method results will be stored in an array variable named “array”, saving this variable and throw it in hex editor I did find that it’s zip file. Unzipping the file we get all the informations collected.

After that it create and object named “stringBuilder” with onion domain value: http://lightnogu5owjjllyo4tj2sfos6fchnmcidlgo6c7e6fz2hgryhfhoyd.onion/stealer/1866445032” and then it start to append the information gathered from the victim machine to the onion domain, and the final result will be:

http://lightnogu5owjjllyo4tj2sfos6fchnmcidlgo6c7e6fz2hgryhfhoyd.onion/stealer/1866445032?pwds=2&cards=0&wlts=5&files=658&username=<base64 username>&comp=<base64 machine name>&ip=<base64 ip>&country=<base64 country>&city=<base64 city >&tag=Default&domains=<base64 domains>&ad=<base64 active directory>

After that it initialize web client to start uploading the collected data

And this was the analysis of the Eternity Stealer Malware sample, hope you find it informative and beneficial, next will be another sample from the Eternity project, Thanks for reading 😀.

--

--

Malware Analyst & Reverse Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store