Intentionally desktop-first — best experienced on a workstation
Portfolio
Threat Analysis · Platform Abuse · Account Infrastructure

Eight Random Letters
How a GitHub Account Factory Signs Its Own Work

Author
Yana Ivanov
Published
October 2026
Classification
Public — Educational
Attack Type
Platform Abuse · Malware Distribution
Sector
Open Source · Developer Platforms
Severity
High · Campaign Active
20 of 20 accounts signed the same way · 98 of 100 still live
Section 01

Executive Summary

On 29 October 2026 I examined a set of GitHub accounts distributing malware through repositories that impersonate zapret, a real open-source tool used in Russia to restore access to Discord, YouTube and Telegram. The accounts were identified from public malware-URL submissions and then checked individually against GitHub's own public API. This analysis reports what that check found.

The campaign is not new and I did not discover it. The Russian-language zapret community has documented these clones since June 2026, and related GitHub distribution campaigns were published by Island in July and by Apiiro in October. What follows is not a discovery of the operation. It is a measurement of how its accounts are constructed, and that measurement produced a signature I have not found described anywhere.

Every account I examined signs itself the same way. It registers with no followers. On that same day it creates one repository whose name is exactly eight random lowercase letters and nothing else. It then goes dormant for somewhere between nine and ninety-six days. Finally it publishes its entire set of lure repositories in a single batch on one later date. Twenty accounts drawn at random followed that sequence without a single exception.

134,146
Downloads Recorded
Across 834 release assets held by 100 sampled accounts
20 of 20
Accounts Signed Alike
Eight-letter repository on registration day, lures on one later date
98 of 100
Still Live
Checked against GitHub's public API on 29 October 2026
9 to 96
Days Dormant
Between account registration and first lure publication

Method and scope. The candidate account list came from public URLhaus submissions between 20 and 29 October 2026, filtered to repository names matching the campaign's lure patterns. Verification was done by reading GitHub's public API: account creation dates, follower counts, repository names and creation dates, and release asset download counts. One hundred accounts were checked for liveness and download totals; twenty of those were examined in full for repository structure. I did not download any payload and did not interact with the infrastructure in any way.

Section 02

Why This Lure Works on This Audience

zapret is a genuine open-source project. In Russia it is used to restore access to services subject to throttling or blocking, principally Discord, YouTube and Telegram. The best-known packaging of it is maintained under the GitHub account Flowseal, and the ordinary way to obtain it is to download a ZIP archive from a GitHub releases page.

That ordinary way is the entire attack. A person searching for a way to unblock Discord expects to find a GitHub repository, expects to download an archive from it, and expects to run an unsigned executable with administrator rights, because that is what the genuine tool legitimately requires. The audience is pre-selected for precisely the behavior the malware needs.

check_circle The Genuine Project

Name: One canonical repository name, with forks that keep it

Account: A maintainer with followers, history and other work

Repositories: Source code, issues, commits over time

Description: Written once, by a person

warning What I Measured

Name: Dozens of permutations of the same words across unrelated accounts

Account: Zero followers on 98 of the 100 I checked

Repositories: Four to six, all published on one day, carrying release archives

Description: The same adjectives reordered from repository to repository

The naming is generated, and it shows

The repository names in this set are permutations of what a user would type into a search box. Reading them in bulk makes the generator visible.

TechniqueExamples Observed
Word-order permutationdiscordzapret / zapretdiscord
Separator variationdiscord-fix / discordfix / fix-discord / fixdiscord
Version suffixes1.9.9c · 1.9.9d · 1.10.1 · 1.10.2 · 1.11.1
Qualifier suffixesDiscordFix-2026 / -New / -Stable / -Update / -Windows
Random case manglingdIsCoRdzapReT · tELeGRaM-ZaPrET
Maintainer's nameflowseal-zapret-discord-youtube
Transliterated Russianobhod, from обход, meaning bypass

The descriptions are generated the same way. Three repositories on three different accounts carried the phrases Стабильнее, быстрее, надежнее, Надежнее, быстрее, стабильнее and Быстрее, надежнее, стабильнее. The same three adjectives, reordered. A reader who does not read Russian sees three plausible descriptions; a reader who does sees one sentence shuffled three ways.

Why the random case mangling matters. Names like dIsCoRdzapReT and ZAPRET_gItHuB-DISCOrd_1.9.9C are not sloppiness. Randomized capitalization defeats exact-string matching on repository names, which is the most obvious check a platform would run. The generator is built against the detection it expects.

Section 03

How the Factory Signs Its Work

The naming is noisy by design and varies account to account. The account lifecycle does not vary at all. Every one of the twenty accounts I examined in full followed the same five steps.

Figure 1 — Observed Account Lifecycle, 20 of 20 Accounts
01
Register
An account is created with a name built from two or three concatenated dictionary words, sometimes with trailing digits. WishLieutenantSlide, PatrolGiraffePipe, noblefreighterreduce. It has zero followers and it will never acquire any. Registration dates in my sample run from 1 June to 22 September 2026.
02
Sign
On the same day it registers, the account creates exactly one repository whose name is eight random lowercase letters: bqwewudp, wxlloxmo, rurrumxe, alsazxkw, fszbyktv. It has no description and it is never touched again. This step appeared on 20 of 20 accounts examined, and it is the clearest marker in the entire campaign.
03
Wait
Nothing happens for between nine and ninety-six days. The account is being aged. A newly registered account publishing a lookalike installer invites scrutiny; a three-month-old account with an existing repository does not. This is the step that makes account-age heuristics useless against this operation.
04
Activate
All of the account's lure repositories are created on one single date, typically three to six of them. Accounts registered on the same day activate on the same day with identical repository sets, which is cohort behavior rather than independent operators working in parallel.
05
Serve
Each repository carries a release with ZIP and RAR archives named after genuine zapret versions. GitHub records a download count on every release asset, and those counters are not zero. Across the 100 accounts I sampled, 834 assets had accumulated 134,146 downloads by 29 October 2026.
Lifecycle derived from twenty accounts selected at random from the candidate set and examined in full through GitHub's public API on 29 October 2026. MITRE ATT&CK: T1585.003 (Establish Accounts: Cloud Accounts), T1608.001 (Stage Capabilities: Upload Malware), T1204.002 (User Execution: Malicious File), T1036.005 (Masquerading: Match Legitimate Name or Location).

Cohorts activate together

The clearest evidence that this is one operation rather than many is that accounts registered on the same day are switched on together, with the same repositories, weeks later.

RegisteredAccountsActivatedRepository Set
30 Jul 2026Lacquergruraid, bandwidowbegin16 Aug 2026Identical, 5 repos
6 Aug 2026wildstagekindle, SwiftSoundIdolize23 Aug 2026Identical, 5 repos
9 Aug 2026SplendorEchoHatchet, StorageStudent2 Sep 2026Identical, 5 repos
13 Aug 2026PatrolGiraffePipe, MoatSorcerer20 Sep 2026Identical, 3 repos

Two accounts with unrelated names, registered the same day, dormant for the same number of days, waking on the same day with the same five repository names. Four such pairs appeared inside a sample of twenty, which is not what independent activity looks like.

Section 04

Key Findings

1
Every Account Carries the Same Eight-Character Marker
Twenty of twenty accounts created a repository named with exactly eight random lowercase letters on the day the account was registered. No description, no content of consequence, never updated. A legitimate developer does not do this, and a fork of the genuine project cannot produce it. Of everything in this campaign, it is the one artifact that is both perfectly consistent and trivially checkable.
OBSERVED 20/20
2
134,146 Downloads Were Recorded on 100 Sampled Accounts
GitHub publishes a download counter on every release asset. Across 834 assets held by 100 randomly sampled accounts, those counters totalled 134,146 on 29 October 2026, with a median of 1,297 per account. Two individual repositories checked earlier showed 341 and 355. The counter includes researchers, sandboxes and scanners as well as real users, so it is a measure of downloads rather than of infections, and it is a floor rather than a ceiling on exposure.
MEASURED
3
The Accounts Are Aged Deliberately Before They Are Used
Registration ran from June to September 2026 while the lure repositories appeared from August to October, with dormancy between nine and ninety-six days. These accounts were not created on demand for a campaign; they were stockpiled and drawn down. Any detection that keys on account age, "new account publishing an installer," fails against this by construction, and the operator appears to know it.
OBSERVED 20/20
4
Cohorts Register Together and Activate Together
Four pairs within a twenty-account sample shared a registration date, a dormancy period, an activation date and an identical repository set. Accounts with no visible relationship to one another behaving in lockstep across intervals of weeks is the signature of one scheduler, not of many unrelated actors arriving at the same idea.
OBSERVED
5
Ninety-Eight of a Hundred Accounts Were Still Live
Of 100 accounts checked against GitHub's public API on 29 October 2026, 98 returned a valid profile and 2 returned 404. This was three weeks after related research was published by Apiiro and more than two months after the Russian-language zapret community began documenting the clones. I am reporting what the API returned on one date; I am not characterizing any platform's moderation process, which I have no visibility into.
MEASURED, ONE DATE
Section 05

What Would Catch This

Most of what is visible here is deliberately noisy. Names are permuted, capitalization is randomized, version numbers rotate. Those are the parts the operator varies, so they are the parts worth ignoring. The signal is in what does not vary.

Detection signals summary

SignalIndicatorConfidence
Eight-character marker reporepo name matches ^[a-z]{8}$, created on account creation dateHigh
Single-date activationall remaining repos share one creation dateHigh
No social graphfollowers == 0 and following == 0Medium
Dormancy before first lureactivation date minus registration date, 9 to 96 daysMedium
Name-permutation clusteringmany accounts, few distinct names for one tokenMedium
Release archive without sourcerelease asset present, repository has no codeMedium

No single row in that table is sufficient on its own. Plenty of real accounts have no followers, and plenty of real projects publish an archive. The first two rows together are a different matter: a repository named with eight random lowercase letters created on registration day, followed by a batch of repositories all created on one later date, is a sequence I have not been able to produce from any legitimate account.

The practical value of the first signal is that it costs nothing to check and the operator cannot vary it without redesigning the generator. The name permutations can be regenerated in an afternoon. The lifecycle is the part that has to stay fixed.

For anyone looking for zapret or a Discord unblocker. Check the account, not the repository. A maintainer of a widely used tool has followers, a history, and other work. An account with none of those, holding four repositories created on one day, is not the project you were looking for, whatever the repository is called.

Section 06

What This Establishes, and What It Does Not

I want to be precise about the boundary, because the interesting finding here is narrow and it is easy to overstate it.

What I measured. One hundred accounts verified live or gone against GitHub's API on a single date. Eight hundred and thirty-four release assets and their recorded download counts. Twenty accounts examined in full, every one showing the same five-step lifecycle. Four cohort pairs within those twenty. Registration dates, follower counts and repository creation dates for all one hundred.

What I did not establish. The candidate list contained 5,066 accounts and 19,597 repositories matching the campaign's naming patterns, but I verified 120 of them individually and I am not claiming the remainder. A name filter is an inference, not a finding, and the genuine project's own name appears inside several of those patterns, so some proportion of any name-matched list will be legitimate. I have not attributed this operation to anyone. I have not analyzed a payload. The malware family named by URLhaus on 17,220 of these URLs is SalatStealer, which is that database's classification rather than my determination.

What changed while I was writing it. Three figures I initially believed did not survive checking. An account total of 19,763 collapsed to 5,066 once legitimate repositories were filtered out of it. A claim that three independent submitters had corroborated the account list collapsed to one submitter. A claim that this campaign delivered SmartLoader collapsed when the campaign-filtered data showed no SmartLoader at all. Each of those was caught by running one more query, and I mention them because a reader has no way to see the claims that were discarded, only the ones that remained.

What survives is small and specific. An operation distributing malware through GitHub builds its accounts on an assembly line, and the assembly line leaves a mark: eight random lowercase letters, created on day zero, never touched again. It is on every account I looked at. It is readable without authentication, without tooling, and without downloading anything. And it is still there on almost all of them.

Method: candidate accounts were drawn from public URLhaus submissions dated 20 to 29 October 2026, filtered to repository names matching this campaign's lure patterns, yielding 5,066 accounts across 19,597 repositories from a single submitter. One hundred accounts were selected at random from those carrying a zapret-named repository and checked against GitHub's public REST API on 29 October 2026 for existence, creation date, follower count, repository list and release asset download counts. Twenty of those hundred were examined in full for repository creation sequence. All figures reflect API responses on that date; download counters are cumulative since each release was published and include automated retrieval by researchers, sandboxes and scanners. No payload was downloaded, no archive was opened, and no interaction with the operation's infrastructure took place at any point. Prior public reporting on related GitHub distribution campaigns: Island, July 2026, 7,600 repositories; Apiiro, October 2026, 17,610 repositories; both describe SmartLoader and StealC rather than the payload classified here. The Russian-language zapret community wiki has documented clone repositories since June 2026 and is the earliest public record of this lure set that I could find. This analysis represents independent research produced for educational purposes.

YI
Yana Ivanov
Security Analyst  ·  Threat Intelligence  ·  Detection Engineering

I'm a security researcher in Connecticut. Analysis is the part I love: tracing threat actor behavior, pulling apart supply chain attacks, and following evidence even when it lands on "unknown." When a question needs a tool that doesn't exist, I build it; most of the tools on this site started that way. Before security I spent 15 years designing enterprise software, which is why my tools assume a human will actually have to use them. I contribute detection rules to Sublime Security's open-source production ruleset. Security+ in progress. Everything here is independent work, shared as a contribution to the security community.

Portfolio