ronin-support 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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