Module: Rex::Text
- Defined in:
- lib/rex/text.rb
Overview
This class formats text in various fashions and also provides a mechanism for wrapping text at a given column.
Defined Under Namespace
Classes: IllegalSequence, UnitTest
Constant Summary collapse
- States =
Constants
["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"]
- UpperAlpha =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- LowerAlpha =
"abcdefghijklmnopqrstuvwxyz"
- Numerals =
"0123456789"
- Base32 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
- Alpha =
UpperAlpha + LowerAlpha
- AlphaNumeric =
Alpha + Numerals
- HighAscii =
[*(0x80 .. 0xff)].pack("C*")
- LowAscii =
[*(0x00 .. 0x1f)].pack("C*")
- DefaultWrap =
60
- AllChars =
[*(0x00 .. 0xff)].pack("C*")
- Punctuation =
( [*(0x21 .. 0x2f)] + [*(0x3a .. 0x3F)] + [*(0x5b .. 0x60)] + [*(0x7b .. 0x7e)] ).flatten.pack("C*")
- DefaultPatternSets =
[ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
- Iconv_EBCDIC =
In case Iconv isn’t loaded
["\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]
- @@codepage_map_cache =
nil
Class Method Summary collapse
-
.ascii_safe_hex(str, whitespace = false) ⇒ Object
Turn non-printable chars into hex representations, leaving others alone.
-
.b32decode(bytes_in) ⇒ Object
Base32 decoder.
-
.b32encode(bytes_in) ⇒ Object
Base32 encoder.
-
.badchar_index(data, badchars = '') ⇒ Object
Return the index of the first badchar in data, otherwise return nil if there wasn’t any badchar occurences.
-
.charset_exclude(keepers) ⇒ Object
This method returns all chars but the supplied set.
-
.compress(str) ⇒ Object
Compresses a string, eliminating all superfluous whitespace before and after lines and eliminating all lines.
- .decode_base32(str) ⇒ Object
-
.decode_base64(str) ⇒ Object
Base64 decoder.
-
.dehex(str) ⇒ Object
Convert hex-encoded characters to literals.
-
.dehex!(str) ⇒ Object
Convert and replace hex-encoded characters to literals.
- .encode_base32(str) ⇒ Object
-
.encode_base64(str, delim = '') ⇒ Object
Base64 encoder.
-
.from_ebcdic(str) ⇒ Object
Converts EBCIDC to ASCII.
-
.from_ebcdic_rex(str) ⇒ Object
A native implementation of the EBCDIC->ASCII table, used to fall back from using Iconv.
-
.gzip(str, level = 9) ⇒ Object
Compresses a string using gzip.
-
.gzip_present? ⇒ Boolean
backwards compat for just a bit…
-
.hex_to_raw(str) ⇒ Object
Converts a hex string to a raw string.
-
.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '') ⇒ Object
Converts a string to a hex version with wrapping support.
-
.html_encode(str, mode = 'hex') ⇒ Object
Encode a string in a manner useful for HTTP URIs and URI Parameters.
-
.md5(str) ⇒ Object
Hexidecimal MD5 digest of the supplied string.
-
.md5_raw(str) ⇒ Object
Raw MD5 digest of the supplied string.
-
.pack_int64le(val) ⇒ Object
Pack a value as 64 bit litle endian; does not exist for Array.pack.
-
.patt2(len, sets = nil) ⇒ Object
Step through an arbitrary number of sets of bytes to build up a findable pattern.
-
.pattern_create(length, sets = nil) ⇒ Object
Creates a pattern that can be used for offset calculation purposes.
-
.pattern_offset(pattern, value, start = 0) ⇒ Object
Calculate the offset to a pattern.
-
.permute_case(word, idx = 0) ⇒ Object
Permute the case of a word.
-
.rand_base(len, bad, *foo) ⇒ Object
Base text generator method.
-
.rand_char(bad, chars = AllChars) ⇒ Object
Generates a random character.
-
.rand_guid ⇒ Object
Generate a random GUID, of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
-
.rand_hostname ⇒ Object
Generate a random hostname.
-
.rand_state ⇒ Object
Generate a state.
-
.rand_text(len, bad = '', chars = AllChars) ⇒ Object
Generate random bytes of data.
-
.rand_text_alpha(len, bad = '') ⇒ Object
Generate random bytes of alpha data.
-
.rand_text_alpha_lower(len, bad = '') ⇒ Object
Generate random bytes of lowercase alpha data.
-
.rand_text_alpha_upper(len, bad = '') ⇒ Object
Generate random bytes of uppercase alpha data.
-
.rand_text_alphanumeric(len, bad = '') ⇒ Object
Generate random bytes of alphanumeric data.
-
.rand_text_english(len, bad = '') ⇒ Object
Generate random bytes of english-like data.
-
.rand_text_hex(len, bad = '') ⇒ Object
Generate random bytes of alphanumeric hex.
-
.rand_text_highascii(len, bad = '') ⇒ Object
Generate random bytes of high ascii data.
-
.rand_text_numeric(len, bad = '') ⇒ Object
Generate random bytes of numeric data.
-
.randomize_space(str) ⇒ Object
Randomize the whitespace in a string.
-
.remove_badchars(data, badchars = '') ⇒ Object
This method removes bad characters from a string.
-
.rol(val, cnt) ⇒ Object
Rotate a 32-bit value to the left by cnt bits.
-
.ror(val, cnt) ⇒ Object
Rotate a 32-bit value to the right by cnt bits.
-
.ror13_hash(name) ⇒ Object
Calculate the ROR13 hash of a given string.
-
.shuffle_a(arr) ⇒ Object
Performs a Fisher-Yates shuffle on an array.
-
.shuffle_s(str) ⇒ Object
Shuffles a byte stream.
-
.split_to_a(str, n) ⇒ Object
Split a string by n charachter into an array.
-
.to_ascii(str = '', type = 'utf-16le', mode = '', size = '') ⇒ Object
Converts a unicode string to standard ASCII text.
-
.to_bash(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a Bash buffer.
-
.to_bash_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a Bash-style comment.
-
.to_c(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a C buffer.
-
.to_c_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a c-style comment.
- .to_ebcdic(str) ⇒ Object
-
.to_ebcdic_rex(str) ⇒ Object
A native implementation of the ASCII->EBCDIC table, used to fall back from using Iconv.
-
.to_hex(str, prefix = "\\x", count = 1) ⇒ Object
Returns the hex version of the supplied string.
-
.to_hex_ascii(str, prefix = "\\x", count = 1, suffix = nil) ⇒ Object
Returns the string with nonprintable hex characters sanitized to ascii.
-
.to_hex_dump(str, width = 16) ⇒ Object
Converts a string a nicely formatted hex dump.
-
.to_java(str, name = "shell") ⇒ Object
Converts a raw string into a java byte array.
-
.to_js_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a javascript-style comment.
-
.to_mixed_case_array(str) ⇒ Object
Takes a string, and returns an array of all mixed case versions.
- .to_octal(str, prefix = "\\") ⇒ Object
-
.to_perl(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a perl buffer.
-
.to_perl_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a perl-style comment.
-
.to_rand_case(str) ⇒ Object
Converts a string to random case.
-
.to_raw(str) ⇒ Object
Returns the raw string.
-
.to_ruby(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a ruby buffer.
-
.to_ruby_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a ruby-style comment.
-
.to_unescape(data, endian = ENDIAN_LITTLE) ⇒ Object
Returns a unicode escaped string for Javascript.
-
.to_unicode(str = '', type = 'utf-16le', mode = '', size = '') ⇒ Object
Converts standard ASCII text to a unicode string.
-
.to_utf8(str) ⇒ Object
Converts ISO-8859-1 to UTF-8.
-
.ungzip(str) ⇒ Object
Uncompresses a string using gzip.
- .unicode_filter_decode(str) ⇒ Object
-
.unicode_filter_encode(str) ⇒ Object
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.
-
.uri_decode(str) ⇒ Object
Decode a URI encoded string.
-
.uri_encode(str, mode = 'hex-normal') ⇒ Object
Encode a string in a manor useful for HTTP URIs and URI Parameters.
-
.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '') ⇒ Object
Wraps text at a given column using a supplied indention.
-
.xml_char_encode(str) ⇒ Object
Encode an ASCII string so it’s safe for XML.
-
.zlib_deflate(str, level = Zlib::BEST_COMPRESSION) ⇒ Object
Compresses a string using zlib.
-
.zlib_inflate(str) ⇒ Object
Uncompresses a string using zlib.
-
.zlib_present? ⇒ Boolean
Returns true if zlib can be used.
Class Method Details
.ascii_safe_hex(str, whitespace = false) ⇒ Object
Turn non-printable chars into hex representations, leaving others alone
If whitespace
is true, converts whitespace (0x20, 0x09, etc) to hex as well.
637 638 639 640 641 642 643 |
# File 'lib/rex/text.rb', line 637 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 |
.b32decode(bytes_in) ⇒ Object
Base32 decoder
765 766 767 768 769 770 771 |
# File 'lib/rex/text.rb', line 765 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 |
.b32encode(bytes_in) ⇒ Object
Base32 encoder
740 741 742 743 744 745 746 |
# File 'lib/rex/text.rb', line 740 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 |
.badchar_index(data, badchars = '') ⇒ Object
Return the index of the first badchar in data, otherwise return nil if there wasn’t any badchar occurences.
1097 1098 1099 1100 1101 1102 1103 |
# File 'lib/rex/text.rb', line 1097 def self.badchar_index(data, badchars = '') badchars.unpack("C*").each { |badchar| pos = data.index(badchar.chr) return pos if pos } return nil end |
.charset_exclude(keepers) ⇒ Object
This method returns all chars but the supplied set
1115 1116 1117 |
# File 'lib/rex/text.rb', line 1115 def self.charset_exclude(keepers) [*(0..255)].pack('C*').delete(keepers) end |
.compress(str) ⇒ Object
Compresses a string, eliminating all superfluous whitespace before and after lines and eliminating all lines.
1000 1001 1002 |
# File 'lib/rex/text.rb', line 1000 def self.compress(str) str.gsub(/\n/m, ' ').gsub(/\s+/, ' ').gsub(/^\s+/, '').gsub(/\s+$/, '') end |
.decode_base32(str) ⇒ Object
773 774 775 776 777 778 779 780 781 782 783 784 785 |
# File 'lib/rex/text.rb', line 773 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 |
.decode_base64(str) ⇒ Object
Base64 decoder
797 798 799 |
# File 'lib/rex/text.rb', line 797 def self.decode_base64(str) str.to_s.unpack("m")[0] end |
.dehex(str) ⇒ Object
Convert hex-encoded characters to literals. Example: “AA\x42CC” becomes “AABCC”
819 820 821 822 823 824 825 826 827 828 |
# File 'lib/rex/text.rb', line 819 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 |
.dehex!(str) ⇒ Object
Convert and replace hex-encoded characters to literals.
833 834 835 836 837 838 |
# File 'lib/rex/text.rb', line 833 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 |
.encode_base32(str) ⇒ Object
748 749 750 751 752 753 754 755 756 757 758 759 760 |
# File 'lib/rex/text.rb', line 748 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 |
.encode_base64(str, delim = '') ⇒ Object
Base64 encoder
790 791 792 |
# File 'lib/rex/text.rb', line 790 def self.encode_base64(str, delim='') [str.to_s].pack("m").gsub(/\s+/, delim) end |
.from_ebcdic(str) ⇒ Object
Converts EBCIDC to ASCII
211 212 213 214 215 216 217 218 219 |
# File 'lib/rex/text.rb', line 211 def self.from_ebcdic(str) begin Iconv.iconv("ASCII", "EBCDIC-US", str).first rescue ::Iconv::IllegalSequence => e raise e rescue self.from_ebcdic_rex(str) end end |
.from_ebcdic_rex(str) ⇒ Object
A native implementation of the EBCDIC->ASCII table, used to fall back from using Iconv
186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/rex/text.rb', line 186 def self.from_ebcdic_rex(str) new_str = [] str.each_byte do |x| if Iconv_EBCDIC.index(x.chr) new_str << Iconv_ASCII[Iconv_EBCDIC.index(x.chr)] else raise Rex::Text::IllegalSequence, ("\\x%x" % x) end end new_str.join end |
.gzip(str, level = 9) ⇒ Object
Compresses a string using gzip
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 |
# File 'lib/rex/text.rb', line 1067 def self.gzip(str, level = 9) raise RuntimeError, "Gzip support is not present." if (!zlib_present?) raise RuntimeError, "Invalid gzip compression level" if (level < 1 or level > 9) s = "" s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding) gz = Zlib::GzipWriter.new(StringIO.new(s, 'wb'), level) gz << str gz.close return s end |
.gzip_present? ⇒ Boolean
backwards compat for just a bit…
1031 1032 1033 |
# File 'lib/rex/text.rb', line 1031 def self.gzip_present? self.zlib_present? end |
.hex_to_raw(str) ⇒ Object
Converts a hex string to a raw string
627 628 629 |
# File 'lib/rex/text.rb', line 627 def self.hex_to_raw(str) [ str.downcase.gsub(/'/,'').gsub(/\\?x([a-f0-9][a-f0-9])/, '\1') ].pack("H*") end |
.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '') ⇒ Object
Converts a string to a hex version with wrapping support
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
# File 'lib/rex/text.rb', line 656 def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '') output = buf_start cur = 0 count = 0 new_line = true # Go through each byte in the string str.each_byte { |byte| count += 1 append = '' # If this is a new line, prepend with the # line start text if (new_line == true) append << line_start new_line = false end # Append the hexified version of the byte append << sprintf("\\x%.2x", byte) cur += append.length # If we're about to hit the column or have gone past it, # time to finish up this line if ((cur + line_end.length >= col) or (cur + buf_end.length >= col)) new_line = true cur = 0 # If this is the last byte, use the buf_end instead of # line_end if (count == str.length) append << buf_end + "\n" else append << line_end + "\n" end end output << append } # If we were in the middle of a line, finish the buffer at this point if (new_line == false) output << buf_end + "\n" end return output end |
.html_encode(str, mode = 'hex') ⇒ Object
Encode a string in a manner useful for HTTP URIs and URI Parameters.
524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/rex/text.rb', line 524 def self.html_encode(str, mode = 'hex') case mode when 'hex' return str.unpack('C*').collect{ |i| "&#x" + ("%.2x" % i) + ";"}.join when 'int' return str.unpack('C*').collect{ |i| "&#" + i.to_s + ";"}.join when 'int-wide' return str.unpack('C*').collect{ |i| "&#" + ("0" * (7 - i.to_s.length)) + i.to_s + ";" }.join else raise TypeError, 'invalid mode' end end |
.md5(str) ⇒ Object
Hexidecimal MD5 digest of the supplied string
811 812 813 |
# File 'lib/rex/text.rb', line 811 def self.md5(str) Digest::MD5.hexdigest(str) end |
.md5_raw(str) ⇒ Object
Raw MD5 digest of the supplied string
804 805 806 |
# File 'lib/rex/text.rb', line 804 def self.md5_raw(str) Digest::MD5.digest(str) end |
.pack_int64le(val) ⇒ Object
Pack a value as 64 bit litle endian; does not exist for Array.pack
1235 1236 1237 |
# File 'lib/rex/text.rb', line 1235 def self.pack_int64le(val) [val & 0x00000000ffffffff, val >> 32].pack("V2") end |
.patt2(len, sets = nil) ⇒ Object
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.
965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 |
# File 'lib/rex/text.rb', line 965 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 #puts counter.inspect end return buf end |
.pattern_create(length, sets = nil) ⇒ Object
Creates a pattern that can be used for offset calculation purposes. This routine is capable of generating patterns using a supplied set and a supplied number of identifiable characters (slots). The supplied sets should not contain any duplicate characters or the logic will fail.
933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 |
# File 'lib/rex/text.rb', line 933 def self.pattern_create(length, sets = nil) buf = '' idx = 0 offsets = [] # Make sure there's something in sets even if we were given an explicit nil sets ||= [ UpperAlpha, LowerAlpha, Numerals ] # Return stupid uses return "" if length.to_i < 1 return sets[0][0].chr * length if sets.size == 1 and sets[0].size == 1 sets.length.times { offsets << 0 } until buf.length >= length begin buf << converge_sets(sets, 0, offsets, length) end end # Maximum permutations reached, but we need more data if (buf.length < length) buf = buf * (length / buf.length.to_f).ceil end buf[0,length] end |
.pattern_offset(pattern, value, start = 0) ⇒ Object
Calculate the offset to a pattern
986 987 988 989 990 991 992 993 994 |
# File 'lib/rex/text.rb', line 986 def self.pattern_offset(pattern, value, start=0) if (value.kind_of?(String)) pattern.index(value, start) elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum)) pattern.index([ value ].pack('V'), start) else raise ::ArgumentError, "Invalid class for value: #{value.class}" end end |
.permute_case(word, idx = 0) ⇒ Object
Permute the case of a word
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 |
# File 'lib/rex/text.rb', line 1145 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 word_lcase = word.dup word_lcase[idx, 1] = word[idx, 1].downcase 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 res.flatten end |
.rand_base(len, bad, *foo) ⇒ Object
Base text generator method
853 854 855 856 857 858 859 |
# File 'lib/rex/text.rb', line 853 def self.rand_base(len, bad, *foo) cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq return "" if cset.length == 0 outp = [] len.times { outp << cset[rand(cset.length)] } outp.pack("C*") end |
.rand_char(bad, chars = AllChars) ⇒ Object
Generates a random character.
848 849 850 |
# File 'lib/rex/text.rb', line 848 def self.rand_char(bad, chars = AllChars) rand_text(1, bad, chars) end |
.rand_guid ⇒ Object
Generate a random GUID, of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
923 924 925 |
# File 'lib/rex/text.rb', line 923 def self.rand_guid "{#{[8,4,4,4,12].map {|a| rand_text_hex(a) }.join("-")}}" end |
.rand_hostname ⇒ Object
Generate a random hostname
1170 1171 1172 1173 1174 1175 1176 1177 1178 |
# File 'lib/rex/text.rb', line 1170 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 |
.rand_state ⇒ Object
Generate a state
1181 1182 1183 |
# File 'lib/rex/text.rb', line 1181 def self.rand_state() States[rand(States.size)] end |
.rand_text(len, bad = '', chars = AllChars) ⇒ Object
Generate random bytes of data
862 863 864 865 |
# File 'lib/rex/text.rb', line 862 def self.rand_text(len, bad='', chars = AllChars) foo = chars.split('') rand_base(len, bad, *foo) end |
.rand_text_alpha(len, bad = '') ⇒ Object
Generate random bytes of alpha data
868 869 870 871 872 873 |
# File 'lib/rex/text.rb', line 868 def self.rand_text_alpha(len, bad='') foo = [] foo += ('A' .. 'Z').to_a foo += ('a' .. 'z').to_a rand_base(len, bad, *foo ) end |
.rand_text_alpha_lower(len, bad = '') ⇒ Object
Generate random bytes of lowercase alpha data
876 877 878 |
# File 'lib/rex/text.rb', line 876 def self.rand_text_alpha_lower(len, bad='') rand_base(len, bad, *('a' .. 'z').to_a) end |
.rand_text_alpha_upper(len, bad = '') ⇒ Object
Generate random bytes of uppercase alpha data
881 882 883 |
# File 'lib/rex/text.rb', line 881 def self.rand_text_alpha_upper(len, bad='') rand_base(len, bad, *('A' .. 'Z').to_a) end |
.rand_text_alphanumeric(len, bad = '') ⇒ Object
Generate random bytes of alphanumeric data
886 887 888 889 890 891 892 |
# File 'lib/rex/text.rb', line 886 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 |
.rand_text_english(len, bad = '') ⇒ Object
Generate random bytes of english-like data
909 910 911 912 913 |
# File 'lib/rex/text.rb', line 909 def self.rand_text_english(len, bad='') foo = [] foo += (0x21 .. 0x7e).map{ |c| c.chr } rand_base(len, bad, *foo ) end |
.rand_text_hex(len, bad = '') ⇒ Object
Generate random bytes of alphanumeric hex.
895 896 897 898 899 900 |
# File 'lib/rex/text.rb', line 895 def self.rand_text_hex(len, bad='') foo = [] foo += ('0' .. '9').to_a foo += ('a' .. 'f').to_a rand_base(len, bad, *foo) end |
.rand_text_highascii(len, bad = '') ⇒ Object
Generate random bytes of high ascii data
916 917 918 919 920 |
# File 'lib/rex/text.rb', line 916 def self.rand_text_highascii(len, bad='') foo = [] foo += (0x80 .. 0xff).map{ |c| c.chr } rand_base(len, bad, *foo ) end |
.rand_text_numeric(len, bad = '') ⇒ Object
Generate random bytes of numeric data
903 904 905 906 |
# File 'lib/rex/text.rb', line 903 def self.rand_text_numeric(len, bad='') foo = ('0' .. '9').to_a rand_base(len, bad, *foo ) end |
.randomize_space(str) ⇒ Object
Randomize the whitespace in a string
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 |
# File 'lib/rex/text.rb', line 1007 def self.randomize_space(str) str.gsub(/\s+/) { |s| len = rand(50)+2 set = "\x09\x20\x0d\x0a" buf = '' while (buf.length < len) buf << set[rand(set.length),1] end buf } end |
.remove_badchars(data, badchars = '') ⇒ Object
This method removes bad characters from a string.
1108 1109 1110 |
# File 'lib/rex/text.rb', line 1108 def self.remove_badchars(data, badchars = '') data.delete(badchars) end |
.rol(val, cnt) ⇒ Object
Rotate a 32-bit value to the left by cnt bits
1209 1210 1211 1212 1213 1214 1215 |
# File 'lib/rex/text.rb', line 1209 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 |
.ror(val, cnt) ⇒ Object
Rotate a 32-bit value to the right by cnt bits
1198 1199 1200 1201 1202 1203 1204 |
# File 'lib/rex/text.rb', line 1198 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 |
.ror13_hash(name) ⇒ Object
Calculate the ROR13 hash of a given string
1189 1190 1191 1192 1193 |
# File 'lib/rex/text.rb', line 1189 def self.ror13_hash(name) hash = 0 name.unpack("C*").each {|c| hash = ror(hash, 13); hash += c } hash end |
.shuffle_a(arr) ⇒ Object
Performs a Fisher-Yates shuffle on an array
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 |
# File 'lib/rex/text.rb', line 1129 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 |
.shuffle_s(str) ⇒ Object
Shuffles a byte stream
1122 1123 1124 |
# File 'lib/rex/text.rb', line 1122 def self.shuffle_s(str) shuffle_a(str.unpack("C*")).pack("C*") end |
.split_to_a(str, n) ⇒ Object
Split a string by n charachter into an array
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 |
# File 'lib/rex/text.rb', line 1220 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 ret end |
.to_ascii(str = '', type = 'utf-16le', mode = '', size = '') ⇒ Object
Converts a unicode string to standard ASCII text.
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
# File 'lib/rex/text.rb', line 451 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 |
.to_bash(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a Bash buffer
106 107 108 |
# File 'lib/rex/text.rb', line 106 def self.to_bash(str, wrap = DefaultWrap, name = "buf") return hexify(str, wrap, '$\'', '\'\\', "export #{name}=\\\n", '\'') end |
.to_bash_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a Bash-style comment
143 144 145 |
# File 'lib/rex/text.rb', line 143 def self.to_bash_comment(str, wrap = DefaultWrap) return wordwrap(str, 0, wrap, '', '# ') end |
.to_c(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a C buffer
78 79 80 |
# File 'lib/rex/text.rb', line 78 def self.to_c(str, wrap = DefaultWrap, name = "buf") return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";') end |
.to_c_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a c-style comment
85 86 87 |
# File 'lib/rex/text.rb', line 85 def self.to_c_comment(str, wrap = DefaultWrap) return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n" end |
.to_ebcdic(str) ⇒ Object
198 199 200 201 202 203 204 205 206 |
# File 'lib/rex/text.rb', line 198 def self.to_ebcdic(str) begin Iconv.iconv("EBCDIC-US", "ASCII", str).first rescue ::Iconv::IllegalSequence => e raise e rescue self.to_ebcdic_rex(str) end end |
.to_ebcdic_rex(str) ⇒ Object
A native implementation of the ASCII->EBCDIC table, used to fall back from using Iconv
172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/rex/text.rb', line 172 def self.to_ebcdic_rex(str) new_str = [] str.each_byte do |x| if Iconv_ASCII.index(x.chr) new_str << Iconv_EBCDIC[Iconv_ASCII.index(x.chr)] else raise Rex::Text::IllegalSequence, ("\\x%x" % x) end end new_str.join end |
.to_hex(str, prefix = "\\x", count = 1) ⇒ Object
Returns the hex version of the supplied string
255 256 257 258 259 260 261 262 263 |
# File 'lib/rex/text.rb', line 255 def self.to_hex(str, prefix = "\\x", count = 1) raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0) # 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. return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s } end |
.to_hex_ascii(str, prefix = "\\x", count = 1, suffix = nil) ⇒ Object
Returns the string with nonprintable hex characters sanitized to ascii. Similiar to to_hex, but regular ASCII is not translated if count is 1.
269 270 271 272 273 274 |
# File 'lib/rex/text.rb', line 269 def self.to_hex_ascii(str, prefix = "\\x", count = 1, suffix=nil) raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0) return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| (0x20..0x7e) === s.to_i(16) ? s.to_i(16).chr : prefix + s + suffix.to_s } end |
.to_hex_dump(str, width = 16) ⇒ Object
Converts a string a nicely formatted hex dump
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
# File 'lib/rex/text.rb', line 588 def self.to_hex_dump(str, width=16) buf = '' idx = 0 cnt = 0 snl = false lst = 0 while (idx < str.length) 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 end buf << "\n" end |
.to_java(str, name = "shell") ⇒ Object
Converts a raw string into a java byte array
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/rex/text.rb', line 113 def self.to_java(str, name = "shell") buff = "byte #{name}[] = new byte[]\n{\n" 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 cnt +=1 if (max > 7) buff << ",\n" if cnt != str.length max = 0 end end buff << "\n};\n" return buff end |
.to_js_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a javascript-style comment
92 93 94 |
# File 'lib/rex/text.rb', line 92 def self.to_js_comment(str, wrap = DefaultWrap) return wordwrap(str, 0, wrap, '', '// ') end |
.to_mixed_case_array(str) ⇒ Object
Takes a string, and returns an array of all mixed case versions.
Example:
>> Rex::Text.to_mixed_case_array "abc1"
=> ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
# File 'lib/rex/text.rb', line 570 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 = [] coords.each do |coord| 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 |
.to_octal(str, prefix = "\\") ⇒ Object
243 244 245 246 247 248 249 250 |
# File 'lib/rex/text.rb', line 243 def self.to_octal(str, prefix = "\\") octal = "" str.each_byte { |b| octal << "#{prefix}#{b.to_s 8}" } return octal end |
.to_perl(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a perl buffer
99 100 101 |
# File 'lib/rex/text.rb', line 99 def self.to_perl(str, wrap = DefaultWrap, name = "buf") return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";') end |
.to_perl_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a perl-style comment
136 137 138 |
# File 'lib/rex/text.rb', line 136 def self.to_perl_comment(str, wrap = DefaultWrap) return wordwrap(str, 0, wrap, '', '# ') end |
.to_rand_case(str) ⇒ Object
Converts a string to random case
554 555 556 557 558 559 560 |
# File 'lib/rex/text.rb', line 554 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 |
.to_raw(str) ⇒ Object
Returns the raw string
150 151 152 |
# File 'lib/rex/text.rb', line 150 def self.to_raw(str) return str end |
.to_ruby(str, wrap = DefaultWrap, name = "buf") ⇒ Object
Converts a raw string into a ruby buffer
64 65 66 |
# File 'lib/rex/text.rb', line 64 def self.to_ruby(str, wrap = DefaultWrap, name = "buf") return hexify(str, wrap, '"', '" +', "#{name} = \n", '"') end |
.to_ruby_comment(str, wrap = DefaultWrap) ⇒ Object
Creates a ruby-style comment
71 72 73 |
# File 'lib/rex/text.rb', line 71 def self.to_ruby_comment(str, wrap = DefaultWrap) return wordwrap(str, 0, wrap, '', '# ') end |
.to_unescape(data, endian = ENDIAN_LITTLE) ⇒ Object
Returns a unicode escaped string for Javascript
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/rex/text.rb', line 224 def self.to_unescape(data, endian=ENDIAN_LITTLE) data << "\x41" if (data.length % 2 != 0) dptr = 0 buff = '' while (dptr < data.length) c1 = data[dptr,1].unpack("C*")[0] dptr += 1 c2 = data[dptr,1].unpack("C*")[0] dptr += 1 if (endian == ENDIAN_LITTLE) buff << sprintf('%%u%.2x%.2x', c2, c1) else buff << sprintf('%%u%.2x%.2x', c1, c2) end end return buff end |
.to_unicode(str = '', type = 'utf-16le', mode = '', size = '') ⇒ Object
Converts standard ASCII text to a unicode string.
Supported unicode types include: utf-16le, utf16-be, utf32-le, utf32-be, utf-7, and utf-8
Providing ‘mode’ provides hints to the actual encoder as to how it should encode the string. Only UTF-7 and UTF-8 use “mode”.
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’)
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’. to_unicode(str, ‘utf-8’, ‘overlong’, 2)
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)
utf-7 defaults to ‘normal’ utf-7 encoding utf-8 defaults to 2 byte ‘normal’ encoding
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/rex/text.rb', line 295 def self.to_unicode(str='', type = 'utf-16le', mode = '', size = '') return '' if not str case type 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| out = '' if 'a' != '+' out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '') end '+' + out + '-' } else return str.gsub(/[^\n\r\t\ A-Za-z0-9\'\(\),-.\/\:\?]/){ |a| out = '' if a != '+' out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '') end '+' + out + '-' } end when 'utf-8' if size == '' size = 2 end if size >= 2 and size <= 7 string = '' str.each_byte { |a| if (a < 21 || a > 0x7f) || mode != '' # ugh. turn a single byte into the binary representation of it, in array form bin = [a].pack('C').unpack('B8')[0].split(//) # even more ugh. bin.collect!{|a_| a_.to_i} 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 else 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 # the ghetto... 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 string << [out.join('')].pack('B*') else string << [a].pack('C') end } return string else raise TypeError, 'invalid utf-8 size' end 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 if @@codepage_map_cache[mode].nil? raise TypeError, "Invalid codepage #{mode}" end str.each_byte {|byte| char = [byte].pack('C*') possible = @@codepage_map_cache[mode]['data'][char] if possible.nil? raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}" end string << possible[ rand(possible.length) ] } return string 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 mode = mode.to_i end if mode != 1252 raise TypeError, "Invalid codepage #{mode}, only 1252 supported for uhwtfms_half" end str.each_byte {|byte| 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') possible = @@codepage_map_cache[mode]['data'][char] if possible.nil? raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}" end string << possible[ rand(possible.length) ] end } return string else raise TypeError, 'invalid utf type' end end |
.to_utf8(str) ⇒ Object
Converts ISO-8859-1 to UTF-8
157 158 159 160 161 162 163 |
# File 'lib/rex/text.rb', line 157 def self.to_utf8(str) begin Iconv.iconv("utf-8","iso-8859-1", str).join(" ") rescue raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)" end end |
.ungzip(str) ⇒ Object
Uncompresses a string using gzip
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 |
# File 'lib/rex/text.rb', line 1082 def self.ungzip(str) raise RuntimeError, "Gzip support is not present." if (!zlib_present?) s = "" s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding) gz = Zlib::GzipReader.new(StringIO.new(str, 'rb')) s << gz.read gz.close return s end |
.unicode_filter_decode(str) ⇒ Object
1252 1253 1254 |
# File 'lib/rex/text.rb', line 1252 def self.unicode_filter_decode(str) str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/ ){|m| [$2].pack("H*") } end |
.unicode_filter_encode(str) ⇒ Object
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
1244 1245 1246 1247 1248 1249 1250 |
# File 'lib/rex/text.rb', line 1244 def self.unicode_filter_encode(str) if (str.to_s.unpack("C*") & ( LowAscii + HighAscii + "\x7f" ).unpack("C*")).length > 0 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 |
.uri_decode(str) ⇒ Object
Decode a URI encoded string
547 548 549 |
# File 'lib/rex/text.rb', line 547 def self.uri_decode(str) str.gsub(/(%[a-z0-9]{2})/i){ |c| [c[1,2]].pack("H*") } end |
.uri_encode(str, mode = 'hex-normal') ⇒ Object
Encode a string in a manor useful for HTTP URIs and URI Parameters.
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/rex/text.rb', line 478 def self.uri_encode(str, mode = 'hex-normal') return "" if str == nil return str if mode == 'none' # fast track no encoding all = /[^\/\\]+/ normal = /[^a-zA-Z0-9\/\\\.\-]+/ normal_na = /[a-zA-Z0-9\/\\\.\-]/ 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, '%') } 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 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) } 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 when 'u-half' return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms-half'), '%u', 2) } else raise TypeError, 'invalid mode' end end |
.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '') ⇒ Object
Wraps text at a given column using a supplied indention
648 649 650 651 |
# File 'lib/rex/text.rb', line 648 def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '') return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){ ( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")} end |
.xml_char_encode(str) ⇒ Object
Encode an ASCII string so it’s safe for XML. It’s a wrapper for to_hex_ascii.
540 541 542 |
# File 'lib/rex/text.rb', line 540 def self.xml_char_encode(str) self.to_hex_ascii(str, "&#x", 1, ";") end |
.zlib_deflate(str, level = Zlib::BEST_COMPRESSION) ⇒ Object
Compresses a string using zlib
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 |
# File 'lib/rex/text.rb', line 1038 def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION) if self.zlib_present? z = Zlib::Deflate.new(level) dst = z.deflate(str, Zlib::FINISH) z.close return dst else raise RuntimeError, "Gzip support is not present." end end |
.zlib_inflate(str) ⇒ Object
Uncompresses a string using zlib
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 |
# File 'lib/rex/text.rb', line 1052 def self.zlib_inflate(str) 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 end |
.zlib_present? ⇒ Boolean
Returns true if zlib can be used.
1021 1022 1023 1024 1025 1026 1027 1028 |
# File 'lib/rex/text.rb', line 1021 def self.zlib_present? begin temp = Zlib return true rescue return false end end |