ronin-support 0.2.0 → 0.3.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.
Files changed (62) hide show
  1. data/.gitignore +11 -0
  2. data/ChangeLog.md +42 -1
  3. data/README.md +4 -1
  4. data/gemspec.yml +2 -1
  5. data/lib/ronin/extensions.rb +2 -0
  6. data/lib/ronin/extensions/enumerable.rb +54 -0
  7. data/lib/ronin/extensions/file.rb +70 -2
  8. data/lib/ronin/extensions/ip_addr.rb +45 -45
  9. data/lib/ronin/extensions/regexp.rb +45 -0
  10. data/lib/ronin/extensions/resolv.rb +80 -0
  11. data/lib/ronin/extensions/string.rb +35 -32
  12. data/lib/ronin/formatting/extensions/binary/integer.rb +12 -5
  13. data/lib/ronin/formatting/extensions/binary/string.rb +44 -16
  14. data/lib/ronin/formatting/extensions/html/integer.rb +51 -31
  15. data/lib/ronin/formatting/extensions/html/string.rb +50 -31
  16. data/lib/ronin/formatting/extensions/http/integer.rb +10 -2
  17. data/lib/ronin/formatting/extensions/sql.rb +20 -0
  18. data/lib/ronin/formatting/extensions/sql/string.rb +98 -0
  19. data/lib/ronin/formatting/extensions/text/array.rb +11 -9
  20. data/lib/ronin/formatting/extensions/text/string.rb +213 -29
  21. data/lib/ronin/formatting/sql.rb +20 -0
  22. data/lib/ronin/network/extensions/http.rb +1 -0
  23. data/lib/ronin/network/extensions/http/net.rb +2 -2
  24. data/lib/ronin/network/extensions/http/uri/http.rb +226 -0
  25. data/lib/ronin/network/extensions/imap/net.rb +1 -1
  26. data/lib/ronin/network/extensions/ssl/net.rb +7 -1
  27. data/lib/ronin/network/http/proxy.rb +20 -21
  28. data/lib/ronin/network/mixins.rb +27 -0
  29. data/lib/ronin/network/mixins/esmtp.rb +165 -0
  30. data/lib/ronin/network/mixins/http.rb +723 -0
  31. data/lib/ronin/network/mixins/imap.rb +151 -0
  32. data/lib/ronin/network/mixins/pop3.rb +141 -0
  33. data/lib/ronin/network/mixins/smtp.rb +159 -0
  34. data/lib/ronin/network/mixins/tcp.rb +331 -0
  35. data/lib/ronin/network/mixins/telnet.rb +199 -0
  36. data/lib/ronin/network/mixins/udp.rb +227 -0
  37. data/lib/ronin/network/ssl.rb +17 -11
  38. data/lib/ronin/path.rb +3 -3
  39. data/lib/ronin/spec/ui/output.rb +28 -0
  40. data/lib/ronin/support.rb +3 -0
  41. data/lib/ronin/support/version.rb +1 -1
  42. data/lib/ronin/ui/output.rb +21 -0
  43. data/lib/ronin/ui/output/helpers.rb +248 -0
  44. data/lib/ronin/ui/output/output.rb +146 -0
  45. data/lib/ronin/ui/output/terminal.rb +21 -0
  46. data/lib/ronin/ui/output/terminal/color.rb +118 -0
  47. data/lib/ronin/ui/output/terminal/raw.rb +103 -0
  48. data/lib/ronin/ui/shell.rb +219 -0
  49. data/ronin-support.gemspec +1 -1
  50. data/spec/extensions/enumerable_spec.rb +24 -0
  51. data/spec/extensions/file_spec.rb +39 -0
  52. data/spec/extensions/ip_addr_spec.rb +6 -0
  53. data/spec/extensions/resolv_spec.rb +18 -0
  54. data/spec/formatting/html/integer_spec.rb +2 -2
  55. data/spec/formatting/html/string_spec.rb +1 -1
  56. data/spec/formatting/sql/string_spec.rb +55 -0
  57. data/spec/formatting/text/string_spec.rb +110 -0
  58. data/spec/network/ssl_spec.rb +10 -4
  59. data/spec/ui/classes/test_shell.rb +22 -0
  60. data/spec/ui/output_spec.rb +32 -0
  61. data/spec/ui/shell_spec.rb +79 -0
  62. metadata +132 -90
@@ -0,0 +1,80 @@
1
+ #
2
+ # Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of Ronin Support.
5
+ #
6
+ # Ronin Support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Ronin Support is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'resolv'
21
+
22
+ class Resolv
23
+
24
+ # List of valid Top-Level-Domains
25
+ TLDS = %w[
26
+ aero arpa asia biz cat com coop edu gov info int jobs mil mobi museum net
27
+ org pro tel travel xxx
28
+
29
+ ac ad ae af ag ai al am an ao aq ar as at au aw ax az
30
+ ba bb bd be bf bg bh bi bj bm bn bo br bs bt bv bw by bz
31
+ ca cc cd cf cg ch ci ck cl cm cn co cr cs cu cv cx cy cz
32
+ dd de dj dk dm do dz
33
+ ec ee eg eh er es et eu
34
+ fi fj fk fm fo fr
35
+ ga gb gd ge gf gg gh gi gl gm gn gp gq gr gs gt gu gw gy
36
+ hk hm hn hr ht hu
37
+ id ie il im in io iq ir is it
38
+ je jm jo jp
39
+ ke kg kh ki km kn kp kr kw ky kz
40
+ la lb lc li lk lr ls lt lu lv ly
41
+ ma mc md me mg mh mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz
42
+ na nc ne nf ng ni nl no np nr nu nz
43
+ om
44
+ pa pe pf pg ph pk pl pm pn pr ps pt pw py
45
+ qa
46
+ re ro rs ru rw
47
+ sa sb sc sd se sg sh si sj sk sl sm sn so sr ss st su sv sy sz
48
+ tc td tf tg th tj tk tl tm tn to tp tr tt tv tw tz
49
+ ua ug ak us uy uz
50
+ va vc ve vg vi vn vu
51
+ wf ws
52
+ ye yt
53
+ za zm zw
54
+ ]
55
+
56
+ #
57
+ # Creates a new resolver.
58
+ #
59
+ # @param [String, Array<String>, nil] nameserver
60
+ # The nameserver(s) to query.
61
+ #
62
+ # @return [Resolv::DNS]
63
+ # A new resolver for the given nameservers, or the default resolver.
64
+ #
65
+ # @example
66
+ # Resolv.resolver('4.2.2.1')
67
+ #
68
+ # @since 0.3.0
69
+ #
70
+ # @api public
71
+ #
72
+ def Resolv.resolver(nameserver=nil)
73
+ if nameserver
74
+ DNS.new(:nameserver => nameserver)
75
+ else
76
+ self
77
+ end
78
+ end
79
+
80
+ end
@@ -39,13 +39,17 @@ class String
39
39
  # @return [String]
40
40
  # The original string
41
41
  #
42
+ # @example
43
+ # "hello".each_substring(3).to_a
44
+ # # => ["hel", "hell", "hello", "ell", "ello", "llo"]
45
+ #
42
46
  # @api public
43
47
  #
44
- def each_substring(min=0,&block)
48
+ def each_substring(min=1,&block)
45
49
  return enum_for(:each_substring,min) unless block
46
50
 
47
- (0..(self.length - min)).each do |i|
48
- ((i + min)..self.length).each do |j|
51
+ (0..(length - min)).each do |i|
52
+ ((i + min)..length).each do |j|
49
53
  sub_string = self[i...j]
50
54
 
51
55
  if block.arity == 2
@@ -79,11 +83,15 @@ class String
79
83
  # @return [String]
80
84
  # The original string
81
85
  #
86
+ # @example
87
+ # "xoxo".each_unique_substring(2).to_a
88
+ # # => ["xo", "xox", "xoxo", "ox", "oxo"]
89
+ #
82
90
  # @see each_substring
83
91
  #
84
92
  # @api public
85
93
  #
86
- def each_unique_substring(min=0,&block)
94
+ def each_unique_substring(min=1,&block)
87
95
  return enum_for(:each_unique_substring,min) unless block
88
96
 
89
97
  unique_strings = {}
@@ -119,11 +127,11 @@ class String
119
127
 
120
128
  min_length.times do |i|
121
129
  if self[i] != other[i]
122
- return self[0...i]
130
+ return self[0,i]
123
131
  end
124
132
  end
125
133
 
126
- return self[0...min_length]
134
+ return self[0,min_length]
127
135
  end
128
136
 
129
137
  #
@@ -143,7 +151,7 @@ class String
143
151
  min_length = [length, other.length].min
144
152
 
145
153
  (min_length - 1).times do |i|
146
- index = (length - i - 1)
154
+ index = (length - i - 1)
147
155
  other_index = (other.length - i - 1)
148
156
 
149
157
  if self[index] != other[other_index]
@@ -160,8 +168,8 @@ class String
160
168
  # Please use {#common_suffix} instead.
161
169
  #
162
170
  def common_postfix(other)
163
- warn "DEPRECATED: String#common_postfix was deprecated in 0.2.0."
164
- warn "DEPRECATED: Please use String#common_suffix instead."
171
+ warn 'DEPRECATED: String#common_postfix was deprecated in 0.2.0.'
172
+ warn 'DEPRECATED: Please use String#common_suffix instead.'
165
173
 
166
174
  common_suffix(other)
167
175
  end
@@ -179,25 +187,29 @@ class String
179
187
  # @api public
180
188
  #
181
189
  def uncommon_substring(other)
182
- prefix = common_prefix(other)
190
+ prefix = common_prefix(other)
183
191
  postfix = self[prefix.length..-1].common_suffix(other[prefix.length..-1])
184
192
 
185
193
  return self[prefix.length...(length - postfix.length)]
186
194
  end
187
195
 
188
196
  if RUBY_VERSION < '1.9.'
189
- ESCAPE_BYTES = {
190
- 0x00 => '\0',
191
- 0x07 => '\a',
192
- 0x08 => '\b',
193
- 0x09 => '\t',
194
- 0x0a => '\n',
195
- 0x0b => '\v',
196
- 0x0c => '\f',
197
- 0x0d => '\r',
198
- 0x22 => '\"',
199
- 0x5c => '\\'
200
- }
197
+ ESCAPE_BYTES = Hash.new do |escape,byte|
198
+ escape[byte] = if (byte >= 0x20 && byte <= 0x7e)
199
+ byte.chr
200
+ else
201
+ "\\x%.2X" % byte
202
+ end
203
+ end
204
+
205
+ ESCAPE_BYTES[0x00] = '\0'
206
+ ESCAPE_BYTES[0x07] = '\a'
207
+ ESCAPE_BYTES[0x08] = '\b'
208
+ ESCAPE_BYTES[0x09] = '\t'
209
+ ESCAPE_BYTES[0x0a] = '\n'
210
+ ESCAPE_BYTES[0x0b] = '\v'
211
+ ESCAPE_BYTES[0x0c] = '\f'
212
+ ESCAPE_BYTES[0x0d] = '\r'
201
213
 
202
214
  #
203
215
  # Dumps the string as a C-style string.
@@ -217,16 +229,7 @@ class String
217
229
  def dump
218
230
  dumped_string = ''
219
231
 
220
- each_byte do |b|
221
- dumped_string << if (b >= 0x20 && b <= 0x7e)
222
- b.chr
223
- elsif ESCAPE_BYTES.has_key?(b)
224
- ESCAPE_BYTES[b]
225
- else
226
- ("\\x%.2X" % b)
227
- end
228
- end
229
-
232
+ each_byte { |b| dumped_string << ESCAPE_BYTES[b] }
230
233
  return "\"#{dumped_string}\""
231
234
  end
232
235
 
@@ -27,14 +27,21 @@ class Integer
27
27
  #
28
28
  # @param [Symbol, String] endian
29
29
  # The endianness to use while decoding the bytes of the Integer.
30
- # May be either `:big`, `:little` or `:net`.
30
+ # May be one of:
31
+ #
32
+ # * `:big` / `"big"`
33
+ # * `:little` / `"little"`
34
+ # * `:net` / `"net"`
31
35
  #
32
36
  # @return [Array]
33
37
  # The bytes decoded from the Integer.
34
38
  #
35
39
  # @raise [ArgumentError]
36
- # The given `endian` is not `:little`, `"little"`, `:net`, `"net"`,
37
- # `:big` or `"big"`.
40
+ # The given `endian` was not one of:
41
+ #
42
+ # * `:little` / `"little"`
43
+ # * `:net` / `"net"`
44
+ # * `:big` / `"big"`
38
45
  #
39
46
  # @example
40
47
  # 0xff41.bytes(2)
@@ -52,7 +59,7 @@ class Integer
52
59
 
53
60
  case endian
54
61
  when :little, :net
55
- mask = 0xff
62
+ mask = 0xff
56
63
  shift = 0
57
64
 
58
65
  address_length.times do |i|
@@ -63,7 +70,7 @@ class Integer
63
70
  end
64
71
  when :big
65
72
  shift = ((address_length - 1) * 8)
66
- mask = (0xff << shift)
73
+ mask = (0xff << shift)
67
74
 
68
75
  address_length.times do |i|
69
76
  buffer << ((self & mask) >> shift)
@@ -84,15 +84,16 @@ class String
84
84
  raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
85
85
  end
86
86
 
87
+ endian = arch.endian.to_sym
87
88
  address_length ||= arch.address_length
88
89
 
89
90
  integer = 0x0
90
91
  byte_index = 0
91
92
 
92
- case arch.endian
93
- when :little, 'little'
93
+ case endian
94
+ when :little
94
95
  mask = lambda { |b| b << (byte_index * 8) }
95
- when :big, 'big'
96
+ when :big
96
97
  mask = lambda { |b|
97
98
  b << ((address_length - byte_index - 1) * 8)
98
99
  }
@@ -100,7 +101,7 @@ class String
100
101
  raise(ArgumentError,"invalid endian #{arch.endian.inspect}")
101
102
  end
102
103
 
103
- self.each_byte do |b|
104
+ each_byte do |b|
104
105
  break if byte_index >= address_length
105
106
 
106
107
  integer |= mask.call(b)
@@ -110,6 +111,8 @@ class String
110
111
  return integer
111
112
  end
112
113
 
114
+ #
115
+ # Hex-escapes characters in the String.
113
116
  #
114
117
  # @return [String]
115
118
  # The hex escaped version of the String.
@@ -207,18 +210,23 @@ class String
207
210
  # @api public
208
211
  #
209
212
  def xor(key)
210
- key = if key.kind_of?(Integer)
213
+ key = case key
214
+ when Integer
211
215
  [key]
212
- elsif key.kind_of?(String)
216
+ when String
213
217
  key.bytes
214
218
  else
215
219
  key
216
220
  end
217
221
 
218
- key = key.cycle
222
+ key = key.cycle
219
223
  result = ''
220
224
 
221
- self.bytes.inject('') { |result,b| result << (b ^ key.next).chr }
225
+ bytes.each do |b|
226
+ result << (b ^ key.next).chr
227
+ end
228
+
229
+ return result
222
230
  end
223
231
 
224
232
  #
@@ -227,6 +235,10 @@ class String
227
235
  # @return [String]
228
236
  # The base64 encoded form of the string.
229
237
  #
238
+ # @example
239
+ # "hello".base64_encode
240
+ # # => "aGVsbG8=\n"
241
+ #
230
242
  # @api public
231
243
  #
232
244
  def base64_encode
@@ -239,6 +251,10 @@ class String
239
251
  # @return [String]
240
252
  # The base64 decoded form of the string.
241
253
  #
254
+ # @example
255
+ # "aGVsbG8=\n"
256
+ # # => "hello"
257
+ #
242
258
  # @api public
243
259
  #
244
260
  def base64_decode
@@ -251,6 +267,10 @@ class String
251
267
  # @return [String]
252
268
  # The Zlib inflated form of the string.
253
269
  #
270
+ # @example
271
+ # "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15".zlib_inflate
272
+ # # => "hello"
273
+ #
254
274
  # @api public
255
275
  #
256
276
  def zlib_inflate
@@ -263,6 +283,10 @@ class String
263
283
  # @return [String]
264
284
  # The Zlib deflated form of the string.
265
285
  #
286
+ # @example
287
+ # "hello".zlib_deflate
288
+ # # => "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15"
289
+ #
266
290
  # @api public
267
291
  #
268
292
  def zlib_deflate
@@ -282,6 +306,7 @@ class String
282
306
  # @option options [Symbol] :encoding
283
307
  # Denotes the encoding used for the bytes within the hexdump.
284
308
  # Must be one of the following:
309
+ #
285
310
  # * `:binary`
286
311
  # * `:octal`
287
312
  # * `:octal_bytes`
@@ -309,14 +334,17 @@ class String
309
334
  def unhexdump(options={})
310
335
  case (format = options[:format])
311
336
  when :od
312
- address_base = base = 8
313
- word_size = 2
337
+ address_base = 8
338
+ base = 8
339
+ word_size = 2
314
340
  when :hexdump
315
- address_base = base = 16
316
- word_size = 2
341
+ address_base = 16
342
+ base = 16
343
+ word_size = 2
317
344
  else
318
- address_base = base = 16
319
- word_size = 1
345
+ address_base = 16
346
+ base = 16
347
+ word_size = 1
320
348
  end
321
349
 
322
350
  case options[:encoding]
@@ -379,13 +407,13 @@ class String
379
407
  end
380
408
  end
381
409
 
382
- segment = segment[0...segment_length]
410
+ segment = segment[0,segment_length]
383
411
  buffer += segment
384
412
  last_addr = current_addr
385
413
  end
386
414
  end
387
415
 
388
- return buffer[0...(last_addr - first_addr)]
416
+ return buffer[0,(last_addr - first_addr)]
389
417
  end
390
418
 
391
419
  end
@@ -23,38 +23,38 @@ class Integer
23
23
 
24
24
  # Special JavaScript bytes and their escaped Strings.
25
25
  JS_ESCAPE_BYTES = {
26
- 0x00 => '%u0000',
27
- 0x01 => '%u0001',
28
- 0x02 => '%u0002',
29
- 0x03 => '%u0003',
30
- 0x04 => '%u0004',
31
- 0x05 => '%u0005',
32
- 0x06 => '%u0006',
33
- 0x07 => '%u0007',
26
+ 0x00 => '\u0000',
27
+ 0x01 => '\u0001',
28
+ 0x02 => '\u0002',
29
+ 0x03 => '\u0003',
30
+ 0x04 => '\u0004',
31
+ 0x05 => '\u0005',
32
+ 0x06 => '\u0006',
33
+ 0x07 => '\u0007',
34
34
  0x08 => '\b',
35
35
  0x09 => '\t',
36
36
  0x0a => '\n',
37
- 0x0b => '%u000b',
37
+ 0x0b => '\u000b',
38
38
  0x0c => '\f',
39
39
  0x0d => '\r',
40
- 0x0e => '%u000e',
41
- 0x0f => '%u000f',
42
- 0x10 => '%u0010',
43
- 0x11 => '%u0011',
44
- 0x12 => '%u0012',
45
- 0x13 => '%u0013',
46
- 0x14 => '%u0014',
47
- 0x15 => '%u0015',
48
- 0x16 => '%u0016',
49
- 0x17 => '%u0017',
50
- 0x18 => '%u0018',
51
- 0x19 => '%u0019',
52
- 0x1a => '%u001a',
53
- 0x1b => '%u001b',
54
- 0x1c => '%u001c',
55
- 0x1d => '%u001d',
56
- 0x1e => '%u001e',
57
- 0x1f => '%u001f',
40
+ 0x0e => '\u000e',
41
+ 0x0f => '\u000f',
42
+ 0x10 => '\u0010',
43
+ 0x11 => '\u0011',
44
+ 0x12 => '\u0012',
45
+ 0x13 => '\u0013',
46
+ 0x14 => '\u0014',
47
+ 0x15 => '\u0015',
48
+ 0x16 => '\u0016',
49
+ 0x17 => '\u0017',
50
+ 0x18 => '\u0018',
51
+ 0x19 => '\u0019',
52
+ 0x1a => '\u001a',
53
+ 0x1b => '\u001b',
54
+ 0x1c => '\u001c',
55
+ 0x1d => '\u001d',
56
+ 0x1e => '\u001e',
57
+ 0x1f => '\u001f',
58
58
  0x22 => '\"',
59
59
  0x5c => '\\\\',
60
60
  }
@@ -65,12 +65,16 @@ class Integer
65
65
  # @return [String]
66
66
  # The escaped HTML String.
67
67
  #
68
+ # @example
69
+ # 0x26.html_escape
70
+ # # => "&amp;"
71
+ #
68
72
  # @since 0.2.0
69
73
  #
70
74
  # @api public
71
75
  #
72
76
  def html_escape
73
- CGI.escapeHTML(self.chr)
77
+ CGI.escapeHTML(chr)
74
78
  end
75
79
 
76
80
  #
@@ -79,6 +83,10 @@ class Integer
79
83
  # @return [String]
80
84
  # The HTML String.
81
85
  #
86
+ # @example
87
+ # 0x41.format_html
88
+ # # => "&#65;"
89
+ #
82
90
  # @since 0.2.0
83
91
  #
84
92
  # @api public
@@ -93,6 +101,14 @@ class Integer
93
101
  # @return [String]
94
102
  # The escaped JavaScript String.
95
103
  #
104
+ # @example
105
+ # 0x22.js_escape
106
+ # # => "\\\""
107
+ #
108
+ # @example
109
+ # 0x7f.js_escape
110
+ # # => "\x7F"
111
+ #
96
112
  # @since 0.2.0
97
113
  #
98
114
  # @api public
@@ -101,7 +117,7 @@ class Integer
101
117
  if self > 0xff
102
118
  format_js
103
119
  else
104
- JS_ESCAPE_BYTES.fetch(self,self.chr)
120
+ JS_ESCAPE_BYTES.fetch(self,chr)
105
121
  end
106
122
  end
107
123
 
@@ -111,15 +127,19 @@ class Integer
111
127
  # @return [String]
112
128
  # The escaped JavaScript String.
113
129
  #
130
+ # @example
131
+ # 0x41.format_js
132
+ # # => "%41"
133
+ #
114
134
  # @since 0.2.0
115
135
  #
116
136
  # @api public
117
137
  #
118
138
  def format_js
119
139
  if self > 0xff
120
- "%%u%.2X%.2X" % [(self & 0xff00) >> 8, (self & 0xff)]
140
+ "\\u%.2X%.2X" % [(self & 0xff00) >> 8, (self & 0xff)]
121
141
  else
122
- "%%%.2X" % self
142
+ "\\x%.2X" % self
123
143
  end
124
144
  end
125
145