Someone on Torrent Websites Saved Fucking With My Sonarr


I run the standard *arr stack on my NAS. It often works simply positive, till I noticed a warning on my dashboard.

The new South Park episode was caught within the queue with:

WHO is definitely falling for this within the large 2026????

Let me very clear about what that is.

Someone took a South Park EP identify, put .exe on the top, and uploaded it to public trackers with 2,392 seeders, ???

Who is dropping episodes as an EXE????

And Sonarr grabbed it, due to course it did. Then it sat there attempting to import it each 90 fucking seconds:

Import failed, path doesn't exist or just isn't accessible by Sonarr:
/knowledge/downloads/torrents/South Park S29E03 1080p WEB H264-MeGusta.exe

Not even a folder with a faux .mkv and a “codec installer” subsequent to it just like the “good outdated days”.

Just the exe. Are we deadass.

qBittorrent marked it “completed” two seconds after including it with total_downloaded: 0, so nothing really landed on disk. No thought why. Don’t care. Thanks qBit.

I blocklisted it in Sonarr, which nukes it from qBittorrent and stops it grabbing the identical junk skid malware once more.

Then I downloaded it once more on function. Because now I’m pissed and I wish to know what’s inside.

It’s an actual PE, x64 GUI. The precise program is 118 KB.

pe finish 0x1ce00
overlay 886653736 bytes

The different 886 MB is random junk glued onto the top. Why? Because lots of scanners simply hand over on recordsdata that large.

The model information says:

FirmName Freeware Developers
FileDescription prepares utility knowledge
OriginalFilename SetupHelper.exe

“Freeware Developers.” my ass

I chopped the 118 KB off the entrance and threw it into IDA, as a result of I’m not loading a gigabyte of bullcrap into something. Then the complete factor is roofed on this:

dword_14000C020 ^= 0xF2C2EAC0;
v34 = 0;
dword_14000C020 ^= 0xF2C2EAC0;

XOR a worldwide. XOR it again. Do nothing. Hundreds of occasions.

It exists purely to make the decompiler output appear like shit, and it does, congrats.

Strip all that out and the logic is like six steps:

  1. Open its personal file.
  2. Read the final 64 bytes.
  3. Use these to seek out and decrypt a payload hidden within the junk.
  4. Map it as a PE in reminiscence by hand.
  5. Point PEB->ImageBaseAddress at it.
  6. Jump in.

Nothing touches disk. Adding all that obfuscation for six steps.

The final 64 bytes of the file are the entire config:

Offset Size Description
0x00 32 bytes key, XORed with a 32 byte masks in .knowledge
0x20 12 bytes ChaCha20 nonce
0x2C 4 bytes payload measurement ^ fnv1a(masks)
0x30 4 bytes (flags | padding << 8) ^ fnv1a(masks)
0x34 8 bytes payload measurement ^ fnv1a(masks)
0x3C 4 bytes fnv1a(masks)

It’s ChaCha20. They hid the constants by constructing them out of globals, and so they nonetheless come out to broaden 32-byte okay. You cannot cover ChaCha20 from somebody who’s seen ChaCha20 earlier than.

flags = 3 activates an anti debug test (PEB->BeingDebugged, debug port queries, the standard) and an anti sandbox rating. Trip both one and it simply quietly exits.

A sandbox sees a traditional app open a file and depart.

Cool. Except the bottom line is actually contained in the file. (????) You do not even must run it:

masks = bytes.fromhex("56951de331cd7f254bf1931533dd82bc3c8bf542f0d1ed5736a40f394c51d0a1")
h = fnv1a(masks)
measurement = u64(footer, 0x34) ^ (h | h << 32)
fl = h ^ u32(footer, 0x30)
pad = fl >> 8
key = xor(masks, footer[:32])
nonce = footer[32:44]
payload = chacha20(key, nonce, knowledge[-64 - pad - size : -64 - pad])

Out pops a second PE. 929 KB, MSVC, C++20, zlib bundled.

All that anti evaluation bullshit however a dozen strains of Python can simply strip the obf.

Strings are encrypted, imports stripped all the way down to the CRT, all the things resolved at runtime.

And then WinMain simply dumps each module by identify in plain textual content:

osinfo
browsers
telegram
wallets
discord
steam
clipboard
remoteaccess
credentialmanager
authy
notes
obs
ssh
electronic mail
video games
filegrabber

Every different string will get its personal operate:

v5 = _mm_xor_ps(v6, v5);
v7 = { 1924987977, 1270327144, 877876327, 271431577 };
v8 = { 641333755, -1942364857, ... };
sub_140080F40(&v5, v7, v8, 0x20);

Two constants XORed right into a key, an IV, ciphertext, size. sub_140080F40 is AES with the S-box hidden behind RC4, as a result of one layer of crypto apparently wasn’t edgy sufficient.

Tried the usual modes on the primary one:

cbc  b'wx1cxe9xc6xa0yx96xa4...'
ctr  b'guid=x00x00x00...'

AES-128-CTR. Per string key. 672 name websites.

I’m not doing that by hand.

So I pulled each name web site out of IDA, emulated simply the few directions earlier than every name in Unicorn, grabbed the important thing, IV and ciphertext out of the registers, and decrypted them in Python. 601 of 672 got here out clear.

The relaxation are buried in larger features however I genuinely COULD NOT care much less, 601 was a lot.

  • Browsers: Chrome, Edge, Brave, Opera, Opera GX, Vivaldi, Firefox. Passwords, cookies, autofill, and it has code for Chrome’s new app sure encryption too.
  • Crypto wallets: Exodus, Electrum, Atomic, Guarda, Coinomi, Ledger Live, Trezor Suite, Wasabi, Sparrow, Monero, Zcash, Armory, plus extension wallets.
  • Password managers: KeePass, KeePassXC, Bitwarden, 1Password, NordPass, RoboForm, Windows Credential Manager.
  • Accounts: Telegram, Discord tokens, Steam, Roblox cookies, Minecraft accounts, Authy.
  • Dev stuff: .ssh, .aws, .azure, gcloud, .kube, .docker.
  • Remote entry: AnyDesk, TeamViewer, WinSCP, FileZilla, mRemoteNG, RDCMan.
  • The relaxation: Outlook, Thunderbird, VPN configs, OBS settings, Sticky Notes, and the paperwork in your desktop.

It even grabs your Sticky Notes for WHAT????

Everything will get zipped with the bundled zlib and shipped off.

No hardcoded server, as a substitute it decrypts:

www.youtube.com/channel/UC18vFC1xgebddr_7NsvgBYA
gist.githubusercontent.com/jasonterra69/48d9e264c05843f0cdc302143b4400c8/uncooked
[[
]]
ZhxchsdfhSGdfgsgdfAJsakdaksdk2364236AH

A YouTube channel, a GitHub gist, two brackets, and a key that’s visibly somebody mashing their keyboard.

The YouTube channel is “bubblegym”. Created September 14, 2026:

Base64 decode it, XOR it with the keyboard smash, and also you get the deal with:

b = base64.b64decode("OA0dDQ0HFBQHJyIHEkkQCAlJLS0JTgwAAB8S")
okay = b"ZhxchsdfhSGdfgsgdfAJsakdaksdk2364236AH"
bytes(x ^ okay[i % len(k)] for i, x in enumerate(b))
beenetprotect[dot]com/lgz/gdata

That actual deal with is additionally hardcoded within the binary as a fallback apparently???

I assume the entire level of a useless drop is that you may swap servers with out the deal with being within the malware.

But you set the deal with within the malware anyway so what is the level for fetching from Gist and YouTube????

Domain Name: BEENETPROTECT.COM
Creation Date: 2026-09-14T06:21:54Z
Registrar: Cloudflare, Inc.
Name Server: DONALD.NS.CLOUDFLARE.COM
Name Server: JULISSA.NS.CLOUDFLARE.COM

Registered September 14. Same day because the “gaming channel”. Builds on October 6, torrent up October 8.

If you run Sonarr or Radarr off public indexers, this WILL hit you. Sonarr cannot run an exe, so it isn’t the issue.

The drawback is your roommate, your dad or mum, or 3am you double clicking it within the downloads folder. (do NOT execute execute the skid malware)

Five minutes of setup:

  • qBittorrent: add *.exe, *.scr, *.lnk, *.bat, *.cmd to “Excluded file names”, tt’ll simply refuse to obtain them.
  • Sonarr / Radarr: blocklist with “Remove from consumer” once you see one in every of these.
  • Prowlarr: if a tracker retains serving this crap, demote it or drop it.

And to whoever made this: you in all probability spent weeks or shit ton of tokens on ChaCha20, AES-CTR, runtime API hashing, anti sandbox scoring, Chrome app sure encryption bypasses, simply to make a shitty skid malware.

Get a job.



Source link