eSinerji Mühendislik - Teklif talebi - Elektrik malzemeleri (Part 2)
Continuing from part 1, I extracted the injected byte array with the following recipe:
Regular_expression('User defined','\\$payloadData = \\(([0-9,]+)\\)',false,false,false,false,false,false,'List capture groups')
From_Decimal('Comma',false)
The resulting payload is a 32-bit MSVC executable with only a .text
section and high entropy, indicating compression or encryption.
Dynamic Analysis
First, I analysed the sample in a FLARE-VM sandbox, using WireShark to capture the C2 traffic.
After running it multiple times on a clean snapshot, I observed it attempting to communicate with over 50 different domains, some of which were clearly decoys. This behaviour appears consistent with the Formbook/XLoader malware families which blend requests towards the C2 server with up to 64 different decoy domains. Some of the domains were inactive at the time of the analysis and I wasn’t able to identify the real C2 server.
The sample sends both GET and POST requests with encrypted and base64-encoded data. The requests have the below headers, as well as “Origin” and “Referer” headers matching the URL.
| Name | Value |
|---|---|
| Accept | text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed‑exchange;v=b3;q=0.7 |
| Accept‑Encoding | gzip, deflate |
| Accept‑Language | en-US |
| Cache‑Control | no-cache |
| Connection | close |
| User‑Agent | Mozilla/5.0 (GNU/linux S.O.; rv:38.0) Gecko/20100101 Firefox/38.0 |
The user agent imitates an old Mozilla Firefox browser (version 38.0) running on Linux.
Additionally, the malware copied the Microsoft Edge “Web Data” SQLite database which contains autofill, address, and credit card data to the temporary file “%TEMP%\1U7G2-Ix5”.
No persistence artifacts were observed during the dynamic analysis.
Static Analysis
For the static analysis, I used Ghidra and enlisted the assistance of ChatGPT to break the encryption, after providing it with the exported program listing, decompiled C code, and Intel Hex dump.
First Stage
The malware defines seven functions, with the entry point being on offset 0x004026A0.
entry
The entry point builds a large state structure on the stack and repeatedly
calls FUN_00401090, changing a single byte selector before each call.
; ...
0040270b c7857dffffff00bc90cb MOV dword ptr [EBP + local_87],0xcb90bc00
00402715 89852dfcffff MOV dword ptr [EBP + local_3d7],EAX
0040271b c785d9fcffffc03b5440 MOV dword ptr [EBP + local_32b],0x40543bc0
00402725 c785ddfbffffe90cc81a MOV dword ptr [EBP + local_427],0x1ac80ce9
0040272f c745d5f9000000 MOV dword ptr [EBP + local_2f],0xf9
00402736 e855e9ffff CALL FUN_00401090
0040273b c745d588000000 MOV dword ptr [EBP + local_2f],0x88
00402742 e849e9ffff CALL FUN_00401090
00402747 c745d559000000 MOV dword ptr [EBP + local_2f],0x59
0040274e e83de9ffff CALL FUN_00401090
00402753 c745d5ed000000 MOV dword ptr [EBP + local_2f],0xed
0040275a e831e9ffff CALL FUN_00401090
; ...
FUN_00402600
size_t __cdecl FUN_00402600(const char *param_1)
This function is equivalent to the standard strlen function.
FUN_00402620
size_t __cdecl FUN_00402620(const wchar_t *param_1)
This function is equivalent to the standard wcslen function.
FUN_00402640
void __cdecl FUN_00402640(void *param_1, const void *param_2, size_t param_3)
This function is equivalent to the standard memcpy function.
FUN_00402670
void *__cdecl FUN_00402670(void *param_1, int param_2, size_t param_3)
This function is equivalent to the standard memset function.
FUN_00401000
void __cdecl FUN_00401000(uintptr_t *param_1)
The function writes a hardcoded buffer of 62 bytes to the given address.
; ...
0040100b c745c01bc5a2cd MOV dword ptr [EBP + local_44],0xcda2c51b
00401012 c745c4a242890b MOV dword ptr [EBP + local_40],0xb8942a2
00401019 c745c8b24e4e4e MOV dword ptr [EBP + local_3c],0x4e4e4eb2
00401020 c745cc4e890bb6 MOV dword ptr [EBP + local_38],0xb60b894e
00401027 c745d0dc054e4e MOV dword ptr [EBP + local_34],0x4e4e05dc
0040102e c745d4890bba4e MOV dword ptr [EBP + local_30],0x4eba0b89
00401035 c745d84e4e4ec5 MOV dword ptr [EBP + local_2c],0xc54e4e4e
0040103c c745dc0bb2750b MOV dword ptr [EBP + local_28],0xb75b20b
00401043 c745e0b6335ac5 MOV dword ptr [EBP + local_24],0xc55a33b6
0040104a c745e403ba4d03 MOV dword ptr [EBP + local_20],0x34dba03
00401051 c745e8b2c703ba MOV dword ptr [EBP + local_1c],0xba03c7b2
00401058 c745ecc51bb2cd MOV dword ptr [EBP + local_18],0xcdb21bc5
0040105f c745f08c44c71b MOV dword ptr [EBP + local_14],0x1bc7448c
00401066 c745f4b2a5aa7d MOV dword ptr [EBP + local_10],0x7daaa5b2
0040106d c745f88ec5ab13 MOV dword ptr [EBP + local_c],0x13abc58e
00401074 66c745fc8d00 MOV word ptr [EBP + local_8],0x8d
0040107a c645fe00 MOV byte ptr [EBP + local_6],0x0
; ...
In little endian, the function produces the following buffer:
1B C5 A2 CD A2 42 89 0B B2 4E 4E 4E 4E 89 0B B6
DC 05 4E 4E 89 0B BA 4E 4E 4E 4E C5 0B B2 75 0B
B6 33 5A C5 03 BA 4D 03 B2 C7 03 BA C5 1B B2 CD
8C 44 C7 1B B2 A5 AA 7D 8E C5 AB 13 8D 00
FUN_00401090
This function implements is the main dispatcher of the first stage.
Rather than receiving the state structure as a parameter, it searches
the caller’s stack for the marker 0x40543BC0 and combines the
selector with 0xCB90BC00 to choose the appropriate branch.
| Selector | Operation |
|---|---|
0x88 | Obtains a pointer into the current image |
0x59 | Stores the image size |
0xED | Recovers the original image base |
0x49 | Materialises an encrypted record |
0x5C | Derives a 20-byte key |
0x5A, 0xAD, 0x01, 0x8F | Implement the RC4 processing |
0xBC, 0x29, 0x44 | Walk the TEB/PEB loader structures to locate a DLL |
0x7A, 0xEF | Parse a PE export table and resolve an API |
0xB3 | Builds the temporary stub from FUN_00401000 |
0x05 | Executes the stub and decrypts the encrypted chunks |
0x24 | Transfers execution to the recovered stage |
Second Stage
The dispatcher first decrypts the complete 273408-byte packed stage with RC4 using the key “1D6A657F0236D3F98130C3D42FA90E164AF87EEA”. It then divides the buffer into 40 chunks and resets RC4 for every chunk using the key “9DCDD799A4C218B5F133FE98CE50CA0D2470444C”.
The recovered stage still contains encrypted functions, which are decrypted at runtime with a custom transform that combines RC4 with forward and backward adjacent-byte addition or subtraction.
Walking the PEB
The malware does not import any libraries but instead resolves functions by walking
the Process Environment Block (PEB) via the Thread Environment Block (TEB)1.
On 32-bit Windows, FS:[0x18] gives the address of the current TEB and the
PEB pointer is then read from offset 0x30 of the TEB structure.
; ...
004020c3 64a118000000 MOV EAX,FS:[0x18]
004020c9 8b4030 MOV EAX,dword ptr [EAX + 0x30]
; ...
From the PEB, the malware accesses the loader data at offset 0x0C and walks
the InLoadOrderModuleList at another offset of 0x0C. This list contains an
LDR_DATA_TABLE_ENTRY for each loaded DLL. It can then search the entries for a
library such as “ntdll.dll”, retrieve its base address, and manually parse its PE
export table to resolve the native API functions it needs (e.g., “NtAllocateVirtualMemory”).
Registration
The registration data contains the branch marker “XLNG:”, an eight-character bot ID, the version marker “8.9:”, the operating system, and a Base64-encoded victim ID:
XLNG:23BDFD508.9:Windows 10 Enterprise N x64:REVTS1RPUC00NzdRVDRBLWZsYXJl
The final field decodes to “DESKTOP-477QT4A-flare”, the hostname and username of the sandbox. Before transmission, the plaintext is RC4-encrypted, base64-encoded, and prefixed with “PKT2:”.2
Encryption
The second stage uses a custom reversible transform around RC4. Mode 0x7A performs
two adjacent-byte subtraction passes, RC4, and then repeats the subtraction passes,
while mode 0x66 uses addition and reverses the operation.3 The registration RC4
key recovered from this sample is “1E603A71E25C3A00BCA282C931545AC3839253F3”.
Junk Code Stub
The temporary stub written by FUN_00401000 is decoded by XORing its first 61 bytes
with 0x4E with the NULL byte being padding.
From_Hex('Space')
Take_bytes(0,61,false)
XOR({'option':'Hex','string':'0x4E'},'Standard',false)
To_Hex('Space',0)
Disassemble_x86('32','Full x86 architecture','16','0',true,true)
The resulting shellcode is a sum computation loop with 1935 iterations that always returns 0.
It is executed from the base of each encrypted chunk and replaced with the original bytes before RC4 processing.
00000000 55 PUSH EBP
00000001 8BEC MOV EBP,ESP
00000003 83EC0C SUB ESP,0000000C
00000006 C745FC00000000 MOV DWORD PTR [EBP-04],00000000
0000000D C745F8924B0000 MOV DWORD PTR [EBP-08],00004B92
00000014 C745F400000000 MOV DWORD PTR [EBP-0C],00000000
0000001B 8B45FC MOV EAX,DWORD PTR [EBP-04]
0000001E 3B45F8 CMP EAX,DWORD PTR [EBP-08]
00000021 7D14 JGE 00000037
00000023 8B4DF4 MOV ECX,DWORD PTR [EBP-0C]
00000026 034DFC ADD ECX,DWORD PTR [EBP-04]
00000029 894DF4 MOV DWORD PTR [EBP-0C],ECX
0000002C 8B55FC MOV EDX,DWORD PTR [EBP-04]
0000002F 83C20A ADD EDX,0000000A
00000032 8955FC MOV DWORD PTR [EBP-04],EDX
00000035 EBE4 JMP 0000001B
00000037 33C0 XOR EAX,EAX
00000039 8BE5 MOV ESP,EBP
0000003B 5D POP EBP
0000003C C3 RET
TCPSVCS Injection
The next runtime is injected into a newly created TCPSVCS.EXE process from SysWOW64.
The malware creates the process suspended, creates a section, maps views of that section locally
and into the target, and redirects the suspended process to the mapped runtime before resuming it.4
C2 Configuration
The configuration contains 64 indexed hostname/path records. Each record stores a base64 seed and is decrypted with two passes of the custom transform.5
For index n, the first key is derived by XORing the byte value of n across this 20-byte base key:
0A3CA5246592AB350674F7BB794E14A24A889AB3
The second key is constant:
D31E07A4B307F70E02AC8DFE64381712466D1F47
An additional hostname (“www.memecheat.shop”) is encrypted separately with its own seed and key pair. Older XLoader versions treated the separately encrypted hostname as the real C2, but the larger list can also contain working C2 servers and modern versions deliberately mix real and decoy traffic6, with XLoader 8.9 in particular often not using this hostname as the real C27.
Browser Database Staging
The browser collector builds the file path “%TEMP%\1U7G2-Ix5” and uses it as a temporary SQLite staging file for Chromium browser data. The source browser database is read into memory and written to this path before SQLite queries are executed. The filename is reused and its contents depend on which browser collector wrote it most recently.
Data Exfiltration
For each profile, the malware calculates K1 = SHA1(hostname + path)
and derives K2 by processing the following network seed with the
custom transform using K1: “9C87A9CB85178BEA4A96824B32AB4DC6C3372C03”.
A GET registration parameter can be base64-decoded and decrypted using RC4 with K2
and K1. Removing the PKT2: prefix, base64-decoding the remainder, and applying
the registration RC4 key reveals the XLNG: registration string.
POST exfiltration uses an inner form with parameters “dat” (data), “un” (victim ID),
and “br” (hardcoded as “9”). The “dat” value is RC4-encrypted with K1 and K2,
base64-encoded, and has the characters +, /, and = replaced with -, _, and ..
The complete inner form is then encrypted again with K1 and K2, base64-encoded, and placed
under a random outer parameter name. The decrypted values from the dynamic analysis network
capture contained clipboard data, browser autofill and recovery data, and browser cookies.
For example, the CyberChef recipe below can be used to decrypt a payload with the associated keys:
K1: 6B53C74E2A05B61CD662EA45B1A466AB9E459756K2: B933BF7C09392013D12E323B543E25052318F1DD
RC4({'option':'Hex','string':'6B53C74E2A05B61CD662EA45B1A466AB9E459756'},'Base64','Latin1')
RC4({'option':'Hex','string':'B933BF7C09392013D12E323B543E25052318F1DD'},'Latin1','Latin1')
Regular_expression('User defined','dat=([^&]+)',false,false,false,false,false,false,'List capture groups')
From_Base64('A-Za-z0-9\\-_.',true,false)
RC4({'option':'Hex','string':'6B53C74E2A05B61CD662EA45B1A466AB9E459756'},'Latin1','Latin1')
RC4({'option':'Hex','string':'B933BF7C09392013D12E323B543E25052318F1DD'},'Latin1','UTF16LE')
The result in this case is the following decrypted payload, containing clipboard data:
Clipboard
Program Manager
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Persistence
The decrypted strings contain the following registry run keys:
- \SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- \SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
The malware resolves NtCreateKey and NtSetValueKey and writes a REG_SZ
value under the user or machine hive. It generates a pseudorandom name
for the key and the value points to the its installed executable path.
Although no persistence artifact was observed during the dynamic analysis, the persistence capability is present and may be activated after initial communication with the C2 server has been established.
Summary
The final payload is a 32-bit XLoader 8.9 infostealer that uses multiple layers of encryption and obfuscation before transferring execution to its main stage. It avoids relying on a conventional import table by walking the TEB and PEB to locate loaded modules such as “ntdll.dll” and manually resolve the native APIs it requires.
The malware subsequently injects itself into a suspended “TCPSVCS.EXE” process and continues execution from the injected process. During execution, it decrypts a configuration containing multiple C2 or decoy domains and associated URL paths, and communicates over HTTP using encrypted and base64-encoded GET and POST parameters.
Indicators of Compromise
| Type | Value | Links | Comment |
|---|---|---|---|
| Domain | www.2226vip15.com | VirusTotal | C2/decoy |
| Domain | www.29870342.xyz | VirusTotal | C2/decoy |
| Domain | www.45si.com | VirusTotal | C2/decoy |
| Domain | www.464656235.xyz | VirusTotal | C2/decoy |
| Domain | www.55rii.com | VirusTotal | C2/decoy |
| Domain | www.56781924.xyz | VirusTotal | C2/decoy |
| Domain | www.abbyandbenjamin.com | VirusTotal | C2/decoy |
| Domain | www.arrow-life.net | VirusTotal | C2/decoy |
| Domain | www.axiasolarestimate.com | VirusTotal | C2/decoy |
| Domain | www.canal-plus.com | VirusTotal | C2/decoy |
| Domain | www.ccn4jab.makeup | VirusTotal | C2/decoy |
| Domain | www.christelbriereaymon.ch | VirusTotal | C2/decoy |
| Domain | www.claimbtc.com | VirusTotal | C2/decoy |
| Domain | www.codetrendforge.shop | VirusTotal | C2/decoy |
| Domain | www.depict-continue.ru | VirusTotal | C2/decoy |
| Domain | www.dodosantoss.space | VirusTotal | C2/decoy |
| Domain | www.duolingo.com | VirusTotal | C2/decoy |
| Domain | www.edmclaw.com | VirusTotal | C2/decoy |
| Domain | www.farmasi-mx.com | VirusTotal | C2/decoy |
| Domain | www.garycooperofficial.com | VirusTotal | C2/decoy |
| Domain | www.google.com.au | VirusTotal | C2/decoy |
| Domain | www.hikikagami.com | VirusTotal | C2/decoy |
| Domain | www.kaverimetalalloys.com | VirusTotal | C2/decoy |
| Domain | www.kvalitnimontaze.cz | VirusTotal | C2/decoy |
| Domain | www.lafabriqueapopcorn.fr | VirusTotal | C2/decoy |
| Domain | www.lbrcaahm.cyou | VirusTotal | C2/decoy |
| Domain | www.macsupport-online.com | VirusTotal | C2/decoy |
| Domain | www.mdc-pixei.cyou | VirusTotal | C2/decoy |
| Domain | www.meyeube.vn | VirusTotal | C2/decoy |
| Domain | www.modulajf.cz | VirusTotal | C2/decoy |
| Domain | www.morenovel.ai | VirusTotal | C2/decoy |
| Domain | www.nfld5.click | VirusTotal | C2/decoy |
| Domain | www.omcgw.cc | VirusTotal | C2/decoy |
| Domain | www.omptrr.com | VirusTotal | C2/decoy |
| Domain | www.p201.cc | VirusTotal | C2/decoy |
| Domain | www.p207.cc | VirusTotal | C2/decoy |
| Domain | www.postimees.ee | VirusTotal | C2/decoy |
| Domain | www.qyfg180.com | VirusTotal | C2/decoy |
| Domain | www.qz8ueo0.cn | VirusTotal | C2/decoy |
| Domain | www.rk88gone.site | VirusTotal | C2/decoy |
| Domain | www.ruvu.life | VirusTotal | C2/decoy |
| Domain | www.rwafrofreedom.com | VirusTotal | C2/decoy |
| Domain | www.sbeomv.com | VirusTotal | C2/decoy |
| Domain | www.scale-agency.org | VirusTotal | C2/decoy |
| Domain | www.slabx.uk | VirusTotal | C2/decoy |
| Domain | www.soludo.top | VirusTotal | C2/decoy |
| Domain | www.sotradis.ma | VirusTotal | C2/decoy |
| Domain | www.stcq8.com | VirusTotal | C2/decoy |
| Domain | www.stone-riser6.ru.com | VirusTotal | C2/decoy |
| Domain | www.stphmngm.store | VirusTotal | C2/decoy |
| Domain | www.thestorypedia.com | VirusTotal | C2/decoy |
| Domain | www.toshiba.co.jp | VirusTotal | C2/decoy |
| Domain | www.tripgenesys.com | VirusTotal | C2/decoy |
| Domain | www.tuxhuset.online | VirusTotal | C2/decoy |
| Domain | www.tvguide.com | VirusTotal | C2/decoy |
| Domain | www.wes521.com | VirusTotal | C2/decoy |
| Domain | www.wildatheartromania.com | VirusTotal | C2/decoy |
| Domain | www.memecheat.shop | VirusTotal | C2/decoy |
| Domain | www.xxxread.store | VirusTotal | C2/decoy |
| Domain | www.yogicweetershuns.fun | VirusTotal | C2/decoy |
| Domain | www.yytk.wang | VirusTotal | C2/decoy |
| Domain | www.zfzzqc4.cn | VirusTotal | C2/decoy |
| Domain | www.zinosazanfaraz.com | VirusTotal | C2/decoy |
| Domain | www.znisjinak.cz | VirusTotal | C2/decoy |
| Domain | www.zxlj-adguard.pro | VirusTotal | C2/decoy |
MITRE ATT&CK® Techniques
-
The Ministry of Silly Walks Presents: Walking the PEB | by Tom O’Neill | InfoSec Write-ups ↩
-
Technical Analysis of Xloader’s Code Obfuscation in Version 4.3 | ThreatLabz ↩
-
Technical Analysis of Xloader Versions 6 and 7 P1 | ThreatLabz ↩
-
Xloader v8.7: Obfuscation, RC4 C2 Encryption & Commands | ThreatLabz ↩
-
Technical Analysis of Xloader Versions 6 and 7 P2 | ThreatLabz ↩
-
Chasing XLoader: Tracking a Notoriously Complex Malware Family at Scale - YouTube ↩