ronin-support 0.5.0 → 0.5.1

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 (38) hide show
  1. data/ChangeLog.md +13 -1
  2. data/README.md +5 -3
  3. data/lib/ronin/binary/hexdump/parser.rb +10 -18
  4. data/lib/ronin/binary/struct.rb +18 -32
  5. data/lib/ronin/binary/template.rb +29 -19
  6. data/lib/ronin/extensions/ip_addr.rb +5 -10
  7. data/lib/ronin/extensions/resolv.rb +2 -4
  8. data/lib/ronin/formatting/extensions/binary.rb +1 -0
  9. data/lib/ronin/formatting/extensions/binary/array.rb +5 -7
  10. data/lib/ronin/formatting/extensions/binary/float.rb +4 -4
  11. data/lib/ronin/formatting/extensions/binary/integer.rb +14 -11
  12. data/lib/ronin/formatting/extensions/binary/string.rb +14 -25
  13. data/lib/ronin/formatting/extensions/html/integer.rb +4 -8
  14. data/lib/ronin/formatting/extensions/html/string.rb +24 -32
  15. data/lib/ronin/formatting/extensions/sql/string.rb +9 -13
  16. data/lib/ronin/formatting/extensions/text/array.rb +8 -6
  17. data/lib/ronin/formatting/extensions/text/string.rb +4 -8
  18. data/lib/ronin/fuzzing/fuzzer.rb +8 -16
  19. data/lib/ronin/network/dns.rb +2 -4
  20. data/lib/ronin/network/ftp.rb +5 -1
  21. data/lib/ronin/network/ssl.rb +9 -10
  22. data/lib/ronin/network/tcp/tcp.rb +8 -0
  23. data/lib/ronin/network/udp/proxy.rb +2 -2
  24. data/lib/ronin/network/udp/udp.rb +8 -0
  25. data/lib/ronin/network/unix.rb +4 -5
  26. data/lib/ronin/path.rb +2 -2
  27. data/lib/ronin/support/version.rb +1 -1
  28. data/lib/ronin/ui/output/helpers.rb +2 -4
  29. data/lib/ronin/ui/shell.rb +3 -6
  30. data/spec/binary/template_spec.rb +14 -0
  31. data/spec/formatting/binary/array_spec.rb +8 -4
  32. data/spec/formatting/binary/float_spec.rb +8 -4
  33. data/spec/formatting/binary/integer_spec.rb +16 -4
  34. data/spec/formatting/binary/string_spec.rb +8 -4
  35. data/spec/network/ftp_spec.rb +16 -0
  36. data/spec/network/network_spec.rb +1 -1
  37. data/spec/network/ssl_spec.rb +50 -0
  38. metadata +359 -399
@@ -31,7 +31,8 @@ class Float
31
31
  # The packed float.
32
32
  #
33
33
  # @raise [ArgumentError]
34
- # The argument was not a String code or a Symbol.
34
+ # The given Symbol could not be found in
35
+ # {Ronin::Binary::Template::FLOAT_TYPES}.
35
36
  #
36
37
  # @example using `Array#pack` template:
37
38
  # 0.42.pack('F')
@@ -42,6 +43,7 @@ class Float
42
43
  # # => ">\xD7\n="
43
44
  #
44
45
  # @see http://rubydoc.info/stdlib/core/Array:pack
46
+ # @see Ronin::Binary::Template
45
47
  #
46
48
  # @since 0.5.0
47
49
  #
@@ -51,14 +53,12 @@ class Float
51
53
  case argument
52
54
  when String
53
55
  [self].pack(argument)
54
- when Symbol
56
+ else
55
57
  unless Ronin::Binary::Template::FLOAT_TYPES.include?(argument)
56
58
  raise(ArgumentError,"unsupported integer type: #{argument}")
57
59
  end
58
60
 
59
61
  [self].pack(Ronin::Binary::Template::TYPES[argument])
60
- else
61
- raise(ArgumentError,"argument must be a String or a Symbol")
62
62
  end
63
63
  end
64
64
 
@@ -98,7 +98,8 @@ class Integer
98
98
  # The packed Integer.
99
99
  #
100
100
  # @raise [ArgumentError]
101
- # The arguments were not a String, Symbol or Architecture object.
101
+ # The given Symbol could not be found in
102
+ # {Ronin::Binary::Template::INT_TYPES}.
102
103
  #
103
104
  # @example using a `Array#pack` template:
104
105
  # 0x41.pack('V')
@@ -122,22 +123,22 @@ class Integer
122
123
  # # => "\0A"
123
124
  #
124
125
  # @see http://rubydoc.info/stdlib/core/Array:pack
126
+ # @see Ronin::Binary::Template
125
127
  #
126
128
  # @api public
127
129
  #
128
130
  def pack(*arguments)
129
- argument = arguments.first
130
-
131
- case argument
132
- when String
133
- [self].pack(argument)
134
- when Symbol
135
- unless Ronin::Binary::Template::INT_TYPES.include?(argument)
136
- raise(ArgumentError,"unsupported integer type: #{argument}")
131
+ if (arguments.length == 1 && arguments.first.kind_of?(String))
132
+ [self].pack(arguments.first)
133
+ elsif (arguments.length == 1 && arguments.first.kind_of?(Symbol))
134
+ type = arguments.first
135
+
136
+ unless Ronin::Binary::Template::INT_TYPES.include?(type)
137
+ raise(ArgumentError,"unsupported integer type: #{type}")
137
138
  end
138
139
 
139
- [self].pack(Ronin::Binary::Template::TYPES[argument])
140
- else
140
+ [self].pack(Ronin::Binary::Template::TYPES[type])
141
+ elsif (arguments.length == 1 || arguments.length == 2)
141
142
  # TODO: deprecate this calling convention
142
143
  arch, address_length = arguments
143
144
 
@@ -155,6 +156,8 @@ class Integer
155
156
  integer_bytes.map! { |b| b.chr }
156
157
 
157
158
  return integer_bytes.join
159
+ else
160
+ raise(ArgumentError,"wrong number of arguments (#{arguments.length} for 1..2)")
158
161
  end
159
162
  end
160
163
 
@@ -36,14 +36,14 @@ class String
36
36
  #
37
37
  # Unpacks the String.
38
38
  #
39
- # @param [String, Array<Symbol>] arguments
39
+ # @param [String, Array<Symbol, (Symbol, Integer)>] arguments
40
40
  # The `String#unpack` template or a list of {Ronin::Binary::Template} types.
41
41
  #
42
42
  # @return [Array]
43
43
  # The values unpacked from the String.
44
44
  #
45
45
  # @raise [ArgumentError]
46
- # The arguments were not a String or a list of Symbols.
46
+ # One of the arguments was not a known {Ronin::Binary::Template} type.
47
47
  #
48
48
  # @example using {Ronin::Binary::Template} types:
49
49
  # "A\0\0\0hello\0".unpack(:uint32_le, :string)
@@ -54,19 +54,17 @@ class String
54
54
  # # => 65
55
55
  #
56
56
  # @see http://rubydoc.info/stdlib/core/String:unpack
57
+ # @see Ronin::Binary::Template
57
58
  #
58
59
  # @since 0.5.0
59
60
  #
60
61
  # @api public
61
62
  #
62
63
  def unpack(*arguments)
63
- case arguments.first
64
- when String
64
+ if (arguments.length == 1 && arguments.first.kind_of?(String))
65
65
  unpack_original(arguments.first)
66
- when Symbol
67
- unpack_original(Ronin::Binary::Template.compile(arguments))
68
66
  else
69
- raise(ArgumentError,"first argument to String#unpack must be a String or Symbol")
67
+ unpack_original(Ronin::Binary::Template.compile(arguments))
70
68
  end
71
69
  end
72
70
 
@@ -190,12 +188,9 @@ class String
190
188
  #
191
189
  def xor(key)
192
190
  key = case key
193
- when Integer
194
- [key]
195
- when String
196
- key.bytes
197
- else
198
- key
191
+ when Integer then [key]
192
+ when String then key.bytes
193
+ else key
199
194
  end
200
195
 
201
196
  key = key.cycle
@@ -229,12 +224,9 @@ class String
229
224
  #
230
225
  def base64_encode(mode=nil)
231
226
  case mode
232
- when :strict
233
- Base64.strict_encode64(self)
234
- when :url, :urlsafe
235
- Base64.urlsafe_encode64(self)
236
- else
237
- Base64.encode64(self)
227
+ when :strict then Base64.strict_encode64(self)
228
+ when :url, :urlsafe then Base64.urlsafe_encode64(self)
229
+ else Base64.encode64(self)
238
230
  end
239
231
  end
240
232
 
@@ -262,12 +254,9 @@ class String
262
254
  #
263
255
  def base64_decode(mode=nil)
264
256
  case mode
265
- when :strict
266
- Base64.strict_decode64(self)
267
- when :url, :urlsafe
268
- Base64.urlsafe_decode64(self)
269
- else
270
- Base64.decode64(self)
257
+ when :strict then Base64.strict_decode64(self)
258
+ when :url, :urlsafe then Base64.urlsafe_decode64(self)
259
+ else Base64.decode64(self)
271
260
  end
272
261
  end
273
262
 
@@ -114,10 +114,8 @@ class Integer
114
114
  # @api public
115
115
  #
116
116
  def js_escape
117
- if self > 0xff
118
- format_js
119
- else
120
- JS_ESCAPE_BYTES.fetch(self,chr)
117
+ if self > 0xff then format_js
118
+ else JS_ESCAPE_BYTES.fetch(self,chr)
121
119
  end
122
120
  end
123
121
 
@@ -136,10 +134,8 @@ class Integer
136
134
  # @api public
137
135
  #
138
136
  def format_js
139
- if self > 0xff
140
- "\\u%.2X%.2X" % [(self & 0xff00) >> 8, (self & 0xff)]
141
- else
142
- "\\x%.2X" % self
137
+ if self > 0xff then "\\u%.4X" % self
138
+ else "\\x%.2X" % self
143
139
  end
144
140
  end
145
141
 
@@ -26,11 +26,11 @@ class String
26
26
 
27
27
  # JavaScript characters that must be back-slashed.
28
28
  JS_BACKSLASHED_CHARS = {
29
- "\\b" => "\b",
30
- "\\t" => "\t",
31
- "\\n" => "\n",
32
- "\\f" => "\f",
33
- "\\r" => "\r",
29
+ "\\b" => "\b",
30
+ "\\t" => "\t",
31
+ "\\n" => "\n",
32
+ "\\f" => "\f",
33
+ "\\r" => "\r",
34
34
  "\\\"" => "\"",
35
35
  "\\\\" => "\\"
36
36
  }
@@ -95,11 +95,9 @@ class String
95
95
  # @api public
96
96
  #
97
97
  def format_html(options={})
98
- formatter = if RUBY_VERSION < '1.9.'
99
- # String#ord was not backported to Ruby 1.8.7
100
- lambda { |c| c[0].format_html }
101
- else
102
- lambda { |c| c.ord.format_html }
98
+ # String#ord was not backported to Ruby 1.8.7
99
+ formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].format_html }
100
+ else lambda { |c| c.ord.format_html }
103
101
  end
104
102
 
105
103
  format_chars(options,&formatter)
@@ -125,11 +123,9 @@ class String
125
123
  # @api public
126
124
  #
127
125
  def js_escape(options={})
128
- formatter = if RUBY_VERSION < '1.9.'
129
- # String#ord was not backported to Rub 1.8.7
130
- lambda { |c| c[0].js_escape }
131
- else
132
- lambda { |c| c.ord.js_escape }
126
+ # String#ord was not backported to Rub 1.8.7
127
+ formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].js_escape }
128
+ else lambda { |c| c.ord.js_escape }
133
129
  end
134
130
 
135
131
  format_chars(options,&formatter)
@@ -152,18 +148,16 @@ class String
152
148
  def js_unescape
153
149
  unescaped = ''
154
150
 
155
- scan(/([\\%]u[0-9a-fA-F]{1,4}|[\\%][0-9a-fA-F]{1,2}|\\[btnfr"\\]|.)/).each do |match|
156
- c = match[0]
157
-
158
- unescaped << if JS_BACKSLASHED_CHARS.has_key?(c)
159
- JS_BACKSLASHED_CHARS[c]
160
- elsif (c.start_with?("\\u") || c.start_with?("%u"))
161
- c[2..-1].to_i(16)
162
- elsif (c.start_with?("\\") || c.start_with?("%"))
163
- c[1..-1].to_i(16)
164
- else
165
- c
166
- end
151
+ scan(/[\\%]u[0-9a-fA-F]{1,4}|[\\%][0-9a-fA-F]{1,2}|\\[btnfr"\\]|./) do |c|
152
+ unescaped << JS_BACKSLASHED_CHARS.fetch(c) do
153
+ if (c.start_with?("\\u") || c.start_with?("%u"))
154
+ c[2..-1].to_i(16)
155
+ elsif (c.start_with?("\\") || c.start_with?("%"))
156
+ c[1..-1].to_i(16)
157
+ else
158
+ c
159
+ end
160
+ end
167
161
  end
168
162
 
169
163
  return unescaped
@@ -189,11 +183,9 @@ class String
189
183
  # @api public
190
184
  #
191
185
  def format_js(options={})
192
- formatter = if RUBY_VERSION < '1.9.'
193
- # String#ord was not backported to Rub 1.8.7
194
- lambda { |c| c[0].format_js }
195
- else
196
- lambda { |c| c.ord.format_js }
186
+ # String#ord was not backported to Rub 1.8.7
187
+ formatter = if RUBY_VERSION < '1.9.' then lambda { |c| c[0].format_js }
188
+ else lambda { |c| c.ord.format_js }
197
189
  end
198
190
 
199
191
  format_chars(options,&formatter)
@@ -40,10 +40,8 @@ class String
40
40
  #
41
41
  def sql_escape(quotes=:single)
42
42
  case quotes
43
- when :single
44
- "'#{gsub(/'/,"''")}'"
45
- when :double
46
- "\"#{gsub(/"/,'""')}\""
43
+ when :single then "'#{gsub(/'/,"''")}'"
44
+ when :double then "\"#{gsub(/"/,'""')}\""
47
45
  else
48
46
  raise(ArgumentError,"invalid quoting style #{quotes.inspect}")
49
47
  end
@@ -80,16 +78,16 @@ class String
80
78
  # # => "/etc/passwd"
81
79
  #
82
80
  def sql_decode
83
- if ((self[0...2] == '0x') && (length % 2 == 0))
81
+ if (start_with?('0x') && (length % 2 == 0))
84
82
  raw = ''
85
83
 
86
- self[2..-1].scan(/[0-9a-fA-F]{2}/).each do |hex_char|
87
- raw << hex_char.hex.chr
84
+ self[2..-1].scan(/../) do |hex_char|
85
+ raw << hex_char.to_i(16).chr
88
86
  end
89
87
 
90
88
  return raw
91
- elsif (self[0..0] == "'" && self[-1..-1] == "'")
92
- self[1..-2].gsub("\\'","'").gsub("''","'")
89
+ elsif (start_with?("'") && end_with?("'"))
90
+ self[1..-2].gsub(/\\'|''/,"'")
93
91
  else
94
92
  return self
95
93
  end
@@ -119,10 +117,8 @@ class String
119
117
  #
120
118
  def sql_inject
121
119
  if (start_with?("'") || start_with?('"') || start_with?('`'))
122
- if self[0,1] == self[-1,1]
123
- self[1..-2]
124
- else
125
- "#{self[1..-1]}--"
120
+ if self[0,1] == self[-1,1] then self[1..-2]
121
+ else "#{self[1..-1]}--"
126
122
  end
127
123
  else
128
124
  self
@@ -40,10 +40,12 @@ class Array
40
40
  bytes = []
41
41
 
42
42
  each do |element|
43
- if element.kind_of?(Integer)
44
- bytes << element
43
+ case element
44
+ when Integer then bytes << element
45
45
  else
46
- element.to_s.each_byte { |b| bytes << b }
46
+ element.to_s.each_byte do |b|
47
+ bytes << b
48
+ end
47
49
  end
48
50
  end
49
51
 
@@ -65,8 +67,8 @@ class Array
65
67
  #
66
68
  def chars
67
69
  array_bytes = bytes
68
-
69
70
  array_bytes.map! { |b| b.chr }
71
+
70
72
  return array_bytes
71
73
  end
72
74
 
@@ -103,8 +105,8 @@ class Array
103
105
  #
104
106
  def hex_chars
105
107
  array_bytes = bytes
106
-
107
108
  array_bytes.map! { |b| '\x%x' % b }
109
+
108
110
  return array_bytes
109
111
  end
110
112
 
@@ -127,8 +129,8 @@ class Array
127
129
  #
128
130
  def hex_integers
129
131
  array_bytes = bytes
130
-
131
132
  array_bytes.map! { |b| '0x%x' % b }
133
+
132
134
  return array_bytes
133
135
  end
134
136
 
@@ -99,10 +99,8 @@ class String
99
99
  formatted = ''
100
100
 
101
101
  matches = lambda { |filter,c|
102
- if filter.respond_to?(:include?)
103
- filter.include?(c)
104
- elsif filter.kind_of?(Regexp)
105
- c =~ filter
102
+ if filter.respond_to?(:include?) then filter.include?(c)
103
+ elsif filter.kind_of?(Regexp) then c =~ filter
106
104
  end
107
105
  }
108
106
 
@@ -143,10 +141,8 @@ class String
143
141
  prob = (options[:probability] || 0.5)
144
142
 
145
143
  format_chars(options) do |c|
146
- if rand <= prob
147
- c.swapcase
148
- else
149
- c
144
+ if rand <= prob then c.swapcase
145
+ else c
150
146
  end
151
147
  end
152
148
  end
@@ -48,21 +48,16 @@ module Ronin
48
48
 
49
49
  rules.each do |pattern,substitution|
50
50
  pattern = case pattern
51
- when Regexp
52
- pattern
53
- when String
54
- Regexp.new(Regexp.escape(pattern))
55
- when Symbol
56
- Regexp.const_get(pattern.to_s.upcase)
51
+ when Regexp then pattern
52
+ when String then Regexp.new(Regexp.escape(pattern))
53
+ when Symbol then Regexp.const_get(pattern.to_s.upcase)
57
54
  else
58
55
  raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp")
59
56
  end
60
57
 
61
58
  substitution = case substitution
62
- when Enumerable
63
- substitution
64
- when Symbol
65
- Fuzzing[substitution]
59
+ when Enumerable then substitution
60
+ when Symbol then Fuzzing[substitution]
66
61
  else
67
62
  raise(TypeError,"substitutions must be Enumerable or a Symbol")
68
63
  end
@@ -97,12 +92,9 @@ module Ronin
97
92
  indices.each do |index,length|
98
93
  substitution.each do |substitute|
99
94
  substitute = case substitute
100
- when Proc
101
- substitute.call(string[index,length])
102
- when Integer
103
- substitute.chr
104
- else
105
- substitute.to_s
95
+ when Proc then substitute[string[index,length]]
96
+ when Integer then substitute.chr
97
+ else substitute.to_s
106
98
  end
107
99
 
108
100
  fuzzed = string.dup