TL؛ DR
A PyPI package named gcli-control shipped a complete Windows remote-access tool: keystroke logging, webcam and microphone capture, clipboard monitoring, browser-credential access, screen control, persistence, privilege elevation, and a self-advertised "140+ commands." It did not hide what it was: the package's own PyPI summary described it as a "Remote access tool via npoint.io".
The detail worth pausing on is that phrase "via npoint.io." Rather than call home to a dedicated server, the implant used npoint[.]io (a free, legitimate service for hosting small JSON documents) as its command-and-control relay. The operator writes commands into a JSON bin; the implant polls that bin, executes, and writes results back. No attacker-owned domain to block, no fresh IP to flag: the traffic goes to a service developers use every day.
Six versions were published in roughly thirteen and a half hours, each more capable than the last. Every one of them was scored ml_predicted_safe by an automated classifier before manual review reclassified the family as malicious.
آناتومی حمله
gcli-control installs the import package gcli, a 35-module Python codebase. There are no install-time hooks — nothing runs during نصب پیپ. The capability lives in the modules themselves, invoked once the tool runs, and the module layout reads like a product spec sheet:
| حوزه قابلیت | ماژول ها |
|---|---|
| Host surveillance | keylog, webcam, audio, clipboard, desktop, monitoring |
| Credential & data access | browser, forensics, fileops, transfer, users |
| Foothold & escalation | persistence, elevator, registry, security |
| Host & network recon | system, processes, network_config, wifi, bluetooth, netutils |
| Command & control | client, host, session, protocol, npoint, crypto, encrypt |
The command channel is the interesting part. Most remote-access tooling reaches a server the operator controls — an IP, a domain, a hosting provider that can be reported and taken offline. gcli-control instead treats a free JSON-bin service as a dead-drop. npoint module reads and writes small JSON documents on npoint[.]io over ordinary HTTPS; the عضو سازمانهای سری ومخفی/رمزگذاری modules wrap the exchanged payloads so the bin contents are not plaintext commands. The effect is a mediated, encrypted relay:
- The operator drops an (encrypted) instruction into a JSON bin.
- The implant, running on the victim host, polls that bin, decrypts, executes one of its command handlers, and writes the (encrypted) result back.
- To a network monitor, the victim is simply talking to npoint[.]io — a service with a legitimate reason to appear in developer traffic.
There is no second-stage download and no obfuscated loader here: the capability ships whole, in readable Python, and the only “hiding” is the choice of relay and the encryption of the relayed payloads.
Why a JSON-bin dead-drop is operationally attractive is worth spelling out, because it explains why we expect to see the pattern again:
- No operator-owned endpoint. There is no C2 domain to register, no VPS to rent, and nothing for a defender or registrar to seize. Takedown of the بسته does not touch the channel; takedown of the کانال means asking a general-purpose SaaS to police one document among millions.
- Reputation laundering. Outbound HTTPS to a well-known developer service carries none of the reputation penalties a fresh domain or a raw IP would. Many egress-filtering setups allow it implicitly.
- Asynchrony and deniability. A polling model — the implant fetches a document on an interval rather than holding an open socket — produces traffic that looks like periodic API polling, not an interactive session. Encrypting the document contents means even an analyst who finds the bin sees ciphertext, not a command list.
- Trivial rotation. Moving to a different bin, or a different note/paste service entirely, is a one-line configuration change for the operator. Any blocklist keyed to the specific relay is stale the moment it ships.
The trade-off the operator accepts is throughput and latency: a dead-drop relay is slower and lower-bandwidth than a direct connection. For a surveillance-and-control implant that mostly issues short commands and collects results over time, that trade is easy to make.
گاهشمار
The family escalated fast. Ticket-creation timestamps for the flagged versions place the whole observed arc inside about thirteen and a half hours, and the scanner’s own evidence count grew alongside the code — from a couple of flagged sites in the first version to fourteen in the latest.
| نسخه | اولین بار دیده شد (UTC) | توجه داشته باشید: |
|---|---|---|
0.1.0 | 2026-07-21 12:59 | Initial upload; minimal flagged surface |
0.5.0 | 2026-07-21 18:01 | Capability expands |
0.2.0 | 2026-07-21 18:03 | (version numbering not monotonic with upload order) |
0.6.0 | 2026-07-22 00:44 | Broader module set |
0.7.0 | 2026-07-22 01:58 | Near-complete toolkit |
0.7.1 | 2026-07-22 02:28 | Latest; 35 modules, full capability |
The version numbers were not published in strict order, but the direction is clear: a small first cut, then rapid iteration toward the fully-featured 0.7.1. This is the shape of a project under active development being pushed to a public registry as it grows, not a one-shot drop.
شاخص های سازش
All indicators below were confirmed against the on-disk package contents and a deterministic indicator scan of version 0.7.1; none are speculative.
| نوع | شاخص |
|---|---|
| Package (PyPI) | gcli-control, versions 0.1.0, 0.2.0, 0.5.0, 0.6.0, 0.7.0, 0.7.1 |
| Import package | gcli |
| C2 relay | npoint[.]io (JSON-bin dead-drop; encrypted payloads) |
| Stated repository | github[.]com/gcli-control/gcli |
| Behavioral fingerprint | Co-located surveillance modules: keylog, webcam, audio, clipboard, browser, plus persistence, elevator, and a client/host/protocol command layer in one package |
| نصب hooks | None: capability runs at tool runtime, not during install |
Defender note: the strongest durable signal is not the domain (a relay host rotates trivially) but the شکل دادن به: a single package that bundles three or more distinct host-surveillance primitives و routes a command/response loop through a public content-hosting service. Blocking npoint[.]io outright is impractical for most shops; alerting on an unexpected process that both captures input devices and talks to a JSON-bin service is far more robust.
Observed behavior & framing
Two things make this sample unusual, and both are observable facts rather than inferences about motive.
It advertised itself. The package summary distributed on PyPI enumerated the capabilities in plain language — remote access, desktop control, user management, webcam, audio, keylogger, persistence, browser data, WiFi, registry, “140+ commands.” There was no attempt to pass the code off as a build helper, a CLI wrapper, or an AI-agent utility, which is the more common disguise we see on public registries. Whether that openness reflects a red-team tool published without access controls or something else is a question the package contents alone do not settle; what is certain is that a working, general-purpose remote-access and surveillance toolkit was installable by anyone with شکستن.
It leaned on trust in a benign service. با استفاده از npoint[.]io as the relay is the defining technique. It is an example of a broader pattern — routing C2 through a legitimate SaaS (paste sites, JSON bins, chat webhooks, cloud docs) so that the malicious traffic blends into normal developer activity and there is no operator-owned endpoint to seize. The payloads on the relay were encrypted, so the bin contents would not read as commands to a casual observer.
The publisher signals are thin and generic. The package declared an نویسنده of “gcli contributors” and an MIT license, and pointed its homepage and repository fields at github[.]com/gcli-control/gcli. None of that is verification: an author string is free text, an MIT license header costs nothing, and a repository URL in package metadata is a claim, not a proof of provenance. The pattern — a brand-new name, a generic collective author, and a self-referential org/repo created around the package — is what a project looks like when it is stood up specifically to carry the code, rather than an established tool that happens to have grown a remote-control feature. We note these as observations; they are consistent with, but do not by themselves establish, a purpose-built distribution.
We describe the disposition as malicious on the basis of capability and delivery: a complete, runnable remote-access and surveillance implant, distributed on a public package index with a covert relay. We do not attribute a target or a motive.
Impact, trends & what defenders can do
A blind spot for disguise-oriented triage. Much automated package triage keys on the پنهان کردن سیگنالهای typical registry malware — obfuscated blobs, install-time hooks, credential-harvesting one-liners. A package that is simply openly a RAT, with clean readable code and no install hook, presents none of those tells and can slip past heuristics that expect concealment. The signals that reliably catch this class are structural rather than disguise-based: a capability census (how many distinct host-surveillance primitives co-exist in one package) and C2-shape analysis (a command/response loop routed through a general-purpose content-hosting service). Those checks fire regardless of how honest or مبهم the packaging is.
The SaaS-as-C2 trend. Abusing a legitimate hosting service as a dead-drop is not new, but it keeps working because the defensive cost of blocking the service is high and the offensive cost of switching services is near zero. Expect more of it. Network defenses keyed to specific bad domains age out immediately; behavioral rules (“this process reads the clipboard and the webcam and then talks to a note-hosting API”) do not.
A concrete detection sketch. The durable rule does not name npoint[.]io at all. It combines two observations that are individually common but jointly rare on a normal developer or CI host:
alert when a single process, within one session, both:
(A) accesses a host-surveillance primitive — input device (keyboard/mouse hook), camera, microphone, screen capture, clipboard read-loop, or a browser credential store ("Login Data" / "Local State" / DPAPI); AND
(B) makes outbound requests to a public content-hosting / paste / JSON-bin / chat-webhook service then raise for review, regardless of the specific service in (B).
Neither half is suspicious alone: plenty of legitimate tools screenshot, and plenty post JSON to a hosting API. The conjunction inside one short-lived process is the signal, and it survives any relay rotation.
Practical steps for teams:
- Treat public package installs on developer and CI hosts as an execution boundary, not a convenience — a RAT on a build agent is a RAT with your secrets.
- Prefer allowlisted internal mirrors; a package literally named for remote control and describing a keylogger should never resolve on a corporate index.
- Alert on the ترکیب — input-device or screen capture plus outbound traffic to a content/paste/JSON-bin service — rather than on any single primitive, which has benign uses in isolation.
- Do not rely on an automated “safe” score as a terminal verdict for packages with broad host-access capability; route them to human review.
The package family has been classified malicious and referred for registry removal. Because a relay-based C2 leaves no operator-owned host to sinkhole, the durable defensive value is in the behavioral fingerprint above, not in any single blocklist entry.





