# TXTBOOK: Dependency-Confusion npm Campaign (993 Packages) Targeting T-Bank with DNS TXT-Staged Sliver Implant

> CloudSEK tracks TXTBOOK, an operator that published 993 malicious npm packages (1,156 versions, via 153 disposable web-library.net publisher accounts) squatting T-Bank (formerly Tinkoff) internal package names for dependency confusion. The loader is gated on T-Bank/CloudPayments hostnames and reassembles a native Sliver implant from several hundred DNS TXT records. The report documents intent and capability; no confirmed successful compromise is stated.

- **Published:** 2026-08-10T00:00:00Z
- **Last reviewed:** 2026-08-10T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-2991
- **ID:** TL-2026-2991
- **Severity:** HIGH
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Detections:** 9 · **IOCs:** 24 (full data via the Threadlinqs MCP server — Purple tier)

## Description

TXTBOOK is a dependency-confusion operation aimed at a single company, T-Bank (the Russian financial group formerly known as Tinkoff), run at a scale normally associated with indiscriminate registry flooding. Per CloudSEK (published 2026-08-10), the operator published 993 malicious packages (1,156 versions) to the public npm registry under names that reproduce T-Bank's internal, private namespace: BNPL (bnpl-* 156, dolyame-* 133), platform and operations tooling (devplatform-* 108, bigops-* 97, checkout-* 61, claims-* 41), the internal component framework (boxy-* 70), tinkoff-* (38) and statist-browser-typed-client-* analytics client libraries (54) that embed real internal service paths (e.g. mb.product.payments, sme.rko.conversionpayments.web, investaccounting.events, leasing.admin.events, dwh.chimera.base). The operator also registered names for T-Bank's openly published projects (tramvai-*, taiga-ui-proprietary-*); CloudSEK notes that public repositories disclose the private namespace structure. A minor cluster of four online-betting-related packages (<1%) is also reported. The knowledge of internal service paths and subsidiary relationships implies an internal-inventory source (CloudSEK infers a leaked lockfile/manifest, exposed registry index, code-search hit or insider; this is inference, not established).

The packages were published through 153 disposable npm accounts whose 12-character lowercase alphanumeric username matches a mailbox at web-library.net (130 accounts hold one package, 21 hold two, 2 hold three, so account-level takedown is nearly ineffective); one legacy account used a mail.ru address. The campaign began on PyPI in July 2026 (predecessor designation 2026-07-andreiiiiiii_i) and moved to npm with the execution trigger rebuilt for the new ecosystem.

Execution varied by version band to defeat hash clustering and signatures: early 5.x-9.x versions share a setup.js loader with byte-identical payloads; 11.x-12.x reintroduced a postinstall hook; the 20.x band (199 archives, same C2 as later bands) and the 33.x-35.x bands (23 and 98 archives) execute at import time through a randomized underscore-prefixed module (e.g. _adapter.js, _bridge.js, _init.js, _compat.js, _runtime.js) wrapped in a swallowed try/catch, with per-package payload variation and fragment-assembled indicators in the 35.x generation. On the PyPI side, a path-configuration file executed at interpreter start. Before contacting any command-and-control, the loader resolves a table of obfuscated victim hostnames (single-byte XOR; key 0x9C for Windows/macOS, 0x0E for Linux ARM64) - nexus.tcsbank.ru (Nexus artifact repository), apt.tcsbank.ru (Linux package repository) and alerts.cloudpayments.ru (CloudPayments alerting) - and proceeds only if they answer, ensuring execution inside the target network. Anti-analysis checks include hypervisor detection (SMBIOS vendor/product/serial, CPU flags), consumer-SSD model checks, a 4.6 GB physical-memory floor, timing checks and TLS-inspection avoidance (requires a pre-trusted CA); the sample self-terminates in five commercial sandboxes.

The third stage is not fetched over HTTP: the loader reassembles a native executable from several hundred DNS TXT records of a few hundred bytes each, which appears to network monitors as a burst of DNS queries. The payload is a Sliver implant (build timestamp 2026-07-04) with 79 of 82 message types confirmed from preserved Go reflection metadata: in-process .NET assembly execution, DLL sideloading, native/WebAssembly extensions, five token/privilege primitives, process migration, memory dumping, screenshots, offline registry hive reading, a full SSH client, Kerberos with constrained-delegation abuse, service control, pivot listeners, SOCKS proxy, port forwarding and WireGuard. Server responses are age-encrypted (X25519 + ChaCha20-Poly1305, not Sliver's native scheme) and Ed25519/minisign-signed; transport uses five interchangeable encoders (custom base64, gzip, hex, English word-pairs, PNG steganography). Two independent operator servers were identified by key partitioning (Server A: Windows x64 and Linux ARM64, key 262CA2380CC0AB31; Server B: Linux x64, key 68BAEB7614479037), both fronted by Cloudflare Workers spread over roughly two dozen accounts in two naming batches; a second staging domain was pre-positioned but dormant. Linux builds carried the operator's keys and C2 hostname in plaintext on disk, whereas Windows/macOS strings were encrypted. CloudSEK recovered keys by memory scanning and notes the implant seals beacons to whichever public key is in memory. No session was observed completing during analysis.

Timeline of operator activity: npm removed nine of the first ten names on 2026-08-01, publishing resumed about 25 hours later, and on 2026-08-03 the staging infrastructure was serving a valid native executable. CloudSEK records no confirmed compromise and no definitive attribution; the report documents intent and capability. The implant's lateral-movement, credential and tunneling features are recovered capabilities, not observed use. Any build that resolved a squatted name would, however, execute native code on import in a credential-rich build environment. Primary mitigation is registry scoping so that internal names cannot resolve against the public registry.

## MITRE ATT&CK

- T1195.001 Compromise Software Dependencies and Development Tools
- T1583.001 Domains
- T1585.002 Email Accounts
- T1583.007 Serverless
- T1608.001 Upload Malware
- T1588.002 Tool
- T1059.007 JavaScript
- T1036.005 Match Legitimate Resource Name or Location
- T1480 Execution Guardrails
- T1497.001 System Checks
- T1497.003 Time Based Checks
- T1027 Obfuscated Files or Information
- T1140 Deobfuscate/Decode Files or Information
- T1620 Reflective Code Loading
- T1071.004 DNS
- T1132.002 Non-Standard Encoding
- T1573.002 Asymmetric Cryptography
- T1001.002 Steganography
- T1090 Proxy
- T1134 Access Token Manipulation
- T1055 Process Injection
- T1558 Steal or Forge Kerberos Tickets
- T1021.004 SSH

## Sources

- [TXTBOOK: A Supply Chain Heist, Rehearsed in Public (CloudSEK)](https://www.cloudsek.com/blog/txtbook-a-supply-chain-heist-rehearsed-in-public)
- [TXTBOOK A Supply Chain Heist, Rehearsed in Public (mirror)](https://www.hendryadrian.com/?p=109564)
- [MITRE ATT&CK T1195.001 Compromise Software Dependencies and Development Tools](https://attack.mitre.org/techniques/T1195/001/)
- [MITRE ATT&CK T1071.004 Application Layer Protocol: DNS](https://attack.mitre.org/techniques/T1071/004/)
- [MITRE ATT&CK S0633 Sliver](https://attack.mitre.org/software/S0633/)
- [BishopFox Sliver C2 framework](https://github.com/BishopFox/sliver)
- [MITRE ATT&CK T1480 Execution Guardrails](https://attack.mitre.org/techniques/T1480/)
- [MITRE ATT&CK T1036.005 Masquerading: Match Legitimate Resource Name or Location](https://attack.mitre.org/techniques/T1036/005/)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-2991
