Wednesday, September 30, 2026

Inside Koi: a Python shell handler built for lab work, pivoting and LLM-driven sessions

Inside Koi: a Python shell handler built for lab work, pivoting and LLM-driven sessions

Koi is a multi-session reverse shell handler with PTY upgrades, Layer 3 tunneling, payload obfuscation and an MCP server, aimed at authorized pentest labs and CTF practice.

Toolb3rt1ng/Koi — multi-session reverse shell handler with PTY upgrade, modules, tunneling and MCP control
CategoryPython C2/shell handler for authorized offensive security training
Primary UseManaging multiple reverse shell sessions in labs like HTB/TryHackMe, upgrading raw shells to PTYs, and pivoting during authorized engagements
Safe UseIntended for authorized penetration tests, CTF boxes, and local dockerized lab targets you own; the author documents it in HTB/THM contexts and provides screenable mode for demos
Telemetry NoteSession traffic is plaintext by default (TLS/HTTP C2 still on the roadmap), shells connect back on a known port, and obfuscation leaves static-analysis artifacts (XOR keys, char-array constructions) that EDR and blue teams can signature

Koi positions itself, in its author's words, as a fast, feature-rich shell handler with a pretty interface — a direct answer to the friction of juggling raw netcat listeners during lab work. Written in Python, GPL-3.0 licensed, and installed as a pipx package, it is explicitly aimed at the HTB and TryHackMe crowd, which the repo's own topic tags confirm. The author is candid that the project is still under development, with transport hardening like TLS and HTTP C2 listed as work-in-progress rather than shipping features. That honesty matters when you are deciding where this tool fits in your authorized workflow.

The core value proposition is multi-session management: Koi catches several reverse shells simultaneously, lets you list, tag, background, and switch between them without dropping anyone, and restores sanity to the parts of a lab exercise that normally degenerate into a wall of terminal tabs. The signal handling is thought through from an operator's perspective — Ctrl+Z backgrounds the active session locally while Ctrl+C forwards SIGINT to the remote process, so you never accidentally murder your own listener by reflex. Small ergonomic details like that are usually what separate a tool people actually use from one they screenshot once.

Once a raw shell lands, Koi can upgrade it to a full PTY via its upgrade command. On Linux this is the classic pty.spawn technique executed with TERM=xterm-256color and terminal resize metadata attached, restoring tab completion and sane signal behavior. On Windows, the author skips cmd entirely and instead leans on an obfuscated ConPtyShell variant: the script is fetched from GitHub, cached locally, its identifiers renamed, distinctive string literals rewritten as runtime char-array constructions, and the invocation delivered via -EncodedCommand. For defenders, that is a useful signature cluster to know — base64-encoded PowerShell invocations paired with split IEX/IWR patterns are exactly what mature EDR telemetry is built to catch.

The connect out feature is a nice operational touch: connect ssh user@host converts credentials you already hold into a registered session, with ssh used only as a delivery vehicle so the shell survives the SSH session ending. This reframes ssh from a management channel into a payload dropper within the handler's session model, which keeps everything in one process. It is worth noting for authorized users that this still requires valid credentials you legitimately control — it is a session-normalization feature, not a credential attack.

Where Koi gets genuinely interesting architecturally is its tunneling subsystem. The tunnel start <id> <cidr> command turns a shell into a Layer 3 pivot by running a userland TCP stack on the target — no root required, no dropped binary, Python only — with routing handled on the operator's side. For lab networks and segmented CTF ranges this is a clean pivot primitive, and the fact that it lives entirely in an interpreted process makes it easy to reason about what you are leaving on a box you own. The module system covers adjacent post-exploitation chores: enumeration, file transfer, pivoting, and AD collection, with an extension point for writing your own modules.

The built-in obfuscator — exposed as the standalone koifuscator shortcut — chains XOR encoding, hex, format strings, and char-array transformations for both Windows and Linux payloads. The README is refreshingly pragmatic about its limits: Koi claims to bypass casual and mid-tier EDR but explicitly concedes that expensive commercial EDR and heavily monitored environments may still flag activity. It also warns that stacking too many transformation layers can corrupt a payload into something unreadable. On the Linux side the rationale is less about antivirus and more about EDR/IDS signatures matching known reverse shell one-liners. This is the tool's most offensive-leaning surface, and it belongs strictly inside ranges you are authorized to test.

The MCP integration is the feature that makes Koi notable beyond its niche. Running koi --mcp exposes sessions, modules, and logs to an LLM client over a local server bound to 127.0.0.1:7331, authenticated with a bearer token printed at startup. Read-only access is the deliberate default; --mcp-allow-exec is the gate that lets a model execute commands and modules on targets. The author's own warning deserves quoting in spirit: with exec enabled, an LLM can run commands on every machine you hold a shell on, and session logs contain output from compromised hosts — attacker-controlled text flowing directly into your model's context. That is a prompt-injection surface every operator should think hard about before flipping that flag, even in a lab.

Operational hygiene is clearly a design concern. Every session is automatically logged and replayable through koireview, which doubles as documentation for writing up a lab box or an authorized engagement report. The screenable mode masks IPs and MAC addresses from output, explicitly intended for safe screen sharing during CTFs and live demos — a rare, thoughtful nod toward not doxxing your infrastructure or your teammates' boxes on stream.

Installation is standard Python packaging: pipx install koi-handler for the stable release, or git clone https://github.com/b3rt1ng/Koi followed by pipx install --editable . if you intend to develop custom modules. The listener defaults to binding 0.0.0.0:4010, with --host and --port flags for customizing — the README's own example uses a tunneled lab address. The payloads *interface* command prints pregenerated stagers bound to your chosen interface, which keeps the operator from hand-rolling syntax errors.

From a defensive research standpoint, Koi is worth studying even if you never run it. Its plaintext-by-default transport, static obfuscation techniques, and reliance on well-documented PTY upgrade patterns make it a good teaching artifact for what mid-tier offensive tooling looks like and what telemetry it generates. At 27 stars it is a young project, and the wiki carries the depth the README only summarizes. For authorized professionals working boxes they own, it is a competent, honest, and increasingly interesting handler.

The honest caveats — unfinished EDR evasion story, no TLS yet, LLM exec mode that demands caution — are all printed in the README itself rather than hidden. That transparency, combined with session logging, screenable mode, and a read-only-by-default MCP posture, suggests an author thinking about operator safety as much as capability. Treat it as a lab-and-engagement tool within scope you control, and it earns its place in the toolkit.

Official project repository for b3rt1ng/Koi.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.