2012-06-29 05:18:28 +00:00
# -*- coding: binary -*-
2006-11-09 19:54:40 +00:00
require 'digest/md5'
2012-10-29 04:49:21 +00:00
require 'digest/sha1'
2006-01-02 07:49:52 +00:00
require 'stringio'
2013-01-08 04:32:43 +00:00
require 'cgi'
2005-09-30 06:48:52 +00:00
2013-02-24 19:10:16 +00:00
%W{ iconv zlib } . each do | libname |
begin
old_verbose = $VERBOSE
$VERBOSE = nil
require libname
rescue :: LoadError
ensure
$VERBOSE = old_verbose
end
2006-01-03 04:07:20 +00:00
end
2005-07-10 07:15:20 +00:00
module Rex
###
#
# This class formats text in various fashions and also provides
# a mechanism for wrapping text at a given column.
#
###
module Text
2009-03-09 05:18:33 +00:00
@@codepage_map_cache = nil
2010-02-12 05:08:16 +00:00
2005-09-30 06:40:35 +00:00
##
#
# Constants
#
##
2006-02-22 23:29:34 +00:00
2006-04-21 03:59:07 +00:00
States = [ " AK " , " AL " , " AR " , " AZ " , " CA " , " CO " , " CT " , " DE " , " FL " , " GA " , " HI " ,
" IA " , " ID " , " IL " , " IN " , " KS " , " KY " , " LA " , " MA " , " MD " , " ME " , " MI " , " MN " ,
" MO " , " MS " , " MT " , " NC " , " ND " , " NE " , " NH " , " NJ " , " NM " , " NV " , " NY " , " OH " ,
" OK " , " OR " , " PA " , " RI " , " SC " , " SD " , " TN " , " TX " , " UT " , " VA " , " VT " , " WA " ,
" WI " , " WV " , " WY " ]
2005-09-30 06:40:35 +00:00
UpperAlpha = " ABCDEFGHIJKLMNOPQRSTUVWXYZ "
LowerAlpha = " abcdefghijklmnopqrstuvwxyz "
Numerals = " 0123456789 "
2013-02-09 21:50:12 +00:00
Base32 = " ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 "
Alpha = UpperAlpha + LowerAlpha
2005-09-30 06:40:35 +00:00
AlphaNumeric = Alpha + Numerals
2009-06-02 23:36:58 +00:00
HighAscii = [ * ( 0x80 .. 0xff ) ] . pack ( " C* " )
2011-07-17 17:32:52 +00:00
LowAscii = [ * ( 0x00 .. 0x1f ) ] . pack ( " C* " )
2005-09-30 06:40:35 +00:00
DefaultWrap = 60
2009-10-20 17:24:33 +00:00
AllChars = [ * ( 0x00 .. 0xff ) ] . pack ( " C* " )
2011-10-16 09:42:04 +00:00
Punctuation = ( [ * ( 0x21 .. 0x2f ) ] + [ * ( 0x3a .. 0x3F ) ] + [ * ( 0x5b .. 0x60 ) ] + [ * ( 0x7b .. 0x7e ) ] ) . flatten . pack ( " C* " )
2005-07-10 07:15:20 +00:00
2005-12-09 00:03:52 +00:00
DefaultPatternSets = [ Rex :: Text :: UpperAlpha , Rex :: Text :: LowerAlpha , Rex :: Text :: Numerals ]
2010-07-05 13:38:39 +00:00
2010-06-03 17:35:58 +00:00
# In case Iconv isn't loaded
Iconv_EBCDIC = [ " \x00 " , " \x01 " , " \x02 " , " \x03 " , " 7 " , " - " , " . " , " / " , " \x16 " , " \x05 " , " % " , " \v " , " \f " , " \r " , " \x0E " , " \x0F " , " \x10 " , " \x11 " , " \x12 " , " \x13 " , " < " , " = " , " 2 " , " & " , " \x18 " , " \x19 " , " ? " , " ' " , " \x1C " , " \x1D " , " \x1E " , " \x1F " , " @ " , " Z " , " \x7F " , " { " , " [ " , " l " , " P " , " } " , " M " , " ] " , " \\ " , " N " , " k " , " ` " , " K " , " a " , " \xF0 " , " \xF1 " , " \xF2 " , " \xF3 " , " \xF4 " , " \xF5 " , " \xF6 " , " \xF7 " , " \xF8 " , " \xF9 " , " z " , " ^ " , " L " , " ~ " , " n " , " o " , " | " , " \xC1 " , " \xC2 " , " \xC3 " , " \xC4 " , " \xC5 " , " \xC6 " , " \xC7 " , " \xC8 " , " \xC9 " , " \xD1 " , " \xD2 " , " \xD3 " , " \xD4 " , " \xD5 " , " \xD6 " , " \xD7 " , " \xD8 " , " \xD9 " , " \xE2 " , " \xE3 " , " \xE4 " , " \xE5 " , " \xE6 " , " \xE7 " , " \xE8 " , " \xE9 " , nil , " \xE0 " , nil , nil , " m " , " y " , " \x81 " , " \x82 " , " \x83 " , " \x84 " , " \x85 " , " \x86 " , " \x87 " , " \x88 " , " \x89 " , " \x91 " , " \x92 " , " \x93 " , " \x94 " , " \x95 " , " \x96 " , " \x97 " , " \x98 " , " \x99 " , " \xA2 " , " \xA3 " , " \xA4 " , " \xA5 " , " \xA6 " , " \xA7 " , " \xA8 " , " \xA9 " , " \xC0 " , " O " , " \xD0 " , " \xA1 " , " \a " , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ]
Iconv_ASCII = [ " \x00 " , " \x01 " , " \x02 " , " \x03 " , " \x04 " , " \x05 " , " \x06 " , " \a " , " \b " , " \t " , " \n " , " \v " , " \f " , " \r " , " \x0E " , " \x0F " , " \x10 " , " \x11 " , " \x12 " , " \x13 " , " \x14 " , " \x15 " , " \x16 " , " \x17 " , " \x18 " , " \x19 " , " \x1A " , " \e " , " \x1C " , " \x1D " , " \x1E " , " \x1F " , " " , " ! " , " \" " , " # " , " $ " , " % " , " & " , " ' " , " ( " , " ) " , " * " , " + " , " , " , " - " , " . " , " / " , " 0 " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " : " , " ; " , " < " , " = " , " > " , " ? " , " @ " , " A " , " B " , " C " , " D " , " E " , " F " , " G " , " H " , " I " , " J " , " K " , " L " , " M " , " N " , " O " , " P " , " Q " , " R " , " S " , " T " , " U " , " V " , " W " , " X " , " Y " , " Z " , nil , " \\ " , nil , nil , " _ " , " ` " , " a " , " b " , " c " , " d " , " e " , " f " , " g " , " h " , " i " , " j " , " k " , " l " , " m " , " n " , " o " , " p " , " q " , " r " , " s " , " t " , " u " , " v " , " w " , " x " , " y " , " z " , " { " , " | " , " } " , " ~ " , " \x7F " , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ]
2010-02-12 05:08:16 +00:00
2005-09-30 06:40:35 +00:00
##
#
# Serialization
#
##
2005-07-10 19:21:40 +00:00
2005-07-10 07:15:20 +00:00
#
# Converts a raw string into a ruby buffer
#
2008-12-20 07:40:27 +00:00
def self . to_ruby ( str , wrap = DefaultWrap , name = " buf " )
return hexify ( str , wrap , '"' , '" +' , " #{ name } = \n " , '"' )
2005-07-10 07:15:20 +00:00
end
2005-07-10 19:21:40 +00:00
#
# Creates a ruby-style comment
#
def self . to_ruby_comment ( str , wrap = DefaultWrap )
return wordwrap ( str , 0 , wrap , '' , '# ' )
end
2005-07-10 07:15:20 +00:00
#
# Converts a raw string into a C buffer
#
2005-07-10 19:21:40 +00:00
def self . to_c ( str , wrap = DefaultWrap , name = " buf " )
return hexify ( str , wrap , '"' , '"' , " unsigned char #{ name } [] = \n " , '";' )
end
#
# Creates a c-style comment
#
def self . to_c_comment ( str , wrap = DefaultWrap )
return " /* \n " + wordwrap ( str , 0 , wrap , '' , ' * ' ) + " */ \n "
2005-07-10 07:15:20 +00:00
end
2010-02-12 05:08:16 +00:00
2006-07-31 04:05:20 +00:00
#
# Creates a javascript-style comment
#
def self . to_js_comment ( str , wrap = DefaultWrap )
return wordwrap ( str , 0 , wrap , '' , '// ' )
end
2010-02-12 05:08:16 +00:00
2005-07-10 07:15:20 +00:00
#
# Converts a raw string into a perl buffer
#
2008-12-20 07:40:27 +00:00
def self . to_perl ( str , wrap = DefaultWrap , name = " buf " )
return hexify ( str , wrap , '"' , '" .' , " my $ #{ name } = \n " , '";' )
2005-07-10 07:15:20 +00:00
end
2013-05-14 01:41:15 +00:00
#
# Converts a raw string into a python buffer
#
def self . to_python ( str , wrap = DefaultWrap , name = " buf " )
return hexify ( str , wrap , " #{ name } += \" " , '"' , " #{ name } = \" \" \n " , '"' )
end
2011-11-11 08:13:17 +00:00
#
# Converts a raw string into a Bash buffer
#
def self . to_bash ( str , wrap = DefaultWrap , name = " buf " )
return hexify ( str , wrap , '$\'' , '\'\\' , " export #{ name } = \\ \n " , '\'' )
end
2007-05-07 04:42:11 +00:00
#
# Converts a raw string into a java byte array
#
2008-12-20 07:40:27 +00:00
def self . to_java ( str , name = " shell " )
buff = " byte #{ name } [] = new byte[] \n { \n "
2007-05-07 04:42:11 +00:00
cnt = 0
max = 0
str . unpack ( 'C*' ) . each do | c |
buff << " , " if max > 0
buff << " \t " if max == 0
buff << sprintf ( '(byte) 0x%.2x' , c )
max += 1
2010-02-12 05:08:16 +00:00
cnt += 1
if ( max > 7 )
buff << " , \n " if cnt != str . length
2007-05-07 04:42:11 +00:00
max = 0
end
end
buff << " \n }; \n "
2010-02-12 05:08:16 +00:00
return buff
2007-05-07 04:42:11 +00:00
end
2010-02-12 05:08:16 +00:00
2005-07-10 19:21:40 +00:00
#
# Creates a perl-style comment
#
def self . to_perl_comment ( str , wrap = DefaultWrap )
return wordwrap ( str , 0 , wrap , '' , '# ' )
end
2011-11-11 08:13:17 +00:00
#
# Creates a Bash-style comment
#
def self . to_bash_comment ( str , wrap = DefaultWrap )
return wordwrap ( str , 0 , wrap , '' , '# ' )
end
2005-07-10 07:15:20 +00:00
#
# Returns the raw string
#
def self . to_raw ( str )
return str
end
2007-02-11 09:22:06 +00:00
#
# Converts ISO-8859-1 to UTF-8
#
def self . to_utf8 ( str )
2013-02-26 23:38:03 +00:00
2013-02-24 19:10:16 +00:00
if str . respond_to? ( :encode )
# Skip over any bytes that fail to convert to UTF-8
return str . encode ( 'utf-8' , { :invalid = > :replace , :undef = > :replace , :replace = > '' } )
end
2007-02-16 18:49:07 +00:00
begin
Iconv . iconv ( " utf-8 " , " iso-8859-1 " , str ) . join ( " " )
rescue
raise :: RuntimeError , " Your installation does not support iconv (needed for utf8 conversion) "
end
2007-02-11 09:22:06 +00:00
end
2010-01-25 15:58:24 +00:00
#
# Converts ASCII to EBCDIC
#
2010-06-03 17:28:45 +00:00
class IllegalSequence < ArgumentError ; end
# A native implementation of the ASCII->EBCDIC table, used to fall back from using
# Iconv
def self . to_ebcdic_rex ( str )
new_str = [ ]
2010-07-05 13:38:39 +00:00
str . each_byte do | x |
2010-06-03 17:35:58 +00:00
if Iconv_ASCII . index ( x . chr )
new_str << Iconv_EBCDIC [ Iconv_ASCII . index ( x . chr ) ]
2010-06-03 17:28:45 +00:00
else
raise Rex :: Text :: IllegalSequence , ( " \\ x%x " % x )
end
end
new_str . join
end
# A native implementation of the EBCDIC->ASCII table, used to fall back from using
# Iconv
def self . from_ebcdic_rex ( str )
new_str = [ ]
2010-07-05 13:38:39 +00:00
str . each_byte do | x |
2010-06-03 17:35:58 +00:00
if Iconv_EBCDIC . index ( x . chr )
new_str << Iconv_ASCII [ Iconv_EBCDIC . index ( x . chr ) ]
2010-06-03 17:28:45 +00:00
else
raise Rex :: Text :: IllegalSequence , ( " \\ x%x " % x )
end
end
new_str . join
end
2010-01-25 15:58:24 +00:00
def self . to_ebcdic ( str )
begin
Iconv . iconv ( " EBCDIC-US " , " ASCII " , str ) . first
rescue :: Iconv :: IllegalSequence = > e
raise e
rescue
2010-06-03 17:28:45 +00:00
self . to_ebcdic_rex ( str )
2010-01-25 15:58:24 +00:00
end
end
2010-02-12 05:08:16 +00:00
#
2010-01-25 15:58:24 +00:00
# Converts EBCIDC to ASCII
#
def self . from_ebcdic ( str )
begin
Iconv . iconv ( " ASCII " , " EBCDIC-US " , str ) . first
rescue :: Iconv :: IllegalSequence = > e
raise e
rescue
2010-06-03 17:28:45 +00:00
self . from_ebcdic_rex ( str )
2010-01-25 15:58:24 +00:00
end
end
2010-02-12 05:08:16 +00:00
2012-11-16 21:11:48 +00:00
#
# Returns the words in +str+ as an Array.
#
# strict - include *only* words, no boundary characters (like spaces, etc.)
#
def self . to_words ( str , strict = false )
splits = str . split ( / \ b / )
splits . reject! { | w | ! ( w =~ / \ w / ) } if strict
splits
end
#
# Removes noise from 2 Strings and return a refined String version.
#
def self . refine ( str1 , str2 )
return str1 if str1 == str2
# get the words of the first str in an array
s_words = to_words ( str1 )
# get the words of the second str in an array
o_words = to_words ( str2 )
# get what hasn't changed (the rdiff, so to speak) as a string
( s_words - ( s_words - o_words ) ) . join
end
2012-11-01 19:14:38 +00:00
2006-07-31 02:50:41 +00:00
#
# Returns a unicode escaped string for Javascript
#
def self . to_unescape ( data , endian = ENDIAN_LITTLE )
data << " \x41 " if ( data . length % 2 != 0 )
dptr = 0
buff = ''
while ( dptr < data . length )
2009-06-20 14:26:22 +00:00
c1 = data [ dptr , 1 ] . unpack ( " C* " ) [ 0 ]
2006-07-31 02:50:41 +00:00
dptr += 1
2009-06-20 14:26:22 +00:00
c2 = data [ dptr , 1 ] . unpack ( " C* " ) [ 0 ]
2006-07-31 02:50:41 +00:00
dptr += 1
2010-02-12 05:08:16 +00:00
2006-07-31 02:50:41 +00:00
if ( endian == ENDIAN_LITTLE )
buff << sprintf ( '%%u%.2x%.2x' , c2 , c1 )
else
buff << sprintf ( '%%u%.2x%.2x' , c1 , c2 )
end
end
2010-02-12 05:08:16 +00:00
return buff
2006-07-31 02:50:41 +00:00
end
2013-01-10 03:45:47 +00:00
#
# Returns the escaped octal version of the supplied string
#
# @example
# Rex::Text.to_octal("asdf") # => "\\141\\163\\144\\146"
#
# @param str [String] The string to be converted
# @param prefix [String]
# @return [String] The escaped octal version of +str+
Squashed commit of the following:
commit 6a3ad1d887df9d277e4878de94f8700ed8e404f9
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 16:22:49 2012 -0600
Add register_command calls for md5 and sha1
commit dbd52c5a1edfe1818a580d4d46aac0a9ca038e9c
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 16:22:09 2012 -0600
Read the file instead of downloading it
commit 55b84ad8e2a8532b3f8520ccb1162169b8e9c056
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 15:27:11 2012 -0600
Re-compile linux meterp to support the loadlib api
commit d112e84e490aa30aa9533fb0bdb33a9713ce01a5
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 14:50:25 2012 -0600
Re-compile java meterp to support the loadlib api
commit c137187b346b708487245a849b95343223e4e7b0
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 14:44:10 2012 -0600
Don't try to get interfaces if this session doesn't implement it
commit 88bba1e6c360c5725c4174623f56bcb6d8b54228
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 14:38:17 2012 -0600
Remove debugging load
commit 02954cbf93e2a13da967780cb703103b3f83ecf4
Merge: d9ef256 88b35a3
Author: James Lee <egypt@metasploit.com>
Date: Wed May 9 12:06:53 2012 -0600
Merge branch 'rapid7' into feature/4905
Conflicts:
data/meterpreter/ext_server_stdapi.php
modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb
commit d9ef2569b88ae8bce67f13316f6eff76311fd846
Author: James Lee <egypt@metasploit.com>
Date: Wed May 2 18:06:06 2012 -0600
PHP doesn't support rev2self
commit bf13ea0ff25541da07b8c099218e5ad7ea6ae8ba
Author: James Lee <egypt@metasploit.com>
Date: Tue May 1 18:21:59 2012 -0600
Add php support for returning new extension commands
commit 7e35f2d671d3797fc3fab12e54015387f44b0b33
Author: James Lee <egypt@metasploit.com>
Date: Tue May 1 16:03:26 2012 -0600
Reset CVE-2012-0507 back to master
Purges commits unrelated to this branch.
commit 86a77b3cd017e1e3a3f23d9fba3b9ed173761f80
Author: James Lee <egypt@metasploit.com>
Date: Tue May 1 15:59:35 2012 -0600
Revert "Make building the jar for cve-2012-0507 a bit easier"
This reverts commit 27ef76522ad10436ec785728445ed2cc0657f85f.
Conflicts:
external/source/exploits/CVE-2012-0507/Makefile
external/source/exploits/CVE-2012-0507/src/msf/x/PayloadX.java
commit 8c259fb779f736be16fe972215ddff1dd32fd0f3
Merge: fe2c273 1c03c2b
Author: James Lee <egypt@metasploit.com>
Date: Tue May 1 15:35:44 2012 -0600
Merge branch 'rapid7' into feature/4905
Conflicts:
data/meterpreter/ext_server_stdapi.jar
data/meterpreter/meterpreter.jar
external/source/meterpreter/java/src/meterpreter/com/metasploit/meterpreter/Meterpreter.java
modules/auxiliary/server/browser_autopwn.rb
commit fe2c273a6d840c67040d6c9e337f908204337e18
Merge: 8caff47 4e955e5
Author: James Lee <egypt@metasploit.com>
Date: Fri Apr 6 10:19:53 2012 -0600
Merge branch 'rapid7' into feature/4905
commit 8caff47d97469f1a5459c04461fd1098487ea514
Author: James Lee <egypt@metasploit.com>
Date: Thu Apr 5 17:51:18 2012 -0600
Fix requires to find the test library
commit 51c33574cee3c47f0b2900c388d3d1213dd0a90d
Author: James Lee <egypt@metasploit.com>
Date: Thu Apr 5 17:48:35 2012 -0600
Fix a load order problem with solaris post mods
commit 81b658362e5e6bdd215d18b53d14429d163aff72
Merge: adad2cf 6ef4257
Author: James Lee <egypt@metasploit.com>
Date: Thu Apr 5 15:43:19 2012 -0600
Merge branch 'master' into feature/4905
commit 6ef42579471c6fde4bba71d0d4ce2c6c3e836180
Merge: 70ab8c0 5852455
Author: James Lee <egypt@metasploit.com>
Date: Thu Apr 5 15:16:56 2012 -0600
Merge branch 'rapid7'
Conflicts:
lib/rex/exploitation/javascriptosdetect.rb
commit adad2cf04c501c2a787e5475b62abd31871c06a0
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 20:20:21 2012 -0600
Deal with null data/jar
Not sure why "" turns into null sometimes, but it was breaking shells;
this fixes it.
commit 4f8a437b490e2b2774f9efd23b4891eaf007cf16
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 18:10:59 2012 -0600
Prev commit moved these to src/a
commit 27ef76522ad10436ec785728445ed2cc0657f85f
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 18:08:32 2012 -0600
Make building the jar for cve-2012-0507 a bit easier
Mostly stolen from cve-2008-5353
commit db3dbad0a5ff20b05758be073c3502138ff095c2
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 14:52:23 2012 -0600
Fix incorrect option name
commit 776976af31795bdf1b405e208a2d4b78a6b6c2cf
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 28 15:36:20 2012 -0600
Add bap support to java_rhino
commit a611ab16e06bd324d6616d0bd69f2c09d671bca0
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 28 15:35:16 2012 -0600
Put next_exploit on the window object so it's always in scope
Solves some issues with Chrome not running more than one exploit
commit 5114d35de7c2f234ac7fe4288b344d4f2bb9731f
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 14:31:53 2012 -0600
Pull common stuff up out of the body
commit 748309465a029593e2fe2fd445149745367513f4
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 11:04:03 2012 -0600
Fix indentation level
commit 954d485e3b8ffea9a7451bd495c1956a098e0eda
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 11:02:42 2012 -0600
Abstract out copy-pasted methods
Need to do the same thing for OSX, but it's a different implementation.
commit cba8d7c911fb184f6358948022fd4a0e010878d0
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 23 18:04:50 2012 -0600
Linux doesn't implement (drop|steal)_token
commit 1cfda3a7b045c08ecfae1ad688e0124e76bd0c8f
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 23 17:57:37 2012 -0600
Add availability checks for net, sys, ui, and webcam
commit 4bdf39a8bf4b5aab293fc47cb8282d0346db0811
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 23 16:45:59 2012 -0600
add requirement checking for fs and core commands
commit 42e35971c9f7348b57293b2b94a42dd0260ac7e4
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 21 17:20:59 2012 -0600
Add a to_octal method that converts e.g. "A" to \0101
commit c3b9415a0a9e2b55b1effbaf2396e11f88301aaa
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 21 17:20:07 2012 -0600
Don't use "echo -n"
It's not portable
commit b0f3ceccfaedbeaf67fbbe76f1a0a9aec7b44548
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 20 17:01:10 2012 -0600
Return a list of new commands after core_loadlib, java version
Thanks mihi for the patch and the awesome responsiveness!
commit d65303e1b6458bd4b95138dc0d61e5354c4e8d3a
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 20 13:21:06 2012 -0600
Make sure we have a response before doing stuff with it
commit 721001ead474a17d1a16de543f78b548879f5e7e
Author: James Lee <egypt@metasploit.com>
Date: Mon Mar 19 21:25:31 2012 -0600
Add missing rmdir and mkdir protocol commands to PHP
Now passes all the stdapi tests that it can
[*] Session type is meterpreter and platform is php/php
[+] should return a user id
[+] should return a sysinfo Hash
[-] FAILED: should return network interfaces
[-] Exception: Rex::Post::Meterpreter::RequestError : stdapi_net_config_get_interfaces: Operation failed: 1
[-] FAILED: should have an interface that matches session_host
[-] Exception: Rex::Post::Meterpreter::RequestError : stdapi_net_config_get_interfaces: Operation failed: 1
[-] FAILED: should return network routes
[-] Exception: Rex::Post::Meterpreter::RequestError : stdapi_net_config_get_routes: Operation failed: 1
[+] should return the proper directory separator
[+] should return the current working directory
[+] should list files in the current directory
[+] should stat a directory
[+] should create and remove a dir
[+] should change directories
[+] should create and remove files
[+] should upload a file
[-] Passed: 10; Failed: 3
commit 024e99167a025f4678a707e1ee809a1524007d4d
Author: James Lee <egypt@metasploit.com>
Date: Mon Mar 19 15:26:00 2012 -0600
Use a proper TLV type instead of a generic one
commit 1836d915cbe0bfd2f536a667e74d8d6a6ccee72a
Author: James Lee <egypt@metasploit.com>
Date: Mon Mar 19 15:24:25 2012 -0600
Fix a counting error that caused segfaults (Linux)
commit 1e419d3fc392e435ae0af703561ce10bd5a45eb0
Author: James Lee <egypt@metasploit.com>
Date: Mon Mar 19 15:06:02 2012 -0600
Return a list of new commands after core_loadlib
Gets Windows back in sync with Linux
commit 3d3959f720de68e2f36ebfabe8196e01f98fe904
Author: James Lee <egypt@metasploit.com>
Date: Mon Mar 19 14:50:55 2012 -0600
Refactor extensionList -> extension_commands
It's not the same as extension_list.
commit a7acb638af803732fc5f3975e0c0632f427e0deb
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sun Mar 18 00:07:27 2012 -0500
Massive whitespace cleanup
commit ef8b9fd5cea7db43860a5b88d7397ba84393ecd5
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sat Mar 17 16:00:20 2012 -0500
Add back enum_protections with some new changes
commit d778eec36953bb9bf4985e967ad2c119a1acd79b
Author: ohdae <bindshell@live.com>
Date: Sat Mar 17 13:28:31 2012 -0400
Added fix for enum_protections
commit 64611819d43bf13ab2d68f4353513c39e5a64fe0
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sat Mar 17 03:14:26 2012 -0500
A bunch of fixes
commit bb1a0205d73e75a61a8fbf5ff6440dd09f9780f9
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sat Mar 17 00:28:05 2012 -0500
The comments in get_chatlogs need an update
commit 666477e42a734f3120dcc4282b01b5ab5819384a
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sat Mar 17 00:25:41 2012 -0500
Correct license format
commit 3c8eecbcd7b952abaca0b1ce14dca41e1d4cabb7
Author: sinn3r <msfsinn3r@gmail.com>
Date: Sat Mar 17 00:22:03 2012 -0500
Add enum_adium.rb post module
commit d290cf4fef1309df9a1af748e7c6c259a6788576
Author: ohdae <bindshell@live.com>
Date: Fri Mar 16 16:54:36 2012 -0300
Changed store_note to store_loot. Fixed local/remote file retrieval
commit ccb830b594ea0f0a8ce7c29b24f2f137ecfd5c4c
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 16 11:29:07 2012 -0600
Fall back to MIB method if we can't get netmasks
Misses IPv6 addresses, but at least doesn't break everything.
[Fixes #6525]
commit a9a30232dd5fcc0854c10b4d58df8511a23f3091
Author: sinn3r <msfsinn3r@gmail.com>
Date: Fri Mar 16 11:49:31 2012 -0500
This module is not ready, yanked.
commit 6bb34f7fd0785d31902f1edc938a6b05b91a1495
Author: Gregory Man <man.gregory@gmail.com>
Date: Fri Mar 16 18:09:08 2012 +0200
sockso_traversal 1.8 compatibility fix
commit e76965ce565a8ae634dc0d3c743542f1a6d977d7
Author: ohdae <bindshell@live.com>
Date: Fri Mar 16 09:17:35 2012 -0400
fix
commit 61ce7b587de54363f7071bc19df5a29eb29e9aa7
Author: ohdae <bindshell@live.com>
Date: Fri Mar 16 09:14:48 2012 -0400
saves each config to loot instead of notes
commit f4713974fa82d8b13017cb0817b5fd36696194d9
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 16 03:46:10 2012 -0600
Check for a 0 prefix length
If the OnLinkPrefixLength is 0, something is wrong, try the value in the
prefix linked list. Appears to fix v4 addresses on XP but not 2k3.
[See #6525]
commit cde7fcc012e04880f2faa28226a1fc5834a2e3d5
Author: James Lee <egypt@metasploit.com>
Date: Fri Mar 16 01:46:41 2012 -0600
Return network prefixes when available
Solves #6525 on Vista+. Win2k still works using the old MIB method
(which doesn't support ipv6). Win2k3 and XP are still busted for
unknown reasons.
commit 98bd9a7bd09149f524ebbe1501ec916bf99b078d
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 22:59:42 2012 -0400
Enumerate important and interesting configuration files
commit 9336df2ac28ee2df10a0e66e7006df3d23493492
Author: David Maloney <David_Maloney@rapid7.com>
Date: Thu Mar 15 19:06:48 2012 -0500
More Virtualisation SSL fixes
commit f24c378281ee6c85f687d4823f09ef5848812daf
Author: David Maloney <David_Maloney@rapid7.com>
Date: Thu Mar 15 18:15:29 2012 -0500
Default SSL to true for esx_fingerprint module
commit d6e14c42120df0fd16b79709ac5723d0e2818810
Author: sinn3r <msfsinn3r@gmail.com>
Date: Thu Mar 15 15:56:24 2012 -0500
Fix typo
commit b24dcfe43e625740ec8a1465f33be02f7ec40162
Author: sinn3r <msfsinn3r@gmail.com>
Date: Thu Mar 15 15:55:54 2012 -0500
Add sockso dir traversal
commit 033052c1e075fcf43e9c17e5ee4a5006247cb375
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 15 14:31:25 2012 -0600
Fix syntax error in 1.8, thanks Jun Koi for the patch
commit 4529efaeaa22e52c9c7c1528c68efb60af8af729
Author: sinn3r <msfsinn3r@gmail.com>
Date: Thu Mar 15 14:27:40 2012 -0500
enum_protections is now find_apps
commit 49e823802bd8f2cb1940545e74db04f3788352d1
Author: sinn3r <msfsinn3r@gmail.com>
Date: Thu Mar 15 14:22:23 2012 -0500
File rename, as well as design and cosmetic changes
commit ccf6b011145cf9db444f7e2d3fb3ec61738e88cb
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 15:29:52 2012 -0300
added report_note, removed store_loot function, cleaned up info/author
commit 27d571932e51afbac0c0fcd95c52f038786a9a28
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 12:18:29 2012 -0300
fixed output newline issue
commit 5a828e35d1629dc68825fe7d9322d1316888f8d7
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 01:05:35 2012 -0300
fixed save line
commit 805c2ee9871c076a8c0ac62b028a7942af70b6a5
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 01:02:07 2012 -0300
removed unneeded comments
commit 5861e1512f2949c0d7848d9ebed8241277462085
Author: ohdae <bindshell@live.com>
Date: Thu Mar 15 01:00:55 2012 -0300
fixed output issue
commit 593a3648111f1db1f56a410250539261c2a7cd9f
Author: ohdae <bindshell@live.com>
Date: Wed Mar 14 18:26:53 2012 -0300
removed unneeded dependency
commit 05053e6e74b0ac99bbd4005c40ecc3b1196fd13f
Author: ohdae <bindshell@live.com>
Date: Wed Mar 14 13:30:16 2012 -0400
locates installed 3rd part av, fws, etc
commit 5bf512d0e9d2b412c4107228db178a7078111443
Author: sinn3r <msfsinn3r@gmail.com>
Date: Wed Mar 14 16:50:54 2012 -0500
Add OSVDB-79863 NetDecision Directory Traversal
commit 18715d0367f4ef01b5998d732043cbe224e1787e
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 14 23:03:01 2012 -0600
Store the retrieved commands on the session
commit b752cb8b31fd8dcd221fb6caa483f6202bf5a4fd
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 14 22:45:16 2012 -0600
Retrieve the list of new commands
The client side doesn't do anything with them yet
commit 69ce8ef42d4089a0b26644bd4d6bebf57c4cfd50
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 14 22:41:16 2012 -0600
Return a list of the new commands in response to core_loadlib
Linux
commit 354c754aa4cce63ffebb4567f3bbfd621ffef46c
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 14 15:13:45 2012 -0600
Whitespace at EOL
commit 4afcb4cb9da1921ede29b03b149433cc65d680da
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 14 14:30:09 2012 -0600
Create instance methods that return extensions
Before this change, meterpreter sessions would not #respond_to? their
extensions despite having a pseudo-accessor for them:
```
>> client.respond_to? :sys
=> false
>> client.sys
=> #<Rex::Post::Meterpreter::ObjectAliases:0x0000000e263488 @aliases={"config"=>#<Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Config:0x0000000e268dc8 @client=#<Session:meterpreter 192.168.99.1:55882 (192.168.99.1) "uid=1000, gid=1000, euid=1000, egid=1000, suid=1000, sgid=1000 @ wpad">>, "process"=>#<Class:0x0000000e268d20>, "registry"=>#<Class:0x0000000e266da0>, "eventlog"=>#<Class:0x0000000e2654e8>, "power"=>#<Class:0x0000000e263c30>}>
```
After:
```
>> client.respond_to? :sys
=> true
```
commit 70ab8c018f67d15929b6f41322540837ab7b37c5
Merge: a8a3938 5f2bace
Author: James Lee <egypt@metasploit.com>
Date: Tue Apr 3 11:46:25 2012 -0600
Merge branch 'master' into bap-refactor
Conflicts:
external/source/exploits/CVE-2012-0507/Help.java
external/source/exploits/CVE-2012-0507/Makefile
external/source/exploits/CVE-2012-0507/msf/x/Help.java
external/source/exploits/CVE-2012-0507/src/a/Exploit.java
external/source/exploits/CVE-2012-0507/src/a/Help.java
commit a8a393891588a8b5c18e3c2173f1cd9c2480b2d0
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 20:20:21 2012 -0600
Deal with null data/jar
Not sure why "" turns into null sometimes, but it was breaking shells;
this fixes it.
commit 5e5eb39d3ccb62a9fc006be8241cfb97723caa06
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 18:10:59 2012 -0600
Prev commit moved these to src/a
commit 5074eadbea426fc4f83d6d165a01e640ef42b4de
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 18:08:32 2012 -0600
Make building the jar for cve-2012-0507 a bit easier
Mostly stolen from cve-2008-5353
commit bdb3fbe7fd19aa76b4069edca5a78c53fec668c0
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 14:52:23 2012 -0600
Fix incorrect option name
commit 78824ef60084510d3befe0ded6eed314d55eeb12
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 13:24:33 2012 -0600
Add the detected browser version to the DOM
Doing it this way lets modules grab the info a bit more easily.
commit 9813ccb8d6b14e0e728b8a13bacf59dd31b9c4b9
Merge: 0faa3f6 b5fc8e4
Author: James Lee <egypt@metasploit.com>
Date: Thu Mar 29 13:19:05 2012 -0600
Merge branch 'master' into bap-refactor
commit 0faa3f65240c3a2b3ab0e72f4aeb2e9f50ed54ee
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 28 15:36:20 2012 -0600
Add bap support to java_rhino
commit 66ca27f994e3b11c9c8adae85642820768158860
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 28 15:35:16 2012 -0600
Put next_exploit on the window object so it's always in scope
Solves some issues with Chrome not running more than one exploit
commit 7fc2ca1a0690c7a973307772aed42ab3514e1761
Merge: 325d306 e48c47e
Author: James Lee <egypt@metasploit.com>
Date: Wed Mar 28 15:10:54 2012 -0600
Merge branch 'master' into bap-refactor
commit 325d3060599bc79674e93dd5f55a4e60061e9bdb
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 14:31:53 2012 -0600
Pull common stuff up out of the body
commit 4f2b3260bf7f14f4d763625792adb0c3cfd1ed7c
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 11:04:03 2012 -0600
Fix indentation level
commit 9b905c53b4d46beb86da8168a1c2c5b2da340f6d
Author: James Lee <egypt@metasploit.com>
Date: Tue Mar 27 11:02:42 2012 -0600
Abstract out copy-pasted methods
Need to do the same thing for OSX, but it's a different implementation.
2012-05-15 23:00:02 +00:00
def self . to_octal ( str , prefix = " \\ " )
octal = " "
str . each_byte { | b |
octal << " #{ prefix } #{ b . to_s 8 } "
}
return octal
end
2005-07-10 07:15:20 +00:00
#
2013-01-10 03:45:47 +00:00
# Returns the escaped hex version of the supplied string
#
# @example
# Rex::Text.to_hex("asdf") # => "\\x61\\x73\\x64\\x66"
2005-07-10 07:15:20 +00:00
#
2013-01-10 03:45:47 +00:00
# @param str (see to_octal)
# @param prefix (see to_octal)
# @param count [Fixnum] Number of bytes to put in each escape chunk
# @return [String] The escaped hex version of +str+
2006-02-27 19:51:17 +00:00
def self . to_hex ( str , prefix = " \\ x " , count = 1 )
2006-10-29 17:41:19 +00:00
raise :: RuntimeError , " unable to chunk into #{ count } byte chunks " if ( ( str . length % count ) > 0 )
2006-02-27 19:51:17 +00:00
# XXX: Regexp.new is used here since using /.{#{count}}/o would compile
# the regex the first time it is used and never check again. Since we
# want to know how many to capture on every instance, we do it this
# way.
2009-11-02 17:09:13 +00:00
return str . unpack ( 'H*' ) [ 0 ] . gsub ( Regexp . new ( " .{ #{ count * 2 } } " , nil , 'n' ) ) { | s | prefix + s }
2005-07-10 07:15:20 +00:00
end
2010-07-13 18:52:27 +00:00
#
2013-01-10 03:45:47 +00:00
# Returns the string with nonprintable hex characters sanitized to ascii.
# Similiar to {.to_hex}, but regular ASCII is not translated if +count+ is 1.
2010-07-13 18:52:27 +00:00
#
2013-01-10 03:45:47 +00:00
# @example
# Rex::Text.to_hex_ascii("\x7fABC\0") # => "\\x7fABC\\x00"
#
# @param str (see to_hex)
# @param prefix (see to_hex)
# @param count (see to_hex)
# @param suffix [String,nil] A string to append to the converted bytes
# @return [String] The original string with non-printables converted to
# their escaped hex representation
2010-09-01 22:40:07 +00:00
def self . to_hex_ascii ( str , prefix = " \\ x " , count = 1 , suffix = nil )
2010-07-13 18:52:27 +00:00
raise :: RuntimeError , " unable to chunk into #{ count } byte chunks " if ( ( str . length % count ) > 0 )
2011-01-25 19:59:56 +00:00
return str . unpack ( 'H*' ) [ 0 ] . gsub ( Regexp . new ( " .{ #{ count * 2 } } " , nil , 'n' ) ) { | s |
2010-09-02 16:22:48 +00:00
( 0x20 .. 0x7e ) === s . to_i ( 16 ) ? s . to_i ( 16 ) . chr : prefix + s + suffix . to_s
2010-07-13 18:52:27 +00:00
}
end
2005-07-13 23:01:34 +00:00
#
2010-02-12 05:08:16 +00:00
# Converts standard ASCII text to a unicode string.
2006-02-13 22:52:01 +00:00
#
# Supported unicode types include: utf-16le, utf16-be, utf32-le, utf32-be, utf-7, and utf-8
2010-02-12 05:08:16 +00:00
#
2013-02-09 21:50:12 +00:00
# Providing 'mode' provides hints to the actual encoder as to how it should encode the string. Only UTF-7 and UTF-8 use "mode".
2010-02-12 05:08:16 +00:00
#
2006-02-13 22:52:01 +00:00
# utf-7 by default does not encode alphanumeric and a few other characters. By specifying the mode of "all", then all of the characters are encoded, not just the non-alphanumeric set.
# to_unicode(str, 'utf-7', 'all')
2010-02-12 05:08:16 +00:00
#
2006-02-13 22:52:01 +00:00
# utf-8 specifies that alphanumeric characters are used directly, eg "a" is just "a". However, there exist 6 different overlong encodings of "a" that are technically not valid, but parse just fine in most utf-8 parsers. (0xC1A1, 0xE081A1, 0xF08081A1, 0xF8808081A1, 0xFC80808081A1, 0xFE8080808081A1). How many bytes to use for the overlong enocding is specified providing 'size'.
2013-02-09 21:50:12 +00:00
# to_unicode(str, 'utf-8', 'overlong', 2)
2006-02-13 22:52:01 +00:00
#
2013-02-09 21:50:12 +00:00
# Many utf-8 parsers also allow invalid overlong encodings, where bits that are unused when encoding a single byte are modified. Many parsers will ignore these bits, rendering simple string matching to be ineffective for dealing with UTF-8 strings. There are many more invalid overlong encodings possible for "a". For example, three encodings are available for an invalid 2 byte encoding of "a". (0xC1E1 0xC161 0xC121). By specifying "invalid", a random invalid encoding is chosen for the given byte size.
# to_unicode(str, 'utf-8', 'invalid', 2)
2006-02-13 22:52:01 +00:00
#
# utf-7 defaults to 'normal' utf-7 encoding
# utf-8 defaults to 2 byte 'normal' encoding
2010-02-12 05:08:16 +00:00
#
2006-02-22 23:29:34 +00:00
def self . to_unicode ( str = '' , type = 'utf-16le' , mode = '' , size = '' )
2007-09-09 22:10:38 +00:00
return '' if not str
2010-02-12 05:08:16 +00:00
case type
2006-02-13 22:52:01 +00:00
when 'utf-16le'
return str . unpack ( 'C*' ) . pack ( 'v*' )
when 'utf-16be'
return str . unpack ( 'C*' ) . pack ( 'n*' )
when 'utf-32le'
return str . unpack ( 'C*' ) . pack ( 'V*' )
when 'utf-32be'
return str . unpack ( 'C*' ) . pack ( 'N*' )
when 'utf-7'
case mode
when 'all'
return str . gsub ( / . / ) { | a |
2006-02-10 17:30:41 +00:00
out = ''
2006-02-13 22:52:01 +00:00
if 'a' != '+'
2006-02-10 17:30:41 +00:00
out = encode_base64 ( to_unicode ( a , 'utf-16be' ) ) . gsub ( / [= \ r \ n] / , '' )
end
'+' + out + '-'
}
2006-02-13 22:52:01 +00:00
else
2010-02-12 05:08:16 +00:00
return str . gsub ( / [^ \ n \ r \ t \ A-Za-z0-9 \ ' \ ( \ ),-. \/ \ : \ ?] / ) { | a |
2006-02-10 17:30:41 +00:00
out = ''
2006-02-13 22:52:01 +00:00
if a != '+'
2006-02-10 17:30:41 +00:00
out = encode_base64 ( to_unicode ( a , 'utf-16be' ) ) . gsub ( / [= \ r \ n] / , '' )
end
'+' + out + '-'
}
2006-02-13 22:52:01 +00:00
end
when 'utf-8'
2006-02-22 23:29:34 +00:00
if size == ''
size = 2
end
2006-02-13 22:52:01 +00:00
if size > = 2 and size < = 7
string = ''
str . each_byte { | a |
2006-02-14 01:04:06 +00:00
if ( a < 21 || a > 0x7f ) || mode != ''
2013-02-09 21:50:12 +00:00
# ugh. turn a single byte into the binary representation of it, in array form
2006-02-13 22:52:01 +00:00
bin = [ a ] . pack ( 'C' ) . unpack ( 'B8' ) [ 0 ] . split ( / / )
# even more ugh.
2009-10-25 17:18:23 +00:00
bin . collect! { | a_ | a_ . to_i }
2006-02-13 22:52:01 +00:00
out = Array . new ( 8 * size , 0 )
0 . upto ( size - 1 ) { | i |
out [ i ] = 1
out [ i * 8 ] = 1
}
i = 0
byte = 0
bin . reverse . each { | bit |
if i < 6
mod = ( ( ( size * 8 ) - 1 ) - byte * 8 ) - i
out [ mod ] = bit
2010-02-12 05:08:16 +00:00
else
2006-02-13 22:52:01 +00:00
byte = byte + 1
i = 0
redo
end
i = i + 1
}
if mode != ''
case mode
when 'overlong'
# do nothing, since we already handle this as above...
when 'invalid'
done = 0
while done == 0
2006-02-14 01:04:06 +00:00
# the ghetto...
2006-02-13 22:52:01 +00:00
bits = [ 7 , 8 , 15 , 16 , 23 , 24 , 31 , 32 , 41 ]
bits . each { | bit |
bit = ( size * 8 ) - bit
if bit > 1
set = rand ( 2 )
if out [ bit ] != set
out [ bit ] = set
done = 1
end
end
}
end
else
raise TypeError , 'Invalid mode. Only "overlong" and "invalid" are acceptable modes for utf-8'
end
end
2009-03-08 07:55:47 +00:00
string << [ out . join ( '' ) ] . pack ( 'B*' )
2006-02-13 22:52:01 +00:00
else
2009-03-08 07:55:47 +00:00
string << [ a ] . pack ( 'C' )
2006-02-13 22:52:01 +00:00
end
}
return string
2010-02-12 05:08:16 +00:00
else
2006-02-13 22:52:01 +00:00
raise TypeError , 'invalid utf-8 size'
2006-02-10 17:30:41 +00:00
end
2006-02-22 23:29:34 +00:00
when 'uhwtfms' # suggested name from HD :P
load_codepage ( )
string = ''
# overloading mode as codepage
if mode == ''
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
else
mode = mode . to_i
end
2007-09-29 06:47:16 +00:00
if @@codepage_map_cache [ mode ] . nil?
2006-02-22 23:29:34 +00:00
raise TypeError , " Invalid codepage #{ mode } "
end
str . each_byte { | byte |
char = [ byte ] . pack ( 'C*' )
2007-09-29 06:47:16 +00:00
possible = @@codepage_map_cache [ mode ] [ 'data' ] [ char ]
2006-02-22 23:29:34 +00:00
if possible . nil?
raise TypeError , " codepage #{ mode } does not provide an encoding for 0x #{ char . unpack ( 'H*' ) [ 0 ] } "
end
2009-03-08 07:55:47 +00:00
string << possible [ rand ( possible . length ) ]
2006-02-22 23:29:34 +00:00
}
return string
2007-05-14 20:49:35 +00:00
when 'uhwtfms-half' # suggested name from HD :P
load_codepage ( )
string = ''
# overloading mode as codepage
if mode == ''
mode = 1252 # ANSI - Latan 1, default for US installs of MS products
else
2009-07-14 00:01:04 +00:00
mode = mode . to_i
end
if mode != 1252
2009-10-20 17:24:33 +00:00
raise TypeError , " Invalid codepage #{ mode } , only 1252 supported for uhwtfms_half "
2007-05-14 20:49:35 +00:00
end
str . each_byte { | byte |
2009-10-16 18:27:18 +00:00
if ( ( byte > = 33 && byte < = 63 ) || ( byte > = 96 && byte < = 126 ) )
string << " \xFF " + [ byte ^ 32 ] . pack ( 'C' )
elsif ( byte > = 64 && byte < = 95 )
string << " \xFF " + [ byte ^ 96 ] . pack ( 'C' )
else
char = [ byte ] . pack ( 'C' )
2007-09-29 06:47:16 +00:00
possible = @@codepage_map_cache [ mode ] [ 'data' ] [ char ]
2007-05-14 20:49:35 +00:00
if possible . nil?
raise TypeError , " codepage #{ mode } does not provide an encoding for 0x #{ char . unpack ( 'H*' ) [ 0 ] } "
end
2009-03-08 07:55:47 +00:00
string << possible [ rand ( possible . length ) ]
2009-10-16 18:27:18 +00:00
end
2007-05-14 20:49:35 +00:00
}
return string
2010-02-12 05:08:16 +00:00
else
2006-02-13 22:52:01 +00:00
raise TypeError , 'invalid utf type'
end
2005-11-26 02:34:39 +00:00
end
2006-02-27 19:51:17 +00:00
2011-03-07 19:57:53 +00:00
#
# Converts a unicode string to standard ASCII text.
#
def self . to_ascii ( str = '' , type = 'utf-16le' , mode = '' , size = '' )
return '' if not str
case type
when 'utf-16le'
return str . unpack ( 'v*' ) . pack ( 'C*' )
when 'utf-16be'
return str . unpack ( 'n*' ) . pack ( 'C*' )
when 'utf-32le'
return str . unpack ( 'V*' ) . pack ( 'C*' )
when 'utf-32be'
return str . unpack ( 'N*' ) . pack ( 'C*' )
when 'utf-7'
raise TypeError , 'invalid utf type, not yet implemented'
when 'utf-8'
raise TypeError , 'invalid utf type, not yet implemented'
when 'uhwtfms' # suggested name from HD :P
raise TypeError , 'invalid utf type, not yet implemented'
when 'uhwtfms-half' # suggested name from HD :P
raise TypeError , 'invalid utf type, not yet implemented'
else
raise TypeError , 'invalid utf type'
end
end
2010-02-12 05:08:16 +00:00
#
# Encode a string in a manor useful for HTTP URIs and URI Parameters.
2006-02-27 19:51:17 +00:00
#
def self . uri_encode ( str , mode = 'hex-normal' )
2010-02-12 05:08:16 +00:00
return " " if str == nil
2007-03-08 14:08:41 +00:00
2006-02-27 19:51:17 +00:00
return str if mode == 'none' # fast track no encoding
all = / [^ \/ \\ ]+ /
2009-10-16 18:27:18 +00:00
normal = / [^a-zA-Z0-9 \/ \\ \ . \ -]+ /
2007-03-08 14:08:41 +00:00
normal_na = / [a-zA-Z0-9 \/ \\ \ . \ -] /
2010-02-12 05:08:16 +00:00
2009-10-16 18:27:18 +00:00
case mode
when 'hex-normal'
return str . gsub ( normal ) { | s | Rex :: Text . to_hex ( s , '%' ) }
when 'hex-all'
return str . gsub ( all ) { | s | Rex :: Text . to_hex ( s , '%' ) }
2012-06-12 20:32:50 +00:00
when 'hex-random'
res = ''
str . each_byte do | c |
b = c . chr
res << ( ( rand ( 2 ) == 0 ) ?
b . gsub ( all ) { | s | Rex :: Text . to_hex ( s , '%' ) } :
b . gsub ( normal ) { | s | Rex :: Text . to_hex ( s , '%' ) } )
end
return res
2009-10-16 18:27:18 +00:00
when 'u-normal'
return str . gsub ( normal ) { | s | Rex :: Text . to_hex ( Rex :: Text . to_unicode ( s , 'uhwtfms' ) , '%u' , 2 ) }
when 'u-all'
return str . gsub ( all ) { | s | Rex :: Text . to_hex ( Rex :: Text . to_unicode ( s , 'uhwtfms' ) , '%u' , 2 ) }
2012-06-12 20:32:50 +00:00
when 'u-random'
res = ''
str . each_byte do | c |
b = c . chr
res << ( ( rand ( 2 ) == 0 ) ?
b . gsub ( all ) { | s | Rex :: Text . to_hex ( Rex :: Text . to_unicode ( s , 'uhwtfms' ) , '%u' , 2 ) } :
b . gsub ( normal ) { | s | Rex :: Text . to_hex ( Rex :: Text . to_unicode ( s , 'uhwtfms' ) , '%u' , 2 ) } )
end
return res
2009-10-16 18:27:18 +00:00
when 'u-half'
return str . gsub ( all ) { | s | Rex :: Text . to_hex ( Rex :: Text . to_unicode ( s , 'uhwtfms-half' ) , '%u' , 2 ) }
else
2013-02-26 23:38:03 +00:00
raise TypeError , " invalid mode #{ mode . inspect } "
2009-10-16 18:27:18 +00:00
end
2006-02-27 19:51:17 +00:00
end
2010-02-12 05:08:16 +00:00
#
2010-03-17 17:47:08 +00:00
# Encode a string in a manner useful for HTTP URIs and URI Parameters.
2010-02-12 05:08:16 +00:00
#
2013-01-10 03:45:47 +00:00
# @param str [String] The string to be encoded
# @param mode ["hex","int","int-wide"]
# @return [String]
# @raise [TypeError] if +mode+ is not one of the three available modes
2006-07-24 19:25:59 +00:00
def self . html_encode ( str , mode = 'hex' )
case mode
when 'hex'
2010-02-12 05:08:16 +00:00
return str . unpack ( 'C*' ) . collect { | i | " & # x " + ( " %.2x " % i ) + " ; " } . join
2006-07-24 19:25:59 +00:00
when 'int'
2010-02-12 05:08:16 +00:00
return str . unpack ( 'C*' ) . collect { | i | " & # " + i . to_s + " ; " } . join
2006-07-24 19:25:59 +00:00
when 'int-wide'
2010-02-12 05:08:16 +00:00
return str . unpack ( 'C*' ) . collect { | i | " & # " + ( " 0 " * ( 7 - i . to_s . length ) ) + i . to_s + " ; " } . join
else
2006-07-24 19:25:59 +00:00
raise TypeError , 'invalid mode'
end
end
2008-04-22 18:48:21 +00:00
2013-01-05 14:21:02 +00:00
#
# Decode a string that's html encoded
#
def self . html_decode ( str )
decoded_str = CGI . unescapeHTML ( str )
return decoded_str
end
2010-09-01 22:40:07 +00:00
#
# Encode an ASCII string so it's safe for XML. It's a wrapper for to_hex_ascii.
#
def self . xml_char_encode ( str )
2010-09-01 23:26:35 +00:00
self . to_hex_ascii ( str , " & # x " , 1 , " ; " )
2010-09-01 22:40:07 +00:00
end
2010-02-12 05:08:16 +00:00
#
2008-04-22 18:48:21 +00:00
# Decode a URI encoded string
#
def self . uri_decode ( str )
str . gsub ( / (%[a-z0-9]{2}) /i ) { | c | [ c [ 1 , 2 ] ] . pack ( " H* " ) }
end
2010-02-12 05:08:16 +00:00
2007-02-18 22:35:07 +00:00
#
# Converts a string to random case
#
2013-01-10 03:45:47 +00:00
# @example
# Rex::Text.to_rand_case("asdf") # => "asDf"
#
# @param str [String] The string to randomize
# @return [String]
# @see permute_case
# @see to_mixed_case_array
2007-02-18 22:35:07 +00:00
def self . to_rand_case ( str )
buf = str . dup
0 . upto ( str . length ) do | i |
buf [ i , 1 ] = rand ( 2 ) == 0 ? str [ i , 1 ] . upcase : str [ i , 1 ] . downcase
end
return buf
end
2006-07-24 19:25:59 +00:00
2010-03-17 17:47:08 +00:00
#
# Takes a string, and returns an array of all mixed case versions.
#
2013-01-10 03:45:47 +00:00
# @example
# >> Rex::Text.to_mixed_case_array "abc1"
# => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
2010-03-17 17:47:08 +00:00
#
2013-01-10 03:45:47 +00:00
# @param str [String] The string to randomize
# @return [Array<String>]
# @see permute_case
2010-03-17 17:47:08 +00:00
def self . to_mixed_case_array ( str )
letters = [ ]
str . scan ( / . / ) . each { | l | letters << [ l . downcase , l . upcase ] }
coords = [ ]
( 1 << str . size ) . times { | i | coords << ( " %0 #{ str . size } b " % i ) }
mixed = [ ]
2010-05-09 02:58:55 +00:00
coords . each do | coord |
2010-03-17 17:47:08 +00:00
c = coord . scan ( / . / ) . map { | x | x . to_i }
this_str = " "
c . each_with_index { | d , i | this_str << letters [ i ] [ d ] }
mixed << this_str
end
return mixed . uniq
end
2007-04-11 22:23:32 +00:00
#
2013-01-10 03:45:47 +00:00
# Converts a string to a nicely formatted hex dump
2007-04-11 22:23:32 +00:00
#
2013-01-10 03:45:47 +00:00
# @param str [String] The string to convert
# @param width [Fixnum] Number of bytes to convert before adding a newline
2007-04-11 22:23:32 +00:00
def self . to_hex_dump ( str , width = 16 )
buf = ''
idx = 0
cnt = 0
snl = false
lst = 0
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
while ( idx < str . length )
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
chunk = str [ idx , width ]
line = chunk . unpack ( " H* " ) [ 0 ] . scan ( / .. / ) . join ( " " )
2010-02-12 05:08:16 +00:00
buf << line
2007-04-11 22:23:32 +00:00
if ( lst == 0 )
lst = line . length
buf << " " * 4
else
buf << " " * ( ( lst - line . length ) + 4 ) . abs
end
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
chunk . unpack ( " C* " ) . each do | c |
2009-12-18 20:40:08 +00:00
if ( c > 0x1f and c < 0x7f )
2007-04-11 22:23:32 +00:00
buf << c . chr
else
buf << " . "
end
end
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
buf << " \n "
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
idx += width
end
2010-02-12 05:08:16 +00:00
2007-04-11 22:23:32 +00:00
buf << " \n "
end
2010-02-12 05:08:16 +00:00
2013-02-09 21:50:12 +00:00
#
# Converts a string a nicely formatted and addressed ex dump
#
def self . to_addr_hex_dump ( str , start_addr = 0 , width = 16 )
buf = ''
idx = 0
cnt = 0
snl = false
lst = 0
addr = start_addr
while ( idx < str . length )
buf << " %08x " % addr
buf << " " * 4
chunk = str [ idx , width ]
line = chunk . unpack ( " H* " ) [ 0 ] . scan ( / .. / ) . join ( " " )
buf << line
if ( lst == 0 )
lst = line . length
buf << " " * 4
else
buf << " " * ( ( lst - line . length ) + 4 ) . abs
end
chunk . unpack ( " C* " ) . each do | c |
if ( c > 0x1f and c < 0x7f )
buf << c . chr
else
buf << " . "
end
end
buf << " \n "
idx += width
addr += width
end
buf << " \n "
end
2005-11-26 02:34:39 +00:00
#
2005-07-13 23:01:34 +00:00
# Converts a hex string to a raw string
#
2013-01-10 03:45:47 +00:00
# @example
# Rex::Text.hex_to_raw("\\x41\\x7f\\x42") # => "A\x7fB"
#
2005-07-13 23:01:34 +00:00
def self . hex_to_raw ( str )
2005-07-18 14:39:00 +00:00
[ str . downcase . gsub ( / ' / , '' ) . gsub ( / \\ ?x([a-f0-9][a-f0-9]) / , '\1' ) ] . pack ( " H* " )
2005-07-13 23:01:34 +00:00
end
2011-04-07 21:59:32 +00:00
#
# Turn non-printable chars into hex representations, leaving others alone
#
# If +whitespace+ is true, converts whitespace (0x20, 0x09, etc) to hex as
# well.
#
2013-01-10 03:45:47 +00:00
# @see hexify
# @see to_hex Converts all the chars
#
2011-04-07 21:59:32 +00:00
def self . ascii_safe_hex ( str , whitespace = false )
if whitespace
str . gsub ( / ([ \ x00- \ x20 \ x80- \ xFF]) / ) { | x | " \\ x%.2x " % x . unpack ( " C* " ) [ 0 ] }
else
str . gsub ( / ([ \ x00- \ x08 \ x0b \ x0c \ x0e- \ x1f \ x80- \ xFF]) /n ) { | x | " \\ x%.2x " % x . unpack ( " C* " ) [ 0 ] }
end
end
2005-07-10 07:15:20 +00:00
#
# Wraps text at a given column using a supplied indention
#
2005-07-10 19:21:40 +00:00
def self . wordwrap ( str , indent = 0 , col = DefaultWrap , append = '' , prepend = '' )
2005-07-10 07:15:20 +00:00
return str . gsub ( / .{1, #{ col - indent } }(?: \ s| \ Z) / ) {
( ( " " * indent ) + prepend + $& + append + 5 . chr ) . gsub ( / \ n \ 005 / , " \n " ) . gsub ( / \ 005 / , " \n " ) }
end
#
# Converts a string to a hex version with wrapping support
#
2005-07-10 19:21:40 +00:00
def self . hexify ( str , col = DefaultWrap , line_start = '' , line_end = '' , buf_start = '' , buf_end = '' )
2013-02-09 21:50:12 +00:00
output = buf_start
cur = 0
count = 0
2005-07-10 07:15:20 +00:00
new_line = true
# Go through each byte in the string
str . each_byte { | byte |
count += 1
2013-02-09 21:50:12 +00:00
append = ''
2005-07-10 07:15:20 +00:00
# If this is a new line, prepend with the
# line start text
if ( new_line == true )
2013-02-09 21:50:12 +00:00
append << line_start
2005-07-10 07:15:20 +00:00
new_line = false
end
# Append the hexified version of the byte
2009-03-08 07:55:47 +00:00
append << sprintf ( " \\ x%.2x " , byte )
2005-07-10 07:15:20 +00:00
cur += append . length
# If we're about to hit the column or have gone past it,
# time to finish up this line
2010-01-14 18:15:15 +00:00
if ( ( cur + line_end . length > = col ) or ( cur + buf_end . length > = col ) )
2005-07-10 07:15:20 +00:00
new_line = true
2013-02-09 21:50:12 +00:00
cur = 0
2005-07-10 07:15:20 +00:00
# If this is the last byte, use the buf_end instead of
# line_end
if ( count == str . length )
2009-03-08 07:55:47 +00:00
append << buf_end + " \n "
2005-07-10 07:15:20 +00:00
else
2009-03-08 07:55:47 +00:00
append << line_end + " \n "
2005-07-10 07:15:20 +00:00
end
end
2009-03-08 07:55:47 +00:00
output << append
2005-07-10 07:15:20 +00:00
}
# If we were in the middle of a line, finish the buffer at this point
if ( new_line == false )
2009-03-08 07:55:47 +00:00
output << buf_end + " \n "
2010-02-12 05:08:16 +00:00
end
2005-07-10 07:15:20 +00:00
return output
end
2005-09-30 06:40:35 +00:00
2005-09-30 06:48:52 +00:00
##
#
# Transforms
#
##
2012-03-21 21:02:46 +00:00
#
# Base32 code
#
# Based on --> https://github.com/stesla/base32
# Copyright (c) 2007-2011 Samuel Tesla
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Base32 encoder
#
def self . b32encode ( bytes_in )
n = ( bytes_in . length * 8 . 0 / 5 . 0 ) . ceil
p = n < 8 ? 5 - ( bytes_in . length * 8 ) % 5 : 0
c = bytes_in . inject ( 0 ) { | m , o | ( m << 8 ) + o } << p
[ ( 0 .. n - 1 ) . to_a . reverse . collect { | i | Base32 [ ( c >> i * 5 ) & 0x1f ] . chr } ,
( " = " * ( 8 - n ) ) ]
end
def self . encode_base32 ( str )
bytes = str . bytes
result = ''
size = 5
while bytes . any? do
bytes . each_slice ( size ) do | a |
bytes_out = b32encode ( a ) . flatten . join
result << bytes_out
bytes = bytes . drop ( size )
end
end
return result
end
#
# Base32 decoder
#
def self . b32decode ( bytes_in )
bytes = bytes_in . take_while { | c | c != 61 } # strip padding
n = ( bytes . length * 5 . 0 / 8 . 0 ) . floor
p = bytes . length < 8 ? 5 - ( n * 8 ) % 5 : 0
c = bytes . inject ( 0 ) { | m , o | ( m << 5 ) + Base32 . index ( o . chr ) } >> p
( 0 .. n - 1 ) . to_a . reverse . collect { | i | ( ( c >> i * 8 ) & 0xff ) . chr }
end
def self . decode_base32 ( str )
bytes = str . bytes
result = ''
size = 8
while bytes . any? do
bytes . each_slice ( size ) do | a |
bytes_out = b32decode ( a ) . flatten . join
result << bytes_out
bytes = bytes . drop ( size )
end
end
return result
end
2005-09-30 06:48:52 +00:00
#
# Base64 encoder
#
2007-04-02 06:23:14 +00:00
def self . encode_base64 ( str , delim = '' )
2011-10-05 01:42:14 +00:00
[ str . to_s ] . pack ( " m " ) . gsub ( / \ s+ / , delim )
2005-09-30 06:48:52 +00:00
end
#
# Base64 decoder
#
def self . decode_base64 ( str )
2011-10-05 01:42:14 +00:00
str . to_s . unpack ( " m " ) [ 0 ]
2005-09-30 06:48:52 +00:00
end
#
# Raw MD5 digest of the supplied string
#
def self . md5_raw ( str )
2010-02-12 05:08:16 +00:00
Digest :: MD5 . digest ( str )
2005-09-30 06:48:52 +00:00
end
#
# Hexidecimal MD5 digest of the supplied string
#
def self . md5 ( str )
2006-11-09 19:54:40 +00:00
Digest :: MD5 . hexdigest ( str )
2005-09-30 06:48:52 +00:00
end
2012-10-29 04:49:21 +00:00
#
# Raw SHA1 digest of the supplied string
#
def self . sha1_raw ( str )
Digest :: SHA1 . digest ( str )
end
#
# Hexidecimal SHA1 digest of the supplied string
#
def self . sha1 ( str )
Digest :: SHA1 . hexdigest ( str )
end
2011-06-30 06:52:52 +00:00
#
# Convert hex-encoded characters to literals.
#
2013-01-10 03:45:47 +00:00
# @example
# Rex::Text.dehex("AA\\x42CC") # => "AABCC"
#
# @see hex_to_raw
# @param str [String]
2011-06-30 06:52:52 +00:00
def self . dehex ( str )
return str unless str . respond_to? :match
return str unless str . respond_to? :gsub
regex = / \ x5cx[0-9a-f]{2} /mi
if str . match ( regex )
str . gsub ( regex ) { | x | x [ 2 , 2 ] . to_i ( 16 ) . chr }
else
str
end
end
#
# Convert and replace hex-encoded characters to literals.
#
2013-01-10 03:45:47 +00:00
# @param (see dehex)
2011-06-30 06:52:52 +00:00
def self . dehex! ( str )
return str unless str . respond_to? :match
return str unless str . respond_to? :gsub
regex = / \ x5cx[0-9a-f]{2} /mi
str . gsub! ( regex ) { | x | x [ 2 , 2 ] . to_i ( 16 ) . chr }
end
2007-09-25 01:50:05 +00:00
2005-09-30 06:40:35 +00:00
##
#
# Generators
#
##
2006-08-14 08:55:37 +00:00
2007-02-18 22:35:07 +00:00
2006-08-14 08:55:37 +00:00
# Generates a random character.
def self . rand_char ( bad , chars = AllChars )
2010-02-12 05:08:16 +00:00
rand_text ( 1 , bad , chars )
2006-08-14 08:55:37 +00:00
end
2010-02-12 05:08:16 +00:00
2005-07-18 01:47:18 +00:00
# Base text generator method
def self . rand_base ( len , bad , * foo )
2010-05-09 02:58:55 +00:00
cset = ( foo . join . unpack ( " C* " ) - bad . to_s . unpack ( " C* " ) ) . uniq
2010-07-05 13:38:39 +00:00
return " " if cset . length == 0
2010-05-09 02:58:55 +00:00
outp = [ ]
len . times { outp << cset [ rand ( cset . length ) ] }
outp . pack ( " C* " )
2005-07-17 10:30:11 +00:00
end
2005-07-18 01:47:18 +00:00
# Generate random bytes of data
2006-01-31 22:25:55 +00:00
def self . rand_text ( len , bad = '' , chars = AllChars )
foo = chars . split ( '' )
2005-07-18 01:47:18 +00:00
rand_base ( len , bad , * foo )
end
# Generate random bytes of alpha data
def self . rand_text_alpha ( len , bad = '' )
foo = [ ]
foo += ( 'A' .. 'Z' ) . to_a
foo += ( 'a' .. 'z' ) . to_a
rand_base ( len , bad , * foo )
end
# Generate random bytes of lowercase alpha data
def self . rand_text_alpha_lower ( len , bad = '' )
rand_base ( len , bad , * ( 'a' .. 'z' ) . to_a )
end
# Generate random bytes of uppercase alpha data
def self . rand_text_alpha_upper ( len , bad = '' )
rand_base ( len , bad , * ( 'A' .. 'Z' ) . to_a )
end
# Generate random bytes of alphanumeric data
def self . rand_text_alphanumeric ( len , bad = '' )
foo = [ ]
foo += ( 'A' .. 'Z' ) . to_a
foo += ( 'a' .. 'z' ) . to_a
foo += ( '0' .. '9' ) . to_a
rand_base ( len , bad , * foo )
end
2005-09-30 06:40:35 +00:00
2010-01-26 02:35:13 +00:00
# Generate random bytes of alphanumeric hex.
def self . rand_text_hex ( len , bad = '' )
foo = [ ]
foo += ( '0' .. '9' ) . to_a
foo += ( 'a' .. 'f' ) . to_a
rand_base ( len , bad , * foo )
end
2007-09-05 13:39:45 +00:00
# Generate random bytes of numeric data
def self . rand_text_numeric ( len , bad = '' )
foo = ( '0' .. '9' ) . to_a
rand_base ( len , bad , * foo )
end
2010-02-12 05:08:16 +00:00
2005-11-24 03:16:10 +00:00
# Generate random bytes of english-like data
def self . rand_text_english ( len , bad = '' )
foo = [ ]
foo += ( 0x21 .. 0x7e ) . map { | c | c . chr }
rand_base ( len , bad , * foo )
end
2010-02-12 05:08:16 +00:00
2009-04-16 03:02:41 +00:00
# Generate random bytes of high ascii data
def self . rand_text_highascii ( len , bad = '' )
foo = [ ]
2009-10-16 18:27:18 +00:00
foo += ( 0x80 .. 0xff ) . map { | c | c . chr }
rand_base ( len , bad , * foo )
end
2013-01-10 03:45:47 +00:00
# Generate a random GUID
#
# @example
# Rex::Text.rand_guid # => "{ca776ced-4ab8-2ed6-6510-aa71e5e2508e}"
#
# @return [String]
2012-04-13 23:58:48 +00:00
def self . rand_guid
" { #{ [ 8 , 4 , 4 , 4 , 12 ] . map { | a | rand_text_hex ( a ) } . join ( " - " ) } } "
end
2005-09-30 06:40:35 +00:00
#
# Creates a pattern that can be used for offset calculation purposes. This
# routine is capable of generating patterns using a supplied set and a
2005-12-09 00:03:52 +00:00
# supplied number of identifiable characters (slots). The supplied sets
# should not contain any duplicate characters or the logic will fail.
2005-09-30 06:40:35 +00:00
#
2013-01-10 03:45:47 +00:00
# @param length [Fixnum]
# @param sets [Array<(String,String,String)>] The character sets to choose
# from. Should have 3 elements, each of which must be a string containing
# no characters contained in the other sets.
# @return [String] A pattern of +length+ bytes, in which any 4-byte chunk is
# unique
# @see pattern_offset
2010-09-04 00:08:12 +00:00
def self . pattern_create ( length , sets = nil )
2005-12-09 00:03:52 +00:00
buf = ''
offsets = [ ]
2010-09-04 00:08:12 +00:00
2010-09-03 23:48:46 +00:00
# Make sure there's something in sets even if we were given an explicit nil
sets || = [ UpperAlpha , LowerAlpha , Numerals ]
2005-09-30 06:40:35 +00:00
2010-10-15 19:40:33 +00:00
# Return stupid uses
return " " if length . to_i < 1
2011-11-11 08:13:17 +00:00
return sets [ 0 ] [ 0 ] . chr * length if sets . size == 1 and sets [ 0 ] . size == 1
2010-10-15 19:40:33 +00:00
2005-12-09 00:03:52 +00:00
sets . length . times { offsets << 0 }
2005-09-30 06:40:35 +00:00
2005-12-09 00:03:52 +00:00
until buf . length > = length
begin
2009-03-08 07:55:47 +00:00
buf << converge_sets ( sets , 0 , offsets , length )
2005-09-30 06:40:35 +00:00
end
end
2010-02-12 05:08:16 +00:00
2007-09-13 16:11:33 +00:00
# Maximum permutations reached, but we need more data
if ( buf . length < length )
buf = buf * ( length / buf . length . to_f ) . ceil
end
2007-10-18 16:55:23 +00:00
2007-04-03 02:42:30 +00:00
buf [ 0 , length ]
2005-09-30 06:40:35 +00:00
end
2010-10-15 19:40:33 +00:00
# Step through an arbitrary number of sets of bytes to build up a findable pattern.
# This is mostly useful for experimentially determining offset lengths into memory
# structures. Note that the supplied sets should never contain duplicate bytes, or
# else it can become impossible to measure the offset accurately.
def self . patt2 ( len , sets = nil )
buf = " "
counter = [ ]
sets || = [ UpperAlpha , LowerAlpha , Numerals ]
len || = len . to_i
return " " if len . zero?
sets = sets . map { | a | a . split ( / / ) }
sets . size . times { counter << 0 }
0 . upto ( len - 1 ) do | i |
setnum = i % sets . size
2011-01-25 19:59:56 +00:00
2011-09-11 02:42:39 +00:00
#puts counter.inspect
2010-10-15 19:40:33 +00:00
end
return buf
end
2005-09-30 06:40:35 +00:00
#
# Calculate the offset to a pattern
#
2013-01-10 03:45:47 +00:00
# @param pattern [String] The pattern to search. Usually the return value
# from {.pattern_create}
# @param value [String,Fixnum,Bignum]
# @return [Fixnum] Index of the given +value+ within +pattern+, if it exists
# @return [nil] if +pattern+ does not contain +value+
# @see pattern_create
2009-11-09 17:50:53 +00:00
def self . pattern_offset ( pattern , value , start = 0 )
2005-09-30 06:40:35 +00:00
if ( value . kind_of? ( String ) )
2009-11-09 17:50:53 +00:00
pattern . index ( value , start )
2005-12-09 00:03:52 +00:00
elsif ( value . kind_of? ( Fixnum ) or value . kind_of? ( Bignum ) )
2009-11-09 17:50:53 +00:00
pattern . index ( [ value ] . pack ( 'V' ) , start )
2005-09-30 06:40:35 +00:00
else
2006-10-29 17:41:19 +00:00
raise :: ArgumentError , " Invalid class for value: #{ value . class } "
2005-09-30 06:40:35 +00:00
end
end
2005-10-01 06:15:39 +00:00
#
# Compresses a string, eliminating all superfluous whitespace before and
# after lines and eliminating all lines.
#
2013-01-10 03:45:47 +00:00
# @param str [String] The string in which to crunch whitespace
# @return [String] Just like +str+, but with repeated whitespace characters
# trimmed down to a single space
2005-10-01 06:15:39 +00:00
def self . compress ( str )
str . gsub ( / \ n /m , ' ' ) . gsub ( / \ s+ / , ' ' ) . gsub ( / ^ \ s+ / , '' ) . gsub ( / \ s+$ / , '' )
end
2006-01-02 07:49:52 +00:00
2008-04-23 06:54:00 +00:00
#
# Randomize the whitespace in a string
#
def self . randomize_space ( str )
str . gsub ( / \ s+ / ) { | s |
len = rand ( 50 ) + 2
set = " \x09 \x20 \x0d \x0a "
buf = ''
while ( buf . length < len )
2009-10-01 16:01:53 +00:00
buf << set [ rand ( set . length ) , 1 ]
2008-04-23 06:54:00 +00:00
end
2010-02-12 05:08:16 +00:00
2008-04-23 06:54:00 +00:00
buf
}
end
2006-01-19 15:12:22 +00:00
# Returns true if zlib can be used.
def self . zlib_present?
2006-01-03 04:07:20 +00:00
begin
2006-07-18 17:30:43 +00:00
temp = Zlib
2006-01-03 04:07:20 +00:00
return true
rescue
return false
end
end
2010-02-12 05:08:16 +00:00
2006-01-27 05:33:08 +00:00
# backwards compat for just a bit...
def self . gzip_present?
self . zlib_present?
end
2006-01-19 15:12:22 +00:00
2006-01-27 05:33:08 +00:00
#
# Compresses a string using zlib
#
2013-01-10 03:45:47 +00:00
# @param str [String] The string to be compressed
# @param level [Fixnum] One of the Zlib compression level constants
# @return [String] The compressed version of +str+
2010-01-21 19:31:17 +00:00
def self . zlib_deflate ( str , level = Zlib :: BEST_COMPRESSION )
2010-01-14 18:15:15 +00:00
if self . zlib_present?
z = Zlib :: Deflate . new ( level )
dst = z . deflate ( str , Zlib :: FINISH )
z . close
return dst
2010-02-12 05:08:16 +00:00
else
2010-01-14 18:15:15 +00:00
raise RuntimeError , " Gzip support is not present. "
end
2006-01-27 05:33:08 +00:00
end
2006-01-19 15:12:22 +00:00
2006-01-27 05:33:08 +00:00
#
# Uncompresses a string using zlib
#
2013-01-10 03:45:47 +00:00
# @param str [String] Compressed string to inflate
# @return [String] The uncompressed version of +str+
2006-01-27 05:33:08 +00:00
def self . zlib_inflate ( str )
2010-01-14 18:15:15 +00:00
if ( self . zlib_present? )
zstream = Zlib :: Inflate . new
buf = zstream . inflate ( str )
zstream . finish
zstream . close
return buf
else
raise RuntimeError , " Gzip support is not present. "
end
2006-01-27 05:33:08 +00:00
end
2006-01-03 04:07:20 +00:00
2006-01-02 07:49:52 +00:00
#
# Compresses a string using gzip
#
2013-01-10 03:45:47 +00:00
# @param str (see zlib_deflate)
# @param level [Fixnum] Compression level, 1 (fast) to 9 (best)
# @return (see zlib_deflate)
2006-01-05 22:20:28 +00:00
def self . gzip ( str , level = 9 )
2006-01-19 15:12:22 +00:00
raise RuntimeError , " Gzip support is not present. " if ( ! zlib_present? )
2006-01-24 03:59:44 +00:00
raise RuntimeError , " Invalid gzip compression level " if ( level < 1 or level > 9 )
2006-01-03 04:07:20 +00:00
2006-01-27 05:33:08 +00:00
s = " "
2011-01-25 20:03:33 +00:00
s . force_encoding ( 'ASCII-8BIT' ) if s . respond_to? ( :encoding )
2011-01-25 19:59:56 +00:00
gz = Zlib :: GzipWriter . new ( StringIO . new ( s , 'wb' ) , level )
2006-01-27 05:33:08 +00:00
gz << str
gz . close
return s
2006-01-05 22:20:28 +00:00
end
2010-02-12 05:08:16 +00:00
2006-01-27 05:33:08 +00:00
#
2006-01-05 22:20:28 +00:00
# Uncompresses a string using gzip
#
2013-01-10 03:45:47 +00:00
# @param str (see zlib_inflate)
# @return (see zlib_inflate)
2006-01-05 22:20:28 +00:00
def self . ungzip ( str )
2006-01-19 15:12:22 +00:00
raise RuntimeError , " Gzip support is not present. " if ( ! zlib_present? )
2006-01-05 22:20:28 +00:00
2006-01-27 05:33:08 +00:00
s = " "
2011-01-25 20:03:33 +00:00
s . force_encoding ( 'ASCII-8BIT' ) if s . respond_to? ( :encoding )
2011-01-25 19:59:56 +00:00
gz = Zlib :: GzipReader . new ( StringIO . new ( str , 'rb' ) )
2006-01-27 05:33:08 +00:00
s << gz . read
gz . close
return s
2006-01-02 07:49:52 +00:00
end
2010-02-12 05:08:16 +00:00
2005-11-09 04:18:08 +00:00
#
2013-01-10 03:45:47 +00:00
# Return the index of the first badchar in +data+, otherwise return
2005-11-09 04:18:08 +00:00
# nil if there wasn't any badchar occurences.
#
2013-01-10 03:45:47 +00:00
# @param data [String] The string to check for bad characters
# @param badchars [String] A list of characters considered to be bad
# @return [Fixnum] Index of the first bad character if any exist in +data+
# @return [nil] If +data+ contains no bad characters
2005-11-26 11:16:36 +00:00
def self . badchar_index ( data , badchars = '' )
2010-01-26 02:39:43 +00:00
badchars . unpack ( " C* " ) . each { | badchar |
2009-06-02 23:36:58 +00:00
pos = data . index ( badchar . chr )
2005-11-09 04:18:08 +00:00
return pos if pos
}
return nil
end
#
2013-01-10 03:45:47 +00:00
# Removes bad characters from a string.
#
# Modifies +data+ in place
2005-11-09 04:18:08 +00:00
#
2013-01-10 03:45:47 +00:00
# @param data [#delete]
# @param badchars [String] A list of characters considered to be bad
2005-11-26 11:16:36 +00:00
def self . remove_badchars ( data , badchars = '' )
2005-11-09 04:18:08 +00:00
data . delete ( badchars )
end
2005-11-27 18:42:44 +00:00
#
2013-01-10 03:45:47 +00:00
# Returns all chars that are not in the supplied set
2005-11-27 18:42:44 +00:00
#
2013-01-10 03:45:47 +00:00
# @param keepers [String]
# @return [String] All characters not contained in +keepers+
2005-12-02 00:49:46 +00:00
def self . charset_exclude ( keepers )
2005-11-27 18:42:44 +00:00
[ * ( 0 .. 255 ) ] . pack ( 'C*' ) . delete ( keepers )
end
2006-01-17 04:09:40 +00:00
#
2013-01-10 03:45:47 +00:00
# Shuffles a byte stream
2006-01-17 04:09:40 +00:00
#
2013-01-10 03:45:47 +00:00
# @param str [String]
# @return [String] The shuffled result
# @see shuffle_a
2006-01-17 04:09:40 +00:00
def self . shuffle_s ( str )
shuffle_a ( str . unpack ( " C* " ) ) . pack ( " C* " )
end
#
# Performs a Fisher-Yates shuffle on an array
#
2013-01-10 03:45:47 +00:00
# Modifies +arr+ in place
#
# @param arr [Array] The array to be shuffled
# @return [Array]
2006-01-17 04:09:40 +00:00
def self . shuffle_a ( arr )
len = arr . length
max = len - 1
cyc = [ * ( 0 .. max ) ]
for d in cyc
e = rand ( d + 1 )
next if e == d
f = arr [ d ] ;
g = arr [ e ] ;
arr [ d ] = g ;
arr [ e ] = f ;
end
return arr
end
2008-10-22 22:43:13 +00:00
# Permute the case of a word
def self . permute_case ( word , idx = 0 )
res = [ ]
if ( ( UpperAlpha + LowerAlpha ) . index ( word [ idx , 1 ] ) )
word_ucase = word . dup
word_ucase [ idx , 1 ] = word [ idx , 1 ] . upcase
2010-02-12 05:08:16 +00:00
2008-10-22 22:43:13 +00:00
word_lcase = word . dup
word_lcase [ idx , 1 ] = word [ idx , 1 ] . downcase
2010-02-12 05:08:16 +00:00
2008-10-22 22:43:13 +00:00
if ( idx == word . length )
return [ word ]
else
res << permute_case ( word_ucase , idx + 1 )
res << permute_case ( word_lcase , idx + 1 )
end
else
res << permute_case ( word , idx + 1 )
end
2010-02-12 05:08:16 +00:00
2008-10-22 22:43:13 +00:00
res . flatten
end
2006-04-21 03:59:07 +00:00
# Generate a random hostname
2013-01-10 03:45:47 +00:00
#
# @return [String] A random string conforming to the rules of FQDNs
2006-04-21 03:59:07 +00:00
def self . rand_hostname
host = [ ]
( rand ( 5 ) + 1 ) . times {
host . push ( Rex :: Text . rand_text_alphanumeric ( rand ( 10 ) + 1 ) )
}
d = [ 'com' , 'net' , 'org' , 'gov' ]
host . push ( d [ rand ( d . size ) ] )
host . join ( '.' ) . downcase
end
# Generate a state
def self . rand_state ( )
States [ rand ( States . size ) ]
end
2008-08-13 01:44:37 +00:00
#
# Calculate the ROR13 hash of a given string
#
2013-01-10 03:45:47 +00:00
# @return [Fixnum]
2008-08-13 01:44:37 +00:00
def self . ror13_hash ( name )
hash = 0
name . unpack ( " C* " ) . each { | c | hash = ror ( hash , 13 ) ; hash += c }
hash
end
#
2013-01-10 03:45:47 +00:00
# Rotate a 32-bit value to the right by +cnt+ bits
2008-08-13 01:44:37 +00:00
#
2013-01-10 03:45:47 +00:00
# @param val [Fixnum] The value to rotate
# @param cnt [Fixnum] Number of bits to rotate by
2008-08-13 01:44:37 +00:00
def self . ror ( val , cnt )
bits = [ val ] . pack ( " N " ) . unpack ( " B32 " ) [ 0 ] . split ( / / )
1 . upto ( cnt ) do | c |
bits . unshift ( bits . pop )
end
[ bits . join ] . pack ( " B32 " ) . unpack ( " N " ) [ 0 ]
end
2010-02-12 05:08:16 +00:00
2008-08-13 01:44:37 +00:00
#
2013-01-10 03:45:47 +00:00
# Rotate a 32-bit value to the left by +cnt+ bits
2008-08-13 01:44:37 +00:00
#
2013-01-10 03:45:47 +00:00
# @param val (see ror)
# @param cnt (see ror)
# @return (see ror)
2008-08-13 01:44:37 +00:00
def self . rol ( val , cnt )
bits = [ val ] . pack ( " N " ) . unpack ( " B32 " ) [ 0 ] . split ( / / )
1 . upto ( cnt ) do | c |
bits . push ( bits . shift )
end
[ bits . join ] . pack ( " B32 " ) . unpack ( " N " ) [ 0 ]
end
2011-03-07 19:57:53 +00:00
#
2013-01-10 03:45:47 +00:00
# Split a string by n character into an array
2011-03-07 19:57:53 +00:00
#
def self . split_to_a ( str , n )
if n > 0
s = str . dup
until s . empty?
( ret || = [ ] ) . push s . slice! ( 0 , n )
end
else
ret = str
end
2013-02-09 21:50:12 +00:00
ret
2011-03-07 19:57:53 +00:00
end
#
2013-01-10 03:45:47 +00:00
# Pack a value as 64 bit litle endian; does not exist for Array.pack
2011-03-07 19:57:53 +00:00
#
def self . pack_int64le ( val )
[ val & 0x00000000ffffffff , val >> 32 ] . pack ( " V2 " )
end
2011-07-17 17:32:52 +00:00
#
# A custom unicode filter for dealing with multi-byte strings on a 8-bit console
# Punycode would have been more "standard", but it requires valid Unicode chars
#
def self . unicode_filter_encode ( str )
2011-10-18 19:16:48 +00:00
if ( str . to_s . unpack ( " C* " ) & ( LowAscii + HighAscii + " \x7f " ) . unpack ( " C* " ) ) . length > 0
2011-07-17 17:32:52 +00:00
str = " $U$ " + str . unpack ( " C* " ) . select { | c | c < 0x7f and c > 0x1f and c != 0x2d } . pack ( " C* " ) + " -0x " + str . unpack ( " H* " ) [ 0 ]
else
str
end
end
def self . unicode_filter_decode ( str )
2011-10-18 19:16:48 +00:00
str . to_s . gsub ( / \ $U \ $([ \ x20- \ x2c \ x2e- \ x7E]*) \ -0x([A-Fa-f0-9]+) / ) { | m | [ $2 ] . pack ( " H* " ) }
2011-07-17 17:32:52 +00:00
end
2008-08-13 01:44:37 +00:00
2005-12-09 00:03:52 +00:00
protected
def self . converge_sets ( sets , idx , offsets , length ) # :nodoc:
buf = sets [ idx ] [ offsets [ idx ] ] . chr
# If there are more sets after use, converage with them.
if ( sets [ idx + 1 ] )
2009-03-08 07:55:47 +00:00
buf << converge_sets ( sets , idx + 1 , offsets , length )
2005-12-09 00:03:52 +00:00
else
# Increment the current set offset as well as previous ones if we
# wrap back to zero.
while ( idx > = 0 and ( ( offsets [ idx ] = ( offsets [ idx ] + 1 ) % sets [ idx ] . length ) ) == 0 )
idx -= 1
end
# If we reached the point where the idx fell below zero, then that
# means we've reached the maximum threshold for permutations.
if ( idx < 0 )
2010-10-15 19:40:33 +00:00
return buf
2005-12-09 00:03:52 +00:00
end
2010-10-15 19:40:33 +00:00
2005-12-09 00:03:52 +00:00
end
buf
end
2010-02-12 05:08:16 +00:00
2006-02-22 23:29:34 +00:00
def self . load_codepage ( )
2007-09-29 06:47:16 +00:00
return if ( ! @@codepage_map_cache . nil? )
2006-02-22 23:29:34 +00:00
file = File . join ( File . dirname ( __FILE__ ) , 'codepage.map' )
page = ''
name = ''
map = { }
File . open ( file ) . each { | line |
next if line =~ / ^ # /
next if line =~ / ^ \ s*$ /
data = line . split
if data [ 1 ] =~ / ^ \ ( /
page = data . shift . to_i
name = data . join ( ' ' ) . sub ( / ^ \ ( / , '' ) . sub ( / \ )$ / , '' )
map [ page ] = { }
map [ page ] [ 'name' ] = name
map [ page ] [ 'data' ] = { }
else
data . each { | entry |
wide , char = entry . split ( ':' )
char = [ char ] . pack ( 'H*' )
wide = [ wide ] . pack ( 'H*' )
if map [ page ] [ 'data' ] [ char ] . nil?
map [ page ] [ 'data' ] [ char ] = [ wide ]
else
map [ page ] [ 'data' ] [ char ] . push ( wide )
end
}
end
}
2007-09-29 06:47:16 +00:00
@@codepage_map_cache = map
2006-02-22 23:29:34 +00:00
end
2005-12-09 00:03:52 +00:00
2012-03-02 23:44:23 +00:00
def self . checksum8 ( str )
str . unpack ( " C* " ) . inject ( :+ ) % 0x100
end
2012-03-21 21:02:46 +00:00
2012-03-02 23:44:23 +00:00
def self . checksum16_le ( str )
str . unpack ( " v* " ) . inject ( :+ ) % 0x10000
end
def self . checksum16_be ( str )
str . unpack ( " n* " ) . inject ( :+ ) % 0x10000
end
def self . checksum32_le ( str )
str . unpack ( " V* " ) . inject ( :+ ) % 0x100000000
end
def self . checksum32_be ( str )
str . unpack ( " N* " ) . inject ( :+ ) % 0x100000000
end
2005-07-10 07:15:20 +00:00
end
2008-10-22 22:43:13 +00:00
end
2010-02-12 05:08:16 +00:00