← Voltar ao feed
critical cryptocurrency

Backdoored fragment-api-py 14.4.2 on PyPI drains TON and USDT wallets at client startup

1 fonte(s) · 1 atualização(ões) · publicado 09/11/2026 21:00 · coletado há 1 hora

A backdoored release of fragment-api-py, a Python client for Telegram's Fragment marketplace, was published to PyPI as version 14.4.2 on 2026-11-08 (pypi.org). The code runs when a client is opened with a wallet seed and sends the wallet's TON and Tether (USDT) to an attacker-controlled address before any purchase. At least two wallets were emptied, losing 0.88 TON and 43.98 TON, and the attacker address took in about 44.87 TON across the three inflows. The malicious files are the 13.0.0 code with a few edited files and a higher version string, so a routine upgrade selects the package. No CVE, GitHub Security Advisory or maintainer statement was found in the pages opened for this report, and the PyPI file listing shows the upload without provenance (pypi.org).

Detalhes técnicos

  • Sweep logic: The function sweep_wallet_to_self() is disguised as a consolidation feature. It hardcodes the destination address at line 172, keeps 0.1 TON for the transfer and a 0.02 TON margin (plus 0.06 TON when USDT is held), and sends the rest of the TON and all USDT in one batched wallet message.
  • Triggers: A call added to __aenter__ (client.py:295) runs the drain on context entry, and a second call at the start of execute_prepared() (utils/wallet.py:410) covers code that skips async with. A flag and a lock limit the drain to once per client.
  • Version evidence: A byte-level comparison of the 14.4.2 wheel with earlier wheels found the closest base is 13.0.0 (28 of 32 files identical). Changed files are __init__.py (version string only), client.py, types/models.py and utils/wallet.py, and tests/test_client.py and tests/test_preparation.py were removed. File timestamps place the backdoor's writing on 2026-10-12, about four weeks before publication.
  • Victims and attacker wallet: Victim 1 did not report the theft and was found in the attacker wallet history. The wallet held 0.999963599 TON, and the outflow matches that balance minus 0.12 TON. Three seconds later the same wallet paid the library's own FEE_ADDRESS (types/constants.py), which ties the wallet to fragment-api-py. The drain happened about six hours after upload. The attacker wallet has been active since at least 2026-10-22, moved about 1,000 TON on 2026-11-01, and paid one unidentified address on 2026-10-30, 2026-10-31 and 2026-11-01.
  • Release path: The 14.4.2 release has no matching tag or commit, and the public GitHub tags end at v14.4.1. The release workflow publishes with a long-lived PyPI API token, and most releases are built locally. The wheel carries the build profile of a Windows machine set to UTC+4, which matches the maintainer's local builds but can be spoofed. A compromised machine, a stolen token or an insider all fit the evidence.
  • ATT&CK: T1195.002 (compromise of a software supply chain) and T1657 (financial theft).

Remediação

  • Run vet scan -D . on the project, check pip show fragment-api-py, and grep site-packages for the attacker address, sweep_wallet_to_self and _ensure_swept.
  • Remove 14.4.2 and pin a release you have verified. The article uses 14.4.1 as its baseline, but no independent verification of that release was done for this report.
  • Treat any seed that ran 14.4.2 as exposed. Move remaining assets to a new wallet created from a new seed on a clean machine.
  • Report the project to PyPI as malware, since the PyPI page offers that option (pypi.org).
  • Watch for deposits to the attacker address and the two unattributed recipients named in the IOC list, and share them with exchanges and investigators.

Linha do tempo

  1. safedep.io ↗ · pub. 09/11/2026 21:00 · coletado 10/11 09:00 primeiro registro

    Backdoored fragment-api-py 14.4.2 on PyPI drains TON and USDT wallets at client startup

    ler a análise desta fonte

    A backdoored release of fragment-api-py, a Python client for Telegram's Fragment marketplace, was published to PyPI as version 14.4.2 on 2026-11-08 (pypi.org). The code runs when a client is opened with a wallet seed and sends the wallet's TON and Tether (USDT) to an attacker-controlled address before any purchase. At least two wallets were emptied, losing 0.88 TON and 43.98 TON, and the attacker address took in about 44.87 TON across the three inflows. The malicious files are the 13.0.0 code with a few edited files and a higher version string, so a routine upgrade selects the package. No CVE, GitHub Security Advisory or maintainer statement was found in the pages opened for this report, and the PyPI file listing shows the upload without provenance (pypi.org).

    Technical Details

    • Sweep logic: The function sweep_wallet_to_self() is disguised as a consolidation feature. It hardcodes the destination address at line 172, keeps 0.1 TON for the transfer and a 0.02 TON margin (plus 0.06 TON when USDT is held), and sends the rest of the TON and all USDT in one batched wallet message.
    • Triggers: A call added to __aenter__ (client.py:295) runs the drain on context entry, and a second call at the start of execute_prepared() (utils/wallet.py:410) covers code that skips async with. A flag and a lock limit the drain to once per client.
    • Version evidence: A byte-level comparison of the 14.4.2 wheel with earlier wheels found the closest base is 13.0.0 (28 of 32 files identical). Changed files are __init__.py (version string only), client.py, types/models.py and utils/wallet.py, and tests/test_client.py and tests/test_preparation.py were removed. File timestamps place the backdoor's writing on 2026-10-12, about four weeks before publication.
    • Victims and attacker wallet: Victim 1 did not report the theft and was found in the attacker wallet history. The wallet held 0.999963599 TON, and the outflow matches that balance minus 0.12 TON. Three seconds later the same wallet paid the library's own FEE_ADDRESS (types/constants.py), which ties the wallet to fragment-api-py. The drain happened about six hours after upload. The attacker wallet has been active since at least 2026-10-22, moved about 1,000 TON on 2026-11-01, and paid one unidentified address on 2026-10-30, 2026-10-31 and 2026-11-01.
    • Release path: The 14.4.2 release has no matching tag or commit, and the public GitHub tags end at v14.4.1. The release workflow publishes with a long-lived PyPI API token, and most releases are built locally. The wheel carries the build profile of a Windows machine set to UTC+4, which matches the maintainer's local builds but can be spoofed. A compromised machine, a stolen token or an insider all fit the evidence.
    • ATT&CK: T1195.002 (compromise of a software supply chain) and T1657 (financial theft).

    Remediation

    • Run vet scan -D . on the project, check pip show fragment-api-py, and grep site-packages for the attacker address, sweep_wallet_to_self and _ensure_swept.
    • Remove 14.4.2 and pin a release you have verified. The article uses 14.4.1 as its baseline, but no independent verification of that release was done for this report.
    • Treat any seed that ran 14.4.2 as exposed. Move remaining assets to a new wallet created from a new seed on a clean machine.
    • Report the project to PyPI as malware, since the PyPI page offers that option (pypi.org).
    • Watch for deposits to the attacker address and the two unattributed recipients named in the IOC list, and share them with exchanges and investigators.