
Penelope Shell Handler
Penelope is a modern shell handler for penetration testers and CTF players. It provides a more capable alternative to basic netcat listeners, adding automatic PTY upgrades, session management, logging, file transfers and helper modules.
Penelope runs on Unix-like systems, including Linux, macOS and FreeBSD, and requires Python 3.6+.
Penelope is available in Kali Linux:
sudo apt update
sudo apt install penelope
Penelope is implemented entirely with Python’s standard library, allowing it to run as a standalone script without any external dependencies:
wget -q https://raw.githubusercontent.com/brightio/penelope/refs/heads/main/penelope.py && python3 penelope.py
To install the latest upstream version directly from GitHub:
pipx install git+https://github.com/brightio/penelope
For a versioned and more stable release path, Penelope is also available on PyPI:
pipx install penelope-shell-handler
(*) Can be manually upgraded to PTY with the upgrade command
⚠️ Windows support is experimental and under active development.
set DisablePayloadHandler True--mcp switch (local HTTP, token-authenticated), driving the same shells alongside you

penelope # Listening for reverse shells on 0.0.0.0:4444
penelope -p 5555 # Listening for reverse shells on 0.0.0.0:5555
penelope -p 4444,5555 # Listening for reverse shells on 0.0.0.0:4444 and 0.0.0.0:5555
penelope -i eth0 -p 5555 # Listening for reverse shells on eth0:5555
penelope -a # Listening for reverse shells on 0.0.0.0:4444 and show sample reverse shell payloads
penelope -c target -p 3333 # Connect to a bind shell on target:3333
penelope ssh user@target # Get a reverse shell from target on local port 4444
penelope -p 5555 ssh user@target # Get a reverse shell from target on local port 5555
penelope -i eth0 -p 5555 -- ssh -l user -p 2222 target # Get a reverse shell from target on eth0, local port 5555 (use -- if ssh needs switches)
penelope -s <File/Folder> # Share a file or folder via HTTP

-s)Penelope can be used also as a quick HTTP file server.
penelope -s file.txt # Serve a single file on 0.0.0.0:8000
penelope -s /path/to/dir # Serve a whole folder
penelope -s a.sh b.elf notes.txt # Serve several items at once
penelope -s . -p 80 # Serve the current dir on port 80
penelope -s secret.txt -prefix xk9 # Hide behind a URL prefix: /xk9/secret.txt
penelope -s -u # Upload mode: accept PUT/POST into the CWD
penelope -s -u -ud /tmp/loot # Upload mode, store received files in /tmp/loot
On start, Penelope prints a ready-to-use link per interface (and an upload hint
when -u is set), so you can copy-paste straight into the target shell.
As shown in the video below, within only a few seconds we can:
https://github.com/brightio/penelope/assets/65655412/7295da32-28e2-4c92-971f-09423eeff178
Some Notes:
F12 to detach the PTY shell and go to the Main Menu. If the upgrade was not possible and you ended up with a basic shell, you can detach it with Ctrl+C. This also prevents the accidental killing of the shell.interact 1 you can just type i 1.
positional arguments:
args Arguments for -s/--serve and SSH reverse shell modes
options:
-p, --ports Ports (comma separated) to listen/connect/serve, depending on -i/-c/-s options
(Default: 4444/5555/8000)
Reverse or Bind shell?:
-i, --interface Local interface/IP to listen. (Default: 0.0.0.0)
-c, --connect Bind shell Host
-j, --jump Reverse shell jump endpoints
Hints:
-a, --payloads Show sample reverse shell payloads for active Listeners
-l, --interfaces List available network interfaces
-h, --help show this help message and exit
Session Logging:
-L, --no-log Disable session log files
-T, --no-timestamps Disable timestamps in logs
-CT, --no-colored-timestamps Disable colored timestamps in logs
Misc:
-M, --menu Start in the Main Menu
-m, --maintain Keep N sessions per target
-S, --single-session Accommodate only the first created session
-ms, --max-sessions Max active sessions per host (default 5, 0 = reject all new)
-C, --no-attach Do not auto-attach on new sessions
-U, --no-upgrade Disable shell auto-upgrade
-H, --keep-history Keep target shell history (do not set HISTFILE=/dev/null)
-O, --oscp-safe Enable OSCP-safe mode
--no-disk Keep all state in RAM (tmpfs); nothing persists to disk
MCP:
--mcp Enable the MCP server over local HTTP
--mcp-host Host/IP to bind (default: 127.0.0.1)
--mcp-port Port to bind (default: saved port, else a random free port persisted to ~/.penelope/mcp.json)
--mcp-token Bearer token (default: saved token, else auto-generated and persisted)
File server:
-s, --serve Run HTTP file server mode
-prefix, --url-prefix URL path prefix
-u, --upload Enable file upload (PUT/POST) to the server
-ud, --upload-dir Directory to store uploads (default: CWD)
Debug:
-N, --no-bins Simulate missing binaries on target (comma-separated)
-v, --version Print version and exit
-d, --debug Enable debug output
-dd, --dev-mode Enable developer mode
-cu, --check-urls Check hardcoded URLs health and exit
Penelope is designed to provide direct and flexible interaction with remote shells. Keep the following in mind when using it:
Terminal escape sequences: Penelope forwards terminal output from remote systems directly to your terminal emulator. Malicious remote processes may use terminal escape sequences to manipulate the screen, create misleading links, or interact with features such as the clipboard. This exposure is inherent to any tool that relays a remote shell to the local terminal (like SSH, telnet, netcat) and is not specific to Penelope. Use a terminal with appropriate security settings when connecting to untrusted systems.
Session logs: Session logs may contain credentials, tokens, commands and other sensitive information received from the target. Store them securely and use --no-log when logging is not required.
Unencrypted connections: Standard reverse and bind shell connections are not encrypted. Avoid using them over untrusted networks unless the traffic is protected by a secure tunnel or VPN.
MCP server (--mcp): When enabled, the MCP server grants full control over every active session (command execution, file transfer) to any client holding the bearer token, which is stored in ~/.penelope/mcp.json (0600). It binds to 127.0.0.1 and is token-authenticated. Keep the token secret and avoid exposing the server on untrusted networks.
⚖️ Disclaimer: Penelope is intended for authorized security testing, research and educational purposes only. Do not use it against systems without explicit permission.
cat may look corrupted. Filtering these escape sequences is planned to make log output smoother.Penelope’s core shell-handling features do not perform automatic exploitation, which makes them suitable for OSCP-style usage. However, exam rules can change, so always verify the current official OffSec rules before using any tool during an exam.
Some modules require extra caution:
If you want to avoid accidental rule violations, use the -O / --oscp-safe switch.
It depends on the type of shell upgrade in use:
F12Ctrl-D)Ctrl-C)In any case, the correct key is always displayed when you attach to a session. For example:

See peneloperc
This usually means you opened a new interactive shell, possibly under a different user. The Penelope agent only tracks the directory of the initial shell and keeps the permissions of the user from that first shell. The best workaround is to cd /tmp before opening a new shell, or, if you switched users, spawn a new reverse shell as the new user.
Your contributions are invaluable! If you’d like to help, please report bugs, unexpected behaviors, or share new ideas. You can also submit pull requests but avoid making commits from IDEs that enforce PEP8 and unintentionally restructure the entire codebase.
Penelope was the wife of Odysseus and is known for her loyalty and patience while waiting for him to return. The tool is named after her because it was built to be a faithful and stable shell handler for workflows that go beyond a basic listener.
| Feature | Unix-like target | Windows target |
|---|
| Auto-upgrade shell | PTY | readline(*) |
| Real-time terminal resize | ✅ | ❌ |
| Logging shell activity | ✅ | ✅ |
| Download remote files/folders | ✅ | ✅ |
| Upload local/HTTP files/folders | ✅ | ✅ |
| In-memory local/HTTP script execution with real-time output downloading | ✅ | ❌ |
| Local port forwarding | ✅ | ❌ |
| Spawn shells on multiple tabs and/or hosts | ✅ | ❌ |
| Auto-maintain N active shells per host (re-spawn on death) | ✅ | ❌ |