Fetching latest headlines…
Found a Second Layer to a GitHub Follow Botnet?
NORTH AMERICA
πŸ‡ΊπŸ‡Έ United Statesβ€’May 21, 2026

Found a Second Layer to a GitHub Follow Botnet?

0 views0 likes0 comments
Originally published byDev.to

This is Parts 2 of an ongoing investigation. Part 1 documented the initial discovery β€” 8 accounts with Jaccard following-list similarity of 0.99+ across ~29,800 entries each, evading cross-follow detection entirely.

After Part 1 published, I kept pulling the data.

Subsequent analysis expanded the cluster to 9 accounts, recovered infrastructure linkage to a specific GitHub identity, and mapped the generation pipeline responsible for all 552 repositories across the cluster. The pipeline left recoverable artifacts in every repository it produced.

Following that same pipeline fingerprint led to an earlier operation β€” running nine months before the follow botnet was provisioned. The same GitHub identity appears in both. So does the same generator artifact. Four accounts documented in Part 1 appear in both operations.

This post documents what the data shows. Inference is labeled as inference throughout. I am not establishing intent or ownership beyond what the API evidence directly supports.

The Cluster Expanded

Running Jaccard similarity analysis against the original 8 accounts and their extended follower graphs surfaced a ninth account: lynewinter.

Pairwise Jaccard similarity against mariwatts:

lynewinter  ↔  mariwatts   jaccard=0.9898   sharedβ‰ˆ29,200

The methodology is identical to Part 1. A coefficient of 0.9898 across ~29,800 following entries places this pair within the same anomalous range as the original cluster. The same alternative explanations from Part 1 apply and fail at the same scale.

The confirmed cluster is now 9 accounts:

canestein, hazexone, domcomit, kylehyne, jaderytm,
vierystein, hanyvert, mariwatts, lynewinter

552 Repositories, One Embedded Timestamp per Account, 34-Minute Span

Each of the 9 accounts has between 57 and 63 public repositories. Total across the cluster: 552 repositories.

Every repository was created on May 12, 2026. Fetching the first repository per account and reading the raw README returned an HTML comment β€” invisible on the rendered page β€” containing a creation timestamp and a job identifier:

2026-05-12 11:10:39 | hanyvert   | SwapLink     | job=48099
2026-05-12 11:18:46 | jaderytm   | GasSync      | job=39412
2026-05-12 11:27:52 | hazexone   | BitForge     | job=63871
2026-05-12 11:30:00 | canestein  | BlockLink    | job=51606
2026-05-12 11:33:07 | mariwatts  | MintChain    | job=82564
2026-05-12 11:35:37 | vierystein | HashSync     | job=20845
2026-05-12 11:38:58 | kylehyne   | SmartLink    | job=38575
2026-05-12 11:42:07 | lynewinter | YieldChain   | job=78012
2026-05-12 11:44:30 | domcomit   | ProjectCloud | job=26977

The first and last timestamps are 34 minutes apart. The job IDs are non-sequential across accounts. Sequential job dispatch from a single process would produce monotonically increasing IDs; non-sequential IDs are consistent with a job queue dispatching work across multiple workers concurrently. That is one interpretation β€” the data does not rule out other scheduling patterns.

The comment format is consistent across all sampled READMEs:

<!-- fallback_BlockLink_20260512113000_51606 -->

The fallback_ prefix is present in every instance retrieved. In the context of template generation systems, a fallback_ label typically indicates the primary generation path failed and a static secondary template was substituted. Whether that interpretation applies here is inference β€” what is directly observable is that the prefix is consistent across all 552 repositories and across both the 2026 and 2025 operations documented below.

Repository Contents

Fetching file trees and raw content from sampled repositories across all 9 accounts returned the same structural pattern.

A representative Python file (blocklink.py, 1,656 bytes):

class BlockLink:
    def run(self) -> bool:
        try:
            self.logger.info("Starting BlockLink processing")
            # Add your main logic here
            self.logger.info("Processing completed successfully")
            return True

The comment # Add your main logic here is the sole content of the method body. Every sampled repository follows this pattern: a class stub, a logging initializer, an argparse entry point, and a test file that instantiates the stub. No functional implementation was found in any sampled file.

Repo names follow a [Word][Suffix] pattern. Suffixes are drawn from a fixed set: Core, Chain, Sync, Vault, Forge, Link. Descriptions are consistent with AI-generated output.

Across all 552 repositories:

  • Stars: 0
  • Forks: 0
  • PyPI uploads: none found
  • CI/CD configuration files: none found (no .github/workflows/, no .travis.yml)
  • Open issues: 0
  • Pull requests: 0

These absences are observable facts. Their interpretation β€” what they indicate about the repositories' purpose β€” is addressed in the inference section below.

A Template Substitution Error Confirms Shared Generation

The LICENSE section of every generated README contains a hardcoded URL. That URL uses mariwatts as the repository owner regardless of which account's repository it appears in.

From canestein/BlockLink:

See the LICENSE file at https://github.com/mariwatts/BlockLink/blob/main/LICENSE

From lynewinter/YieldChain:

See the LICENSE file at https://github.com/mariwatts/YieldChain/blob/main/LICENSE

The repo name variable was substituted correctly. The account name variable in the LICENSE URL field was not. mariwatts appears to be the base account in the generation template β€” the value that was present when the template was authored and not replaced during per-account substitution.

This pattern was confirmed across multiple accounts and multiple repositories. It is not present in the mariwatts repositories themselves, where the URL resolves correctly.

The Pipeline Is Linked to a Specific GitHub Identity via Commit Metadata

Every repository across all 9 accounts contains a co-author trailer in its commit history:

Co-authored-by: Hajigur <[email protected]>

GitHub's authenticated noreply format is [email protected]. The numeric ID prefix is assigned by GitHub at account creation and embedded by GitHub's own systems when a commit is pushed through an authenticated session. It is not user-configurable and cannot be produced by manually typing a username.

The GitHub account hajigur69 has the internal numeric ID 66867581. This can be verified:

curl -s https://api.github.com/users/hajigur69 | python3 -c \
  "import json,sys; u=json.load(sys.stdin); print(u['id'])"
# 66867581

Fetching the commit history of hajigur69's own repository (Cloud9, created February 2026) returns commits authored with the same identifier:

Author: Hajigur | [email protected]

The same authenticated GitHub ID (66867581) appears in commits across all 9 cluster accounts and in commits authored directly by hajigur69. GitHub account created June 13, 2020. At time of retrieval: 903 followers, 679 following. Public bio field: lamer.

This co-author line is present in every repository across the cluster. It links the cluster's commit history to a specific, authenticated GitHub identity. It does not establish that hajigur69 provisioned the accounts or controls them β€” it establishes that the same authenticated identity was used to produce commits in the cluster's repositories and in hajigur69's own repository.

Infrastructure: carox.tech

Two cluster accounts β€” canestein and lynewinter β€” use a custom email domain in their git commit author metadata:

canestein  β†’ [email protected]
lynewinter β†’ [email protected]

These addresses appear in the author field of every commit on those accounts. Git records the author email at commit time from the local git configuration of the machine that made the commit.

WHOIS and DNS records for carox.tech:

Creation Date:  2025-07-19
Updated Date:   2025-08-01
Registrar:      Namify Domains Inc
Name Servers:   raphaela.ns.cloudflare.com
                uriah.ns.cloudflare.com

DNS:
  A record:  none
  MX:        route1.mx.cloudflare.net (priority 44)
             route2.mx.cloudflare.net (priority 84)
             route3.mx.cloudflare.net (priority 28)
  TXT:       v=spf1 include:_spf.mx.cloudflare.net ~all

The domain has no A record and no web presence. The MX records point to Cloudflare Email Routing, a free service that forwards inbound email from a custom domain to an external inbox. The destination inbox is not publicly recoverable from DNS.

The domain was created July 19, 2025 and updated August 1, 2025 β€” approximately 10 months before the cluster's repository generation run on May 12, 2026. It predates the provisioning event.

A Second Malformed Co-Author Address

In addition to the hajigur69 co-author trailer, a second co-author line appears on commits across 8 of the 9 cluster accounts:

Co-authored-by: v <[email protected]>

There is a GitHub account with login v, internal ID 627846. Its correctly formatted noreply address is [email protected]. The string in these commits β€” [email protected] β€” is missing the numeric ID prefix that GitHub generates automatically during an authenticated push. It cannot be produced by a normal authenticated session.

The most likely explanations: a user.email set manually in a local git config, a placeholder from a development environment not replaced before deployment, or a test identity carried into production unchanged. All three produce the same result: consistent across 8 of 9 accounts, indicating it was set once and not audited.

This is not an attribution of the v GitHub account to this operation. That account's correctly formatted address is not present in these commits.

What the Repository Evidence Does and Does Not Show

What the data shows directly:

  • 552 repositories were created across 9 accounts in a 34-minute window on a single day
  • Every repository contains a consistent embedded comment format with a fallback_ prefix, generation timestamp, and non-sequential job ID
  • No repository in the cluster contains functional implementation code in any sampled file
  • No repository has stars, forks, CI configuration, issues, or pull requests
  • All repositories were generated from a shared template, evidenced by the LICENSE URL substitution error
  • The same authenticated GitHub identity (66867581+hajigur69) is present in commit metadata across the cluster and in that identity's own repository

What the data does not show directly:

  • Who controls the 9 cluster accounts
  • What the repositories or the follow botnet are used for after provisioning
  • Whether hajigur69 is the operator, a collaborator, or an identity whose credentials were used without their knowledge
  • Whether the absence of implementation code indicates any specific intended use

The downstream use of this infrastructure is an open question. The confirmed finding is the shared generation pipeline, the common commit identity, and the behavioral coordination documented in Part 1.

An Earlier Operation: The Same Fingerprints, Nine Months Prior

The 66867581+hajigur69 co-author string and the fallback_ generator artifact do not appear for the first time in May 2026.

GitHub's commit search API returns the same string across thousands of commits from a cluster of 22 accounts in a July–August 2025 window:

2025-07-08..2025-07-14  β†’  1,738 hits
2025-07-15..2025-07-21  β†’    701 hits
2025-07-22..2025-07-31  β†’    949 hits
2025-08-01..2025-08-15  β†’  7,194 hits
2025-08-16..2025-08-31  β†’      0 hits

Four accounts from the 2026 follow botnet cluster β€” canestein, hazexone, domcomit, kylehyne β€” are present in this earlier commit set. The activity stops completely on August 16, 2025. The cause of that stop is not established by this data.

Lyne6666: Account Creation and Repository Generation

Lyne6666 is a GitHub account created May 3, 2025 with 163 public repositories. The GitHub API returns a creation timestamp of July 9, 2025, 18:55 UTC for all 163 repositories. Multiple commits across these repositories share the same minute-level timestamp.

The LICENSE file SHA across all 163 repositories:

8aa26455d23acf904be3ed9dfb3a3efe3e49245a

Git computes hashes from file content. An identical SHA across 163 repositories means 163 identical LICENSE files. A single source file was copied into every repository without modification.

Repository names follow the pattern {Tech}{Testnet}{Function}{Suffix}:

TPUTestnetSystemSolutionsNext
DAOTestnetAIKitPro
IoTTestnetPlatformLabsX

The install section of every README contains:

pip install git+https://github.com/Lyne6666/{RepoName}.git

This instruction is present across all 163 repositories. No postinstall hook content was confirmed in the repositories examined. The presence of the install vectors is a direct observation; what a developer who followed these instructions would receive is not established by this analysis.

uhsr: Commit Volume and Account Metadata

The Lyne6666 repositories contain [email protected] in their commit author email fields. eteb.me is a private domain with WHOIS privacy protection via Identity Digital. The account uhsr was created July 10, 2025 β€” one day after Lyne6666's mass repository creation timestamp.

At time of retrieval: 237 public repositories, 2,972 followers, 30,778 following.

GitHub API commit volume for uhsr by month:

July 2025:      1,382 commits
August 2025:      247 commits
September 2025:    21 commits
October 2025:      96 commits

July 2025 accounts for 71% of uhsr's all-time commit count at the time of retrieval.

The Backdated Commit History

uhsr/AssetMarket contains a .Logs file with approximately 365 entries spanning January 1, 2025 through December 31, 2025. Each entry follows the format: Logs: YYYY-MM-DD <8charToken>.

The repository creation date, returned by the GitHub API:

curl -s "https://api.github.com/repos/uhsr/AssetMarket" | python3 -c \
  "import json,sys; r=json.load(sys.stdin); print(r['created_at'])"
# 2025-08-02T16:29:22Z

The root commit, retrieved by paginating the commit history to its earliest entry:

SHA:            4f8f47697eb89c8818820ca92348be01c4544878
Message:        Logs on 2025-01-01
Author date:    2025-01-01T14:47:47Z
Committer date: 2025-01-01T14:47:47Z
Author email:   [email protected]

The repository did not exist until August 2, 2025. The root commit carries an author date of January 1, 2025 β€” 213 days earlier.

Git stores two timestamps per commit: GIT_AUTHOR_DATE and GIT_COMMITTER_DATE. Both are user-configurable before a push. When only the author date is overridden, the committer date retains the real push timestamp, producing a detectable mismatch. In the AssetMarket root commit, both fields are set identically to 2025-01-01T14:47:47Z. The mismatch that would normally expose backdating is not present.

The .Logs file content β€” daily entries with 8-character tokens across a full calendar year β€” is consistent with bulk generation rather than incremental accumulation, but that is an interpretation of the content pattern, not a directly provable fact.

The Generator Artifact in the 2025 Repositories

Fetching the raw README content of uhsr/AssetMarket returned this HTML comment at the top of the file:

<!-- fallback_AssetMarket_20250802163009_95172 -->

The same format as the 2026 cluster: fallback_ prefix, repo name variable, generation timestamp, and a numeric identifier.

The same comment was present in two additional repositories:

uhsr/SmartContract  β†’  <!-- fallback_SmartContract_20250802162757_83653 -->
uhsr/TokenLab       β†’  <!-- fallback_TokenLab_20250802161931_80263 -->

Three repositories, three comments, with timestamps spanning a 38-minute window on August 2, 2025:

16:19:31  TokenLab      β†’ trailing ID: 80263
16:27:57  SmartContract β†’ trailing ID: 83653
16:30:09  AssetMarket   β†’ trailing ID: 95172

The trailing numeric identifiers increase across the three runs but not by a fixed increment β€” gaps of approximately 3,390 and 11,519 respectively. On Linux systems, process IDs are assigned sequentially; irregular gaps are consistent with other processes running between jobs consuming PID assignments. This is an interpretation of the pattern, not a definitive conclusion about the execution environment.

The fallback_ prefix is present in all three 2025 artifacts and in all 552 2026 repositories. The format is identical across both operations: fallback_{reponame}_{YYYYMMDDHHMMSS}_{numericID}.

The Stargazer Overlap

The following repositories had star counts in the range of 49–83 at time of analysis: AssetMarket (83 stars), SmartContract (50), DigitalWallet (49), BlockchainKit (36).

Pulling the full stargazer lists via the GitHub API and computing intersections:

AssetMarket ∩ DigitalWallet ∩ SmartContract = 33 accounts

33 accounts starred all three repositories β€” 67% of DigitalWallet's total star count from a single overlapping pool. For unrelated repositories with independent audiences, overlap at this concentration is not consistent with organic discovery; it would require the same users to independently find and star three separate, unpromotable repositories with no followers, no forks, and no search visibility.

The July 11, 2025 batch β€” 83 repositories created in a single day β€” showed the following star distribution:

β˜…2:  64 repositories  (77%)
β˜…1:  19 repositories  (23%)
β˜…0:   0 repositories

Every repository in this batch received at least one star. The distribution has no zero-count entries and no values above 2 for this batch, producing a uniform two-tier pattern with no variance.

Two accounts from the 33-account overlap pool β€” SAPH1TE and ahnshy β€” also appear in the stargazer lists for Lyne6666 repositories. The uhsr cluster and the Lyne6666 cluster share no observable social graph overlap β€” different account creation dates, different repository naming patterns, no mutual followers or following relationships found. The two accounts appearing in both stargazer pools is the only cross-cluster link found in this data.

What produced the 33-account overlap and the two-tier star distribution is not established by this data. The overlap pattern is documented as an observable finding.

mohammadtzs

One fork of DigitalWallet exists: it was made by mohammadtzs. Account created March 2025, 506 public repositories, 100 forks. All 100 forks are from accounts that returned 404 at time of retrieval β€” the accounts have been deleted or suspended. Fork names included alork1, alork2, alork3, alorki1.

mohammadtzs also appears in the 33-account stargazer pool described above.

Observable facts: this account forked a uhsr cluster repository and is present in the shared stargazer pool. Account age, repository count, fork history, and the status of the forked-from accounts are all directly retrievable via the API.

October 2025: Repository Names

uhsr's commit activity dropped to 21 commits in September 2025 and returned to 96 in October. The October commits are concentrated in a single 15-minute window on October 20, 2025, between 05:04 and 05:19 UTC, across seven repositories:

awesomepythonTech
freeprogrammingbooksHub
publicapisAI
codinginterviewuniversityTools
developerroadmapLab
systemdesignprimerCloud
buildyourownxTools

The names append suffixes (Tech, Hub, AI, Tools, Lab, Cloud, X) to terms matching the names of widely-followed GitHub repositories:

  • vinta/awesome-python (290,000+ stars)
  • EbookFoundation/free-programming-books (340,000+ stars)
  • public-apis/public-apis (320,000+ stars)
  • jwasham/coding-interview-university (310,000+ stars)
  • kamranahmedse/developer-roadmap (300,000+ stars)
  • donnemartin/system-design-primer (280,000+ stars)
  • codecrafters-io/build-your-own-x (330,000+ stars)

None of the seven repositories contain implementation content. The description field of developerroadmapLab contains the string "enterprise enterprise-grade" β€” a duplicated token consistent with a template variable that was substituted twice or a template field whose value contained a placeholder that was not resolved before being written to the description.

Alternative Explanations

Before treating the connection between the 2025 and 2026 operations as confirmed attribution to a single operator, it is worth asking what else could produce these observations.

Could the hajigur69 co-author identity appear in unrelated operations by coincidence? The GitHub noreply format embeds a numeric account ID that is immutable and account-specific. The same numeric ID (66867581) appearing across thousands of commits in a 2025 commit-farming cluster and across all 552 repositories in the 2026 follow botnet cluster is not consistent with coincidence. The identity would have to be re-used deliberately or the same credentials would have to have been used in both operations.

Could the fallback_ artifact format be from a widely distributed open-source tool? Possible. If the fallback_ prefix is a convention from a publicly available README generation tool, its presence in both operations would indicate both operations used the same tool, not necessarily the same operator. No such tool was identified in the course of this research. The artifact format is not established as unique to a single actor.

Could the four accounts present in both the 2025 and 2026 operations be coincidentally shared? Four accounts from the 9-account 2026 follow botnet cluster β€” canestein, hazexone, domcomit, kylehyne β€” appear in the 2025 commit-farming activity set. These accounts were also identified in Part 1 as exhibiting Jaccard following similarity of 0.99+. Their presence across both operations is documented as a factual overlap. Whether that overlap reflects shared control is an inference.

I am not establishing that a single individual or organization controls both operations. I am documenting that the same authenticated GitHub identity, the same generator artifact prefix and format, and four of the same accounts appear across both.

Summary of Confirmed Findings

Finding Method
Cluster expanded to 9 accounts, all Jaccard β‰₯ 0.98 API-derived following list comparison
All 552 repos created May 12, 2026 in a 34-minute window Embedded HTML comment timestamps, GitHub API
<!-- fallback_NAME_TIMESTAMP_ID --> in every README Direct raw file fetch, all 9 accounts
mariwatts hardcoded in LICENSE URLs across all foreign accounts Direct raw file fetch, multiple accounts
66867581+hajigur69 co-author on all cluster commits Raw commit data, GitHub API
66867581+hajigur69 author on hajigur69's own repository Raw commit data, GitHub API
66867581 = hajigur69's GitHub numeric ID GET /users/hajigur69
[email protected] lacks numeric ID prefix Raw commit data, canestein/BlockLink
[email protected], [email protected] in commit author fields Raw commit data
carox.tech: no A record, Cloudflare MX only, created July 2025 WHOIS, DNS
All 552 repos: no stars, no forks, no CI, no issues, no PRs GitHub API
Same fallback_ format present in 2025 uhsr repositories Direct raw file fetch
uhsr/AssetMarket root commit dated 213 days before repo creation GET /repos/uhsr/AssetMarket/commits, GET /repos/uhsr/AssetMarket
Root commit SHA with both date fields set to 2025-01-01 4f8f47697eb89c8818820ca92348be01c4544878
PID artifacts in 3 README files, same machine, 38-minute window Direct raw file fetch, timestamp analysis
33-account pool appearing in all three high-value stargazer lists Stargazer API, cross-reference
SAPH1TE, ahnshy in both uhsr and Lyne6666 stargazer lists Stargazer API, cross-cluster comparison
canestein, hazexone, domcomit, kylehyne in both 2025 and 2026 operations Commit search API, Part 1 cluster data
October 2025 repos named after widely-starred GitHub repositories GitHub API, direct name comparison

Disclosure

This report has been submitted in full to GitHub Trust & Safety with API-verifiable evidence including the root backdated commit SHA (4f8f47697eb89c8818820ca92348be01c4544878), the generator artifact URLs, the 33-account stargazer overlap, and the complete account list.

All data was retrieved via the GitHub REST API v3 with authenticated requests. No accounts were accessed beyond their public API surface. No systems were compromised.

The accounts canestein, hazexone, domcomit, and kylehyne appear in both this report and Part 1. All account names published here are publicly visible GitHub profiles. This methodology is only verifiable if the data is reproducible.

If you have seen the hajigur69 co-author string or the fallback_ artifact pattern in your own repositories' commit histories, that is the fingerprint documented here. Worth reporting.

All tooling used in this investigation is in BANANA_TREE.

Comments (0)

Sign in to join the discussion

Be the first to comment!