When a fake TV torrent delivers Lumma Stealer in a 900 MB screensaver

A LimeTorrents listing for a season pack served a hex-named Windows screensaver instead of video. Reverse engineering the 900 MB wrapper recovers Lumma Stealer v6: reflective loading, nine C2 domains, Steam fallback, and verified clipboard and screenshot theft.

  • By Charlie Kelly
  • 26 min read
  • Threat intelligence
  • Malware
  • Windows

Overview#

A LimeTorrents listing for The Pitt season two advertised 15 Matroska episodes. The torrent behind it held one file, a 900 MB Windows screensaver named after a hexadecimal string. A .scr file is a Windows portable executable (PE) and runs code exactly like an .exe. This one is a padded loader that decrypts Lumma Stealer version 6 and runs it in memory.

Have I Been Squatted tracks torrent listings that impersonate TV and film releases while serving executables. This sample was analyzed in August 2026 with static analysis, custom unpacking, and offline emulation, and no command-and-control (C2) server was contacted. The payload's request format, Steam fallback, obfuscation, and collection code support a high-confidence assessment that it is Lumma v6 or a close derivative. Its ten C2 domains share one server, and on 27 October 2026 all ten still resolved to it.

The chain below runs from the listing to the payload's collection routines. Select a stage to see its evidence. The capabilities panel separates what this sample verifiably does from what Lumma's configuration can add.

Execution chain

Fake TV torrent to in-memory Lumma Stealer

Public torrent listings that impersonate TV and film releases are a common delivery channel for information stealers. This sample came from a LimeTorrents listing for a release of The Pitt season two, where the apparent media file was a Windows .scr screensaver.

The channel costs nothing, faces no mail gateway, and reaches an audience already willing to run an unsigned file from an untrusted source.

Observed evidence

  • The Pitt S02 1080p WEBRip DS4K AV1 Opus 5 1-heTOrico
  • Windows screensaver executable
  • Retrieved from the listing

Payload capabilities

Verified in this sample versus documented for Lumma

Clipboard.txt

Clipboard theft

Copies Unicode clipboard text into the payload's collection buffer.

Verified in the recovered payload

Evidence

  • Calls OpenClipboard and requests format 13, CF_UNICODETEXT.
  • Copies the text under GlobalLock, then releases it with GlobalUnlock and CloseClipboard.
  • The Clipboard.txt label was recovered from the sample's own stack string.

Capability boundary

  • The recovered routine reads Unicode text. No other clipboard format was found in the code.

Response implication

Anything on the clipboard at run time, such as a copied password or wallet address, is exposed.

A season pack that is one file#

The listing's file table shows 16 entries, 15 .mkv episodes and a release-group .nfo, totaling about 11.5 GB. That is what a legitimate season pack looks like.

Torrent file contents dialog showing 16 files: a The Pitt season two folder with 15 Matroska episodes and a heTOrico.nfo
Advertised torrent contents for the listing: 15 Matroska episodes and a release-group .nfo

The torrent the page links to contains one file, and its length matches the analyzed sample to the byte.

FieldValue
Infohash (v1)98618871fb8b9348fcd8ecbfdaacc85d3cefb034
Name00A32B3471A8BC9632A105A9B3D5E5C7471C5C39.scr
Length944,366,592 bytes, 900.62 MiB
Created8 August 2026, 13:02:06 UTC, by qBittorrent v5.1.4

The mismatch is not tampering by a seeder or a tracker. A torrent's infohash is the SHA-1 of its info dictionary, which holds the file list and a hash for every piece, so a client rejects metadata or pieces that do not match it. The file table is HTML that the index site renders, and nothing binds it to the magnet link beside it. The .torrent served from the page carries the comment Torrent downloaded from torrent cache at http://itorrents.net, a cache that returns metadata by infohash.

The rest of the metadata reads as automation rather than a release group. The announce list is a pasted block of 248 public trackers, 81 of them duplicates, including the long-dead 9.rarbg.com. The torrent was created on the same date the screensaver's PE header claims. A victim who opens the torrent before starting it sees one hex-named .scr and a download about 13 times smaller than the page advertised. Listings change, so files served from that page later may not match this sample.

900 MB of padding around a small loader#

900.62 MiB on disk, 0.06% program

549,376 bytes

Program, 0.06% of the file

200.09 MiB

Resources, 22.22% of the file

700.00 MiB

Overlay, 77.72% of the file

Raw on-disk sizes in file-offset order. The loader is 549,376 bytes. The rest is padding.

Valid PE data ends at 200.62 MiB, and 700 MiB of overlay follows it. Most of the PE itself is a 200 MiB resource section. Strip both and the program that remains is 549,376 bytes, 0.06% of the download. None of the bulk is code. It pushes the file past sandbox upload limits and makes the download look like video.

A loader that hides from analysis#

The outer file's import directory is empty. The loader walks the Process Environment Block (PEB) and resolves Windows API functions by hash, such as 0xba8a1141 for VirtualAlloc. It also exports hundreds of plausible names that point at dummy stubs. Triage based on imports shows nothing about what the program does.

Before unpacking anything, the loader reads the user's locale with GetUserDefaultLCID and abandons the malicious path on Russian (0x0419) or Belarusian (0x0423) systems. The check avoids those systems rather than targeting them, and says nothing definitive about where the operator is.

It then runs a busy wait of about one second and measures the elapsed time with GetTickCount. Sandboxes and emulators often skip or slow down such loops, and a deviation beyond about 50 milliseconds stops the payload. The second stage reads the tick count straight from KUSER_SHARED_DATA at 0x7ffe0014 instead of calling an API.

Once the checks pass, the loader decrypts a 349,696-byte PE from 0x42b100 with a 128-byte key at 0x42b000. It then decrypts a 3,296-byte stub, marks its memory executable, and calls it with a pointer to the PE. The stub maps the second stage from memory, so the payload never exists as a file on disk.

The stealer#

The second stage is obfuscated with control-flow flattening, stack-built encrypted strings, dead code, and indirect calls, the style Microsoft describes in current Lumma builds. Three collection routines survived it well enough to verify directly.

The clipboard routine opens the clipboard, reads Unicode text (CF_UNICODETEXT), and hands it to the payload's collection routine as Clipboard.txt. The screenshot routine copies the virtual desktop through the Windows Graphics Device Interface (GDI) with BitBlt and labels it Screenshot.png. Both labels come from the sample's own decrypted strings, not from family reporting. A third routine queries SELECT * FROM Win32_BIOS through Windows Management Instrumentation (WMI) for the BIOS serial number, a stable identifier for the machine.

The payload also resolves file-enumeration and disk-space functions, but Lumma takes its list of browsers, wallets, applications, and documents to steal from the C2 configuration. The emulator returned none, so this analysis cannot say which of those targets a live run would collect. Microsoft documents browser credentials, cookies, wallets, application data, documents, and follow-on payloads as family capabilities. No persistence, encryption, or exfiltration appeared in the path analyzed, which is expected for a payload that never received its configuration.

Command and control#

The payload loads winhttp.dll at runtime, sets five-minute timeouts, and identifies itself with a Chrome 109 user agent. Its first request is a form POST to the server root over port 80.

uid=19edfae77fa464317284726b20497eded3333549&cid=0d5b0d6e95037f7d0d4d809554f3b6d0

A body with only uid and cid, and none of the older act, ver, lid, and j fields, is what Microsoft identifies as Lumma v6's configuration request. uid identifies the operator and campaign, and cid the optional features. Neither identifies a victim, and both are useful pivots.

The payload sends that request to nine hardcoded domains in order, up to four attempts each, and moves on until one returns a usable body. In order, they are , , , , , , , , and .

A Steam profile as the fallback#

When all nine fail, the sample requests https://steamcommunity.com/profiles/76561198668480149. Lumma reads a profile's display name and decodes it with a Caesar shift, which moves every letter a fixed number of places through the alphabet. AhnLab documented the scheme in earlier builds. This profile's title, shifted back 11 places, gives a domain.

Profile title:  ezzwdpa.mtk
Decoded domain: toolsep[.]biz

The same shift turns AhnLab's published example, cptyqzcnpotcpnezcjho.dsza, into reinforcedirectorywd[.]shop, and no other shift of this title produces a real top-level domain. The decoded domain, , was registered in the same second as the hardcoded domains and resolves to the same server. The emulator served no profile page, so the sample's own decoder never ran. The decode rests on the documented scheme and that infrastructure match.

Renaming the profile points infected hosts at a new C2 without a new build. On 26 October 2026 the title was unchanged. Because the fallback domain was bought in the same order as the main set, it was likely planned from the start rather than added after the main domains were blocked.

Domain protection

Detect adversary infrastructure while it is being staged.

Have I Been Squatted helps security teams detect lookalike domains, certificate and DNS changes, and staging infrastructure, investigate the evidence, and coordinate takedowns.

One server behind every domain#

The infrastructure data below is passive, collected on 10 August 2026 from registration records, DNS, certificate transparency, routing data, Shodan, urlscan.io, and AlienVault Open Threat Exchange (OTX). The domain links open Have I Been Squatted analyze snapshots taken on 27 October 2026, which did contact each domain.

DomainRegistered (UTC)Registry handle
valuidge[.]cyou23 July 2026, 12:10:42D633547871-CNIC
creaflow[.]cyou24 July 2026, 14:43:40D633591628-CNIC
trendion[.]cyou24 July 2026, 14:43:40D633591629-CNIC
starzone[.]cyou24 July 2026, 14:43:40D633591630-CNIC
businway[.]cyou24 July 2026, 14:43:40D633591631-CNIC
visioint[.]cyou24 July 2026, 14:43:40D633591632-CNIC
smaridge[.]cyou24 July 2026, 14:43:40D633591633-CNIC
futurtep[.]cyou24 July 2026, 14:43:40D633591634-CNIC
citymket[.]cyou24 July 2026, 14:43:40D633591636-CNIC
toolsep[.]biz24 July 2026, 14:43:40.biz registry

All ten were registered through Dynadot and use its nameservers. Eight .cyou domains and the .biz fallback share a registration second, and the .cyou handles are near-sequential, which points to one automated bulk order. Handle D633591635-CNIC sits in the gap between futurtep and citymket, so the order probably created one more domain that this analysis cannot recover. valuidge was registered 26.5 hours earlier and is the only domain with a public certificate, from Let's Encrypt and valid from 1 August. That makes it a plausible staging domain, though the role is an inference.

Every domain resolved to the same address with a five-minute time to live.

Ten C2 domains, one IPv4 address

  • valuidge[.]cyou23 Jul
  • creaflow[.]cyou24 Jul batch
  • trendion[.]cyou24 Jul batch
  • starzone[.]cyou24 Jul batch
  • businway[.]cyou24 Jul batch
  • visioint[.]cyou24 Jul batch
  • smaridge[.]cyou24 Jul batch
  • futurtep[.]cyou24 Jul batch
  • citymket[.]cyou24 Jul batch
  • toolsep[.]bizSteam fallback

Shared A record, TTL 300

64[.]89[.]161[.]173

ASN
AS205759
Holder
Ghosty Networks LLC
HTTP
nginx 401
PTR
None
Nine hardcoded domains recovered from the sample, plus the domain its Steam fallback decodes to. valuidge was registered a day before the batch. Hosting details are from 10 August 2026.

The server returns 401 Unauthorized from nginx/1.18.0 (Ubuntu) on every domain. Shodan saw that response 35 minutes before the 24 July batch was registered, which fits an operator who provisioned the backend first and pointed bulk-registered domains at it afterward. Shodan also recorded an OpenSSH host key on port 22. A host key is a better pivot than an address, because it follows the server to a new IP unless the operator regenerates it. Its fingerprints are in the indicator list below.

By 27 October 2026, 64.89.161.0/24 was announced by AS403005 (Blatant) instead of AS205759, while the address and every domain record stayed the same. ASN-based blocks built from the August data no longer cover the server. urlscan.io ties 32 apex domains to the address with the same 401 fingerprint, more than this sample uses, so revalidate the address before blocking it.

An earlier batch on the same server#

A community AlienVault OTX pulse titled "Lumma", published on 27 July 2026, lists 18 domains. Eight are the 24 July batch, and a ninth is . That independent match, made before this sample was analyzed, corroborates the Lumma assessment.

The other nine are not in the binary. They are , , , , , , , , and . All nine were registered through Dynadot at 12:26:04 UTC on 9 June 2026, with CentralNic handles from D631035759-CNIC to D631035776-CNIC. That is a second bulk order, six weeks before the July batch, pointed at the same server. The pulse has no write-up attached, so treat these nine as medium-confidence hunting pivots rather than confirmed C2.

Timeline#

23 Jul 2026  valuidge[.]cyou registered
24 Jul 2026  Shodan observes nginx returning HTTP 401 on 64[.]89[.]161[.]173
24 Jul 2026  eight remaining C2 domains and toolsep[.]biz registered in the same second
27 Jul 2026  OTX community pulse labels the batch, including toolsep[.]biz, as Lumma
01 Aug 2026  Let's Encrypt certificate becomes valid for valuidge[.]cyou
02 Aug 2026  first public urlscan.io scans of the sample's domains
08 Aug 2026  torrent created; outer screensaver's claimed PE timestamp
10 Aug 2026  passive snapshot: all 19 OTX and sample domains resolve to one IP
26 Oct 2026  Steam profile title unchanged; toolsep[.]biz still resolves to the same IP
27 Oct 2026  prefix announced by AS403005 instead of AS205759; all 19 domains unchanged

Detection and response#

High-value behavioral sequence#

  1. a torrent advertised as a video release resolves to a single hex-named .scr
  2. the user launches the .scr from a downloads, torrent, or media directory
  3. a PE with an empty import directory walks the PEB and resolves APIs by hash
  4. the process allocates memory, marks it executable, and transfers control into it
  5. the process loads winhttp.dll at runtime and sets five-minute timeouts
  6. it sends root-path form POSTs containing only uid and cid to several young .cyou domains over port 80
  7. after those requests fail, it requests one exact Steam Community profile over HTTPS, then resolves the decoded domain
  8. the same process also queries Win32_BIOS through WMI, reads Unicode clipboard text, and captures the desktop with GDI BitBlt, in an order relative to C2 that the analysis did not establish

Screenshots and WMI queries are common in legitimate software. The sequence and the context make this sample distinctive.

Host hunting#

Search for:

  • .scr, .exe, .pif, or script files launched from directories that otherwise hold video releases
  • the SHA-256 e8a378b0f1256b0eda320641f07cf65785212455073b9f9dfa4bd1af3e56b270
  • PE files near 900 MB with a large overlay or resource section and little code
  • HTTP bodies matching uid=[0-9a-f]+&cid=[0-9a-f]+, especially toward young or low-reputation domains
  • failed connections to several unrelated domains followed by access to a specific Steam or Telegram profile
  • access to steamcommunity.com/profiles/76561198668480149, matched on the exact path
  • DNS lookups for the ten domains in the indicator list

Recommendations#

Isolate a host that ran the file and preserve memory and disk evidence before cleanup. Only the outer .scr is on disk. From a separate trusted device, end sessions and rotate passwords for every account reachable from the host's browsers and applications, and move funds from any wallet whose keys or extensions were on the host.

Block the ten domains and the exact Steam profile path. Do not block steamcommunity.com as a whole.

For anyone downloading media torrents, trust the file list the BitTorrent client resolves from the infohash, not the table an index page draws around it. A Windows screensaver is executable code, and a single hex-named .scr is not a season pack.

Summary#

A LimeTorrents listing for The Pitt season two served a 900 MB Windows screensaver instead of video. The file is a padded loader that checks locale and timing, decrypts a second-stage PE, and maps it in memory. The payload behaves like Lumma Stealer v6. It sends uid and cid to nine hardcoded .cyou domains, then falls back to a Steam profile whose title decodes to .

All ten domains resolve to one server, nine were registered in the same second, and a community OTX pulse labeled them as Lumma before this sample was analyzed. The same pulse exposes an earlier June batch on that server. The offline analysis verified clipboard, screenshot, and host-fingerprinting routines, and a live configuration can add browser, wallet, and document theft, so treat any host that ran the file as having exposed its credentials and sessions.

TTPs and IOCs#

The tactics, techniques, and procedures (TTPs) below use MITRE ATT&CK v20 technique identifiers and tactic names. Indicators of compromise (IOCs) are grouped into exportable lists.

References#

Contact#

Evidence has been preserved and shared with relevant parties.

For questions, related intelligence, or sightings of similar torrent-delivered stealers, contact [email protected].

For press inquiries, contact [email protected].