rex-text 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Text
4
+ class IllegalSequence < ArgumentError; end
5
+ end
6
+ end
@@ -0,0 +1,156 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Text
4
+ # We are re-opening the module to add these module methods.
5
+ # Breaking them up this way allows us to maintain a little higher
6
+ # degree of organisation and make it easier to find what you're looking for
7
+ # without hanging the underlying calls that we historically rely upon.
8
+
9
+ #
10
+ # Converts a raw string into a ruby buffer
11
+ #
12
+ def self.to_ruby(str, wrap = DefaultWrap, name = "buf")
13
+ return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
14
+ end
15
+
16
+ #
17
+ # Creates a ruby-style comment
18
+ #
19
+ def self.to_ruby_comment(str, wrap = DefaultWrap)
20
+ return wordwrap(str, 0, wrap, '', '# ')
21
+ end
22
+
23
+ #
24
+ # Converts a raw string into a C buffer
25
+ #
26
+ def self.to_c(str, wrap = DefaultWrap, name = "buf")
27
+ return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
28
+ end
29
+
30
+ def self.to_csharp(str, wrap = DefaultWrap, name = "buf")
31
+ ret = "byte[] #{name} = new byte[#{str.length}] {"
32
+ i = -1;
33
+ while (i += 1) < str.length
34
+ ret << "\n" if i%(wrap/4) == 0
35
+ ret << "0x" << str[i].unpack("H*")[0] << ","
36
+ end
37
+ ret = ret[0..ret.length-2] #cut off last comma
38
+ ret << " };\n"
39
+ end
40
+
41
+ #
42
+ # Creates a c-style comment
43
+ #
44
+ def self.to_c_comment(str, wrap = DefaultWrap)
45
+ return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
46
+ end
47
+
48
+ #
49
+ # Creates a javascript-style comment
50
+ #
51
+ def self.to_js_comment(str, wrap = DefaultWrap)
52
+ return wordwrap(str, 0, wrap, '', '// ')
53
+ end
54
+
55
+ #
56
+ # Converts a raw string into a perl buffer
57
+ #
58
+ def self.to_perl(str, wrap = DefaultWrap, name = "buf")
59
+ return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";')
60
+ end
61
+
62
+ #
63
+ # Converts a raw string into a python buffer
64
+ #
65
+ def self.to_python(str, wrap = DefaultWrap, name = "buf")
66
+ return hexify(str, wrap, "#{name} += \"", '"', "#{name} = \"\"\n", '"')
67
+ end
68
+
69
+ #
70
+ # Converts a raw string into a Bash buffer
71
+ #
72
+ def self.to_bash(str, wrap = DefaultWrap, name = "buf")
73
+ return hexify(str, wrap, '$\'', '\'\\', "export #{name}=\\\n", '\'')
74
+ end
75
+
76
+ #
77
+ # Converts a raw string into a java byte array
78
+ #
79
+ def self.to_java(str, name = "shell")
80
+ buff = "byte #{name}[] = new byte[]\n{\n"
81
+ cnt = 0
82
+ max = 0
83
+ str.unpack('C*').each do |c|
84
+ buff << ", " if max > 0
85
+ buff << "\t" if max == 0
86
+ buff << sprintf('(byte) 0x%.2x', c)
87
+ max +=1
88
+ cnt +=1
89
+
90
+ if (max > 7)
91
+ buff << ",\n" if cnt != str.length
92
+ max = 0
93
+ end
94
+ end
95
+ buff << "\n};\n"
96
+ return buff
97
+ end
98
+
99
+ #
100
+ # Converts a raw string to a vbscript byte array
101
+ #
102
+ def self.to_vbscript(str, name = "buf")
103
+ return "#{name}" if str.nil? or str.empty?
104
+
105
+ code = str.unpack('C*')
106
+ buff = "#{name}=Chr(#{code[0]})"
107
+ 1.upto(code.length-1) do |byte|
108
+ if(byte % 100 == 0)
109
+ buff << "\r\n#{name}=#{name}"
110
+ end
111
+ # exe is an Array of bytes, not a String, thanks to the unpack
112
+ # above, so the following line is not subject to the different
113
+ # treatments of String#[] between ruby 1.8 and 1.9
114
+ buff << "&Chr(#{code[byte]})"
115
+ end
116
+
117
+ return buff
118
+ end
119
+
120
+ #
121
+ # Converts a raw string into a vba buffer
122
+ #
123
+ def self.to_vbapplication(str, name = "buf")
124
+ return "#{name} = Array()" if str.nil? or str.empty?
125
+
126
+ code = str.unpack('C*')
127
+ buff = "#{name} = Array("
128
+ maxbytes = 20
129
+
130
+ 1.upto(code.length) do |idx|
131
+ buff << code[idx].to_s
132
+ buff << "," if idx < code.length - 1
133
+ buff << " _\r\n" if (idx > 1 and (idx % maxbytes) == 0)
134
+ end
135
+
136
+ buff << ")\r\n"
137
+
138
+ return buff
139
+ end
140
+
141
+ #
142
+ # Creates a perl-style comment
143
+ #
144
+ def self.to_perl_comment(str, wrap = DefaultWrap)
145
+ return wordwrap(str, 0, wrap, '', '# ')
146
+ end
147
+
148
+ #
149
+ # Creates a Bash-style comment
150
+ #
151
+ def self.to_bash_comment(str, wrap = DefaultWrap)
152
+ return wordwrap(str, 0, wrap, '', '# ')
153
+ end
154
+
155
+ end
156
+ end
@@ -0,0 +1,91 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Text
4
+ # We are re-opening the module to add these module methods.
5
+ # Breaking them up this way allows us to maintain a little higher
6
+ # degree of organisation and make it easier to find what you're looking for
7
+ # without hanging the underlying calls that we historically rely upon.
8
+
9
+ #
10
+ # Creates a pattern that can be used for offset calculation purposes. This
11
+ # routine is capable of generating patterns using a supplied set and a
12
+ # supplied number of identifiable characters (slots). The supplied sets
13
+ # should not contain any duplicate characters or the logic will fail.
14
+ #
15
+ # @param length [Fixnum]
16
+ # @param sets [Array<(String,String,String)>] The character sets to choose
17
+ # from. Should have 3 elements, each of which must be a string containing
18
+ # no characters contained in the other sets.
19
+ # @return [String] A pattern of +length+ bytes, in which any 4-byte chunk is
20
+ # unique
21
+ # @see pattern_offset
22
+ def self.pattern_create(length, sets = nil)
23
+ buf = ''
24
+ offsets = []
25
+
26
+ # Make sure there's something in sets even if we were given an explicit nil
27
+ sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
28
+
29
+ # Return stupid uses
30
+ return "" if length.to_i < 1
31
+ return sets[0][0].chr * length if sets.size == 1 and sets[0].size == 1
32
+
33
+ sets.length.times { offsets << 0 }
34
+
35
+ until buf.length >= length
36
+ begin
37
+ buf << converge_sets(sets, 0, offsets, length)
38
+ end
39
+ end
40
+
41
+ # Maximum permutations reached, but we need more data
42
+ if (buf.length < length)
43
+ buf = buf * (length / buf.length.to_f).ceil
44
+ end
45
+
46
+ buf[0,length]
47
+ end
48
+
49
+ # Step through an arbitrary number of sets of bytes to build up a findable pattern.
50
+ # This is mostly useful for experimentially determining offset lengths into memory
51
+ # structures. Note that the supplied sets should never contain duplicate bytes, or
52
+ # else it can become impossible to measure the offset accurately.
53
+ def self.patt2(len, sets = nil)
54
+ buf = ""
55
+ counter = []
56
+ sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
57
+ len ||= len.to_i
58
+ return "" if len.zero?
59
+
60
+ sets = sets.map {|a| a.split(//)}
61
+ sets.size.times { counter << 0}
62
+ 0.upto(len-1) do |i|
63
+ setnum = i % sets.size
64
+
65
+ #puts counter.inspect
66
+ end
67
+
68
+ return buf
69
+ end
70
+
71
+ #
72
+ # Calculate the offset to a pattern
73
+ #
74
+ # @param pattern [String] The pattern to search. Usually the return value
75
+ # from {.pattern_create}
76
+ # @param value [String,Fixnum,Bignum]
77
+ # @return [Fixnum] Index of the given +value+ within +pattern+, if it exists
78
+ # @return [nil] if +pattern+ does not contain +value+
79
+ # @see pattern_create
80
+ def self.pattern_offset(pattern, value, start=0)
81
+ if (value.kind_of?(String))
82
+ pattern.index(value, start)
83
+ elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum))
84
+ pattern.index([ value ].pack('V'), start)
85
+ else
86
+ raise ::ArgumentError, "Invalid class for value: #{value.class}"
87
+ end
88
+ end
89
+
90
+ end
91
+ end
@@ -0,0 +1,233 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Text
4
+ # We are re-opening the module to add these module methods.
5
+ # Breaking them up this way allows us to maintain a little higher
6
+ # degree of organisation and make it easier to find what you're looking for
7
+ # without hanging the underlying calls that we historically rely upon.
8
+
9
+
10
+ TLDs = ['com', 'net', 'org', 'gov', 'biz', 'edu']
11
+ States = ["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DE", "FL", "GA", "HI",
12
+ "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN",
13
+ "MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH",
14
+ "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA",
15
+ "WI", "WV", "WY"]
16
+ #
17
+ # Most 100 common surnames, male/female names in the U.S. (http://names.mongabay.com/)
18
+ #
19
+
20
+ Surnames = [
21
+ "adams", "alexander", "allen", "anderson", "bailey", "baker", "barnes",
22
+ "bell", "bennett", "brooks", "brown", "bryant", "butler", "campbell",
23
+ "carter", "clark", "coleman", "collins", "cook", "cooper", "cox",
24
+ "davis", "diaz", "edwards", "evans", "flores", "foster", "garcia",
25
+ "gonzales", "gonzalez", "gray", "green", "griffin", "hall", "harris",
26
+ "hayes", "henderson", "hernandez", "hill", "howard", "hughes", "jackson",
27
+ "james", "jenkins", "johnson", "jones", "kelly", "king", "lee", "lewis",
28
+ "long", "lopez", "martin", "martinez", "miller", "mitchell", "moore",
29
+ "morgan", "morris", "murphy", "nelson", "parker", "patterson", "perez",
30
+ "perry", "peterson", "phillips", "powell", "price", "ramirez", "reed",
31
+ "richardson", "rivera", "roberts", "robinson", "rodriguez", "rogers",
32
+ "ross", "russell", "sanchez", "sanders", "scott", "simmons", "smith",
33
+ "stewart", "taylor", "thomas", "thompson", "torres", "turner", "walker",
34
+ "ward", "washington", "watson", "white", "williams", "wilson", "wood",
35
+ "wright", "young"
36
+ ]
37
+
38
+ Names_Male = [
39
+ "aaron", "adam", "alan", "albert", "andrew", "anthony", "antonio",
40
+ "arthur", "benjamin", "billy", "bobby", "brandon", "brian", "bruce",
41
+ "carl", "carlos", "charles", "chris", "christopher", "clarence", "craig",
42
+ "daniel", "david", "dennis", "donald", "douglas", "earl", "edward",
43
+ "eric", "ernest", "eugene", "frank", "fred", "gary", "george", "gerald",
44
+ "gregory", "harold", "harry", "henry", "howard", "jack", "james", "jason",
45
+ "jeffrey", "jeremy", "jerry", "jesse", "jimmy", "joe", "john", "johnny",
46
+ "jonathan", "jose", "joseph", "joshua", "juan", "justin", "keith",
47
+ "kenneth", "kevin", "larry", "lawrence", "louis", "mark", "martin",
48
+ "matthew", "michael", "nicholas", "patrick", "paul", "peter", "philip",
49
+ "phillip", "ralph", "randy", "raymond", "richard", "robert", "roger",
50
+ "ronald", "roy", "russell", "ryan", "samuel", "scott", "sean", "shawn",
51
+ "stephen", "steve", "steven", "terry", "thomas", "timothy", "todd",
52
+ "victor", "walter", "wayne", "william", "willie"
53
+ ]
54
+
55
+ Names_Female = [
56
+ "alice", "amanda", "amy", "andrea", "angela", "ann", "anna", "anne",
57
+ "annie", "ashley", "barbara", "betty", "beverly", "bonnie", "brenda",
58
+ "carol", "carolyn", "catherine", "cheryl", "christina", "christine",
59
+ "cynthia", "deborah", "debra", "denise", "diana", "diane", "donna",
60
+ "doris", "dorothy", "elizabeth", "emily", "evelyn", "frances", "gloria",
61
+ "heather", "helen", "irene", "jacqueline", "jane", "janet", "janice",
62
+ "jean", "jennifer", "jessica", "joan", "joyce", "judith", "judy", "julia",
63
+ "julie", "karen", "katherine", "kathleen", "kathryn", "kathy", "kelly",
64
+ "kimberly", "laura", "lillian", "linda", "lisa", "lois", "lori", "louise",
65
+ "margaret", "maria", "marie", "marilyn", "martha", "mary", "melissa",
66
+ "michelle", "mildred", "nancy", "nicole", "norma", "pamela", "patricia",
67
+ "paula", "phyllis", "rachel", "rebecca", "robin", "rose", "ruby", "ruth",
68
+ "sandra", "sara", "sarah", "sharon", "shirley", "stephanie", "susan",
69
+ "tammy", "teresa", "theresa", "tina", "virginia", "wanda"
70
+ ]
71
+
72
+
73
+ # Generates a random character.
74
+ def self.rand_char(bad, chars = AllChars)
75
+ rand_text(1, bad, chars)
76
+ end
77
+
78
+ # Base text generator method
79
+ def self.rand_base(len, bad, *foo)
80
+ cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq
81
+ return "" if cset.length == 0
82
+ outp = []
83
+ len.times { outp << cset[rand(cset.length)] }
84
+ outp.pack("C*")
85
+ end
86
+
87
+ # Generate random bytes of data
88
+ def self.rand_text(len, bad='', chars = AllChars)
89
+ foo = chars.split('')
90
+ rand_base(len, bad, *foo)
91
+ end
92
+
93
+ # Generate random bytes of alpha data
94
+ def self.rand_text_alpha(len, bad='')
95
+ foo = []
96
+ foo += ('A' .. 'Z').to_a
97
+ foo += ('a' .. 'z').to_a
98
+ rand_base(len, bad, *foo )
99
+ end
100
+
101
+ # Generate random bytes of lowercase alpha data
102
+ def self.rand_text_alpha_lower(len, bad='')
103
+ rand_base(len, bad, *('a' .. 'z').to_a)
104
+ end
105
+
106
+ # Generate random bytes of uppercase alpha data
107
+ def self.rand_text_alpha_upper(len, bad='')
108
+ rand_base(len, bad, *('A' .. 'Z').to_a)
109
+ end
110
+
111
+ # Generate random bytes of alphanumeric data
112
+ def self.rand_text_alphanumeric(len, bad='')
113
+ foo = []
114
+ foo += ('A' .. 'Z').to_a
115
+ foo += ('a' .. 'z').to_a
116
+ foo += ('0' .. '9').to_a
117
+ rand_base(len, bad, *foo )
118
+ end
119
+
120
+ # Generate random bytes of alphanumeric hex.
121
+ def self.rand_text_hex(len, bad='')
122
+ foo = []
123
+ foo += ('0' .. '9').to_a
124
+ foo += ('a' .. 'f').to_a
125
+ rand_base(len, bad, *foo)
126
+ end
127
+
128
+ # Generate random bytes of numeric data
129
+ def self.rand_text_numeric(len, bad='')
130
+ foo = ('0' .. '9').to_a
131
+ rand_base(len, bad, *foo )
132
+ end
133
+
134
+ # Generate random bytes of english-like data
135
+ def self.rand_text_english(len, bad='')
136
+ foo = []
137
+ foo += (0x21 .. 0x7e).map{ |c| c.chr }
138
+ rand_base(len, bad, *foo )
139
+ end
140
+
141
+ # Generate random bytes of high ascii data
142
+ def self.rand_text_highascii(len, bad='')
143
+ foo = []
144
+ foo += (0x80 .. 0xff).map{ |c| c.chr }
145
+ rand_base(len, bad, *foo )
146
+ end
147
+
148
+ # Generate random bytes of base64 data
149
+ def self.rand_text_base64(len, bad='')
150
+ foo = Base64.unpack('C*').map{ |c| c.chr }
151
+ rand_base(len, bad, *foo )
152
+ end
153
+
154
+ # Generate random bytes of base64url data
155
+ def self.rand_text_base64url(len, bad='')
156
+ foo = Base64Url.unpack('C*').map{ |c| c.chr }
157
+ rand_base(len, bad, *foo )
158
+ end
159
+
160
+ # Generate a random GUID
161
+ #
162
+ # @example
163
+ # Rex::Text.rand_guid # => "{ca776ced-4ab8-2ed6-6510-aa71e5e2508e}"
164
+ #
165
+ # @return [String]
166
+ def self.rand_guid
167
+ "{#{[8,4,4,4,12].map {|a| rand_text_hex(a) }.join("-")}}"
168
+ end
169
+
170
+ #
171
+ # Generate a valid random 4 byte UTF-8 character
172
+ # valid codepoints for 4byte UTF-8 chars: U+010000 - U+10FFFF
173
+ #
174
+ # @example
175
+ # Rex::Text.rand_4byte_utf8 # => "\u{108CF3}"
176
+ #
177
+ # @return [String]
178
+ def self.rand_4byte_utf8
179
+ [rand(0x10000..0x10ffff)].pack('U*')
180
+ end
181
+
182
+ # Generate a random hostname
183
+ #
184
+ # @return [String] A random string conforming to the rules of FQDNs
185
+ def self.rand_hostname
186
+ host = []
187
+ (rand(5) + 1).times {
188
+ host.push(Rex::Text.rand_text_alphanumeric(rand(10) + 1))
189
+ }
190
+ host.push(TLDs.sample)
191
+ host.join('.').downcase
192
+ end
193
+
194
+ # Generate a state
195
+ def self.rand_state()
196
+ States.sample
197
+ end
198
+
199
+ # Generate a surname
200
+ def self.rand_surname
201
+ Surnames.sample
202
+ end
203
+
204
+ # Generate a name
205
+ def self.rand_name
206
+ if rand(10) % 2 == 0
207
+ Names_Male.sample
208
+ else
209
+ Names_Female.sample
210
+ end
211
+ end
212
+
213
+ # Generate a male name
214
+ def self.rand_name_male
215
+ Names_Male.sample
216
+ end
217
+
218
+ # Generate a female name
219
+ def self.rand_name_female
220
+ Names_Female.sample
221
+ end
222
+
223
+ # Generate a random mail address
224
+ def self.rand_mail_address
225
+ mail_address = ''
226
+ mail_address << Rex::Text.rand_name
227
+ mail_address << '.'
228
+ mail_address << Rex::Text.rand_surname
229
+ mail_address << '@'
230
+ mail_address << Rex::Text.rand_hostname
231
+ end
232
+ end
233
+ end