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.
- data/ChangeLog.md +13 -1
- data/README.md +5 -3
- data/lib/ronin/binary/hexdump/parser.rb +10 -18
- data/lib/ronin/binary/struct.rb +18 -32
- data/lib/ronin/binary/template.rb +29 -19
- data/lib/ronin/extensions/ip_addr.rb +5 -10
- data/lib/ronin/extensions/resolv.rb +2 -4
- data/lib/ronin/formatting/extensions/binary.rb +1 -0
- data/lib/ronin/formatting/extensions/binary/array.rb +5 -7
- data/lib/ronin/formatting/extensions/binary/float.rb +4 -4
- data/lib/ronin/formatting/extensions/binary/integer.rb +14 -11
- data/lib/ronin/formatting/extensions/binary/string.rb +14 -25
- data/lib/ronin/formatting/extensions/html/integer.rb +4 -8
- data/lib/ronin/formatting/extensions/html/string.rb +24 -32
- data/lib/ronin/formatting/extensions/sql/string.rb +9 -13
- data/lib/ronin/formatting/extensions/text/array.rb +8 -6
- data/lib/ronin/formatting/extensions/text/string.rb +4 -8
- data/lib/ronin/fuzzing/fuzzer.rb +8 -16
- data/lib/ronin/network/dns.rb +2 -4
- data/lib/ronin/network/ftp.rb +5 -1
- data/lib/ronin/network/ssl.rb +9 -10
- data/lib/ronin/network/tcp/tcp.rb +8 -0
- data/lib/ronin/network/udp/proxy.rb +2 -2
- data/lib/ronin/network/udp/udp.rb +8 -0
- data/lib/ronin/network/unix.rb +4 -5
- data/lib/ronin/path.rb +2 -2
- data/lib/ronin/support/version.rb +1 -1
- data/lib/ronin/ui/output/helpers.rb +2 -4
- data/lib/ronin/ui/shell.rb +3 -6
- data/spec/binary/template_spec.rb +14 -0
- data/spec/formatting/binary/array_spec.rb +8 -4
- data/spec/formatting/binary/float_spec.rb +8 -4
- data/spec/formatting/binary/integer_spec.rb +16 -4
- data/spec/formatting/binary/string_spec.rb +8 -4
- data/spec/network/ftp_spec.rb +16 -0
- data/spec/network/network_spec.rb +1 -1
- data/spec/network/ssl_spec.rb +50 -0
- metadata +359 -399
@@ -31,7 +31,8 @@ class Float
|
|
31
31
|
# The packed float.
|
32
32
|
#
|
33
33
|
# @raise [ArgumentError]
|
34
|
-
# The
|
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
|
-
|
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
|
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
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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[
|
140
|
-
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
|
195
|
-
|
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
|
-
|
234
|
-
|
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
|
-
|
267
|
-
|
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
|
-
|
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
|
-
|
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"
|
30
|
-
"\\t"
|
31
|
-
"\\n"
|
32
|
-
"\\f"
|
33
|
-
"\\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
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
129
|
-
|
130
|
-
|
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(/
|
156
|
-
c
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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
|
-
|
193
|
-
|
194
|
-
|
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
|
-
|
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 ((
|
81
|
+
if (start_with?('0x') && (length % 2 == 0))
|
84
82
|
raw = ''
|
85
83
|
|
86
|
-
self[2..-1].scan(
|
87
|
-
raw << hex_char.
|
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 (
|
92
|
-
self[1..-2].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
|
-
|
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
|
-
|
44
|
-
|
43
|
+
case element
|
44
|
+
when Integer then bytes << element
|
45
45
|
else
|
46
|
-
element.to_s.each_byte
|
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
|
103
|
-
|
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
|
-
|
148
|
-
else
|
149
|
-
c
|
144
|
+
if rand <= prob then c.swapcase
|
145
|
+
else c
|
150
146
|
end
|
151
147
|
end
|
152
148
|
end
|
data/lib/ronin/fuzzing/fuzzer.rb
CHANGED
@@ -48,21 +48,16 @@ module Ronin
|
|
48
48
|
|
49
49
|
rules.each do |pattern,substitution|
|
50
50
|
pattern = case pattern
|
51
|
-
when Regexp
|
52
|
-
|
53
|
-
when
|
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
|
-
|
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
|
-
|
102
|
-
|
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
|