ronin-support 0.3.0 → 0.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +77 -7
- data/README.md +19 -3
- data/gemspec.yml +2 -2
- data/lib/ronin/extensions/regexp.rb +50 -2
- data/lib/ronin/extensions/string.rb +1 -0
- data/lib/ronin/formatting.rb +1 -0
- data/lib/ronin/formatting/extensions.rb +1 -0
- data/lib/ronin/formatting/extensions/binary/string.rb +56 -5
- data/lib/ronin/formatting/extensions/html/string.rb +6 -7
- data/lib/ronin/formatting/extensions/sql/string.rb +34 -0
- data/lib/ronin/formatting/extensions/text/string.rb +0 -180
- data/lib/ronin/fuzzing.rb +21 -0
- data/lib/ronin/fuzzing/extensions.rb +20 -0
- data/lib/ronin/fuzzing/extensions/string.rb +380 -0
- data/lib/ronin/fuzzing/fuzzing.rb +191 -0
- data/lib/ronin/network/esmtp.rb +94 -1
- data/lib/ronin/network/extensions/esmtp/net.rb +2 -82
- data/lib/ronin/network/extensions/http/net.rb +1 -736
- data/lib/ronin/network/extensions/imap/net.rb +1 -103
- data/lib/ronin/network/extensions/pop3/net.rb +1 -71
- data/lib/ronin/network/extensions/smtp/net.rb +2 -157
- data/lib/ronin/network/extensions/ssl/net.rb +1 -132
- data/lib/ronin/network/extensions/tcp/net.rb +2 -296
- data/lib/ronin/network/extensions/telnet/net.rb +1 -135
- data/lib/ronin/network/extensions/udp/net.rb +2 -214
- data/lib/ronin/network/http/http.rb +750 -5
- data/lib/ronin/network/imap.rb +105 -2
- data/lib/ronin/network/mixins.rb +1 -1
- data/lib/ronin/network/mixins/esmtp.rb +49 -52
- data/lib/ronin/network/mixins/http.rb +49 -53
- data/lib/ronin/network/mixins/imap.rb +47 -44
- data/lib/ronin/network/mixins/mixin.rb +58 -0
- data/lib/ronin/network/mixins/pop3.rb +44 -38
- data/lib/ronin/network/mixins/smtp.rb +49 -51
- data/lib/ronin/network/mixins/tcp.rb +56 -69
- data/lib/ronin/network/mixins/telnet.rb +57 -50
- data/lib/ronin/network/mixins/udp.rb +48 -52
- data/lib/ronin/network/network.rb +1 -0
- data/lib/ronin/network/pop3.rb +72 -2
- data/lib/ronin/network/smtp/email.rb +1 -0
- data/lib/ronin/network/smtp/smtp.rb +159 -3
- data/lib/ronin/network/ssl.rb +131 -2
- data/lib/ronin/network/tcp.rb +306 -1
- data/lib/ronin/network/telnet.rb +136 -2
- data/lib/ronin/network/udp.rb +229 -1
- data/lib/ronin/support.rb +2 -3
- data/lib/ronin/support/support.rb +38 -0
- data/lib/ronin/support/version.rb +1 -1
- data/lib/ronin/templates/erb.rb +2 -1
- data/lib/ronin/ui/output/helpers.rb +35 -1
- data/lib/ronin/ui/shell.rb +12 -2
- data/lib/ronin/wordlist.rb +157 -0
- data/spec/extensions/regexp_spec.rb +38 -0
- data/spec/formatting/html/string_spec.rb +1 -1
- data/spec/formatting/sql/string_spec.rb +23 -3
- data/spec/formatting/text/string_spec.rb +0 -110
- data/spec/fuzzing/string_spec.rb +158 -0
- data/spec/wordlist_spec.rb +65 -0
- metadata +35 -27
data/ChangeLog.md
CHANGED
@@ -1,3 +1,73 @@
|
|
1
|
+
### 0.4.0 / 2012-01-01
|
2
|
+
|
3
|
+
* Require uri-query_params ~> 0.6.
|
4
|
+
* Require parameters ~> 0.4.
|
5
|
+
* Added {Regexp::DELIM}.
|
6
|
+
* Added {Regexp::IDENTIFIER}.
|
7
|
+
* Added {Regexp::OCTET}.
|
8
|
+
* Added {Regexp::FILE_EXT}.
|
9
|
+
* Added {Regexp::FILE_NAME}.
|
10
|
+
* Added {Regexp::FILE}.
|
11
|
+
* Added {Regexp::DIRECTORY}.
|
12
|
+
* Added {Regexp::LOCAL_UNIX_PATH}.
|
13
|
+
* Added {Regexp::ABSOLUTE_UNIX_PATH}.
|
14
|
+
* Added {Regexp::UNIX_PATH}.
|
15
|
+
* Added {Regexp::LOCAL_WINDOWS_PATH}.
|
16
|
+
* Added {Regexp::ABSOLUTE_WINDOWS_PATH}.
|
17
|
+
* Added {Regexp::WINDOWS_PATH}.
|
18
|
+
* Added {Regexp::LOCAL_PATH}.
|
19
|
+
* Added {Regexp::ABSOLUTE_PATH}.
|
20
|
+
* Added {Regexp::PATH}.
|
21
|
+
* Added {String#repeating}.
|
22
|
+
* Added {String#sql_inject}.
|
23
|
+
* Added {String#mutate}.
|
24
|
+
* Added {Ronin::Fuzzing}.
|
25
|
+
* Added {Ronin::Fuzzing.[]}.
|
26
|
+
* Added {Ronin::Fuzzing.bad_strings}.
|
27
|
+
* Added {Ronin::Fuzzing.format_strings}.
|
28
|
+
* Added {Ronin::Fuzzing.bad_paths}.
|
29
|
+
* Added {Ronin::Fuzzing.bit_fields}.
|
30
|
+
* Added {Ronin::Fuzzing.signed_bit_fields}.
|
31
|
+
* Added {Ronin::Fuzzing.uint8}.
|
32
|
+
* Added {Ronin::Fuzzing.uint16}.
|
33
|
+
* Added {Ronin::Fuzzing.uint32}.
|
34
|
+
* Added {Ronin::Fuzzing.uint64}.
|
35
|
+
* Added {Ronin::Fuzzing.int8}.
|
36
|
+
* Added {Ronin::Fuzzing.int16}.
|
37
|
+
* Added {Ronin::Fuzzing.int32}.
|
38
|
+
* Added {Ronin::Fuzzing.int64}.
|
39
|
+
* Added {Ronin::Fuzzing.sint8}.
|
40
|
+
* Added {Ronin::Fuzzing.sint16}.
|
41
|
+
* Added {Ronin::Fuzzing.sint32}.
|
42
|
+
* Added {Ronin::Fuzzing.sint64}.
|
43
|
+
* Added {Ronin::Wordlist}.
|
44
|
+
* Added {Ronin::Network::Mixins::Mixin}.
|
45
|
+
* Added {Ronin::UI::Output::Helpers#print_exception}.
|
46
|
+
* Made {Regexp::HOST_NAME} case-insensitive.
|
47
|
+
* Refactored {Regexp::IPv4} to not match invalid IPv4 addresses.
|
48
|
+
* Require `ronin/formatting/html` in `ronin/formatting`.
|
49
|
+
* Allow {String#base64_encode} and {String#base64_decode} to accept a formatting
|
50
|
+
argument.
|
51
|
+
* `:normal`
|
52
|
+
* `:strict`
|
53
|
+
* `:url` / `:urlsafe`
|
54
|
+
* Fixed a bug in {String#js_unescape}, where `%uXX` chars were not being
|
55
|
+
unescaped (thanks isis!).
|
56
|
+
* Have {String#fuzz} only accept `Regexp` and `String` objects.
|
57
|
+
* Moved {String#fuzz} and {String.generate} into `ronin/fuzzing`.
|
58
|
+
* Moved `Net.*` methods into the {Ronin::Network} modules.
|
59
|
+
* Fixed bugs in {Ronin::Network::UDP#udp_connect} and
|
60
|
+
{Ronin::Network::UDP#udp_server}.
|
61
|
+
* Fixed a bug in {Ronin::Network::Mixins::HTTP#http_session}, where
|
62
|
+
normalized options were not being yielded.
|
63
|
+
* Allow {Ronin::Templates::Erb} to use `<%- -%>` syntax.
|
64
|
+
* Alias `<<` to `write` in {Ronin::UI::Output::Helpers}.
|
65
|
+
* Fixed bugs in {Ronin::UI::Shell}.
|
66
|
+
* Warning messages are printed by {Ronin::UI::Output::Helpers}, unless output
|
67
|
+
is silenced.
|
68
|
+
* {Ronin::UI::Output::Helpers} and {Ronin::Network} modules are included into
|
69
|
+
{Ronin::Support}.
|
70
|
+
|
1
71
|
### 0.3.0 / 2011-10-16
|
2
72
|
|
3
73
|
* Require combinatorics ~> 0.4.
|
@@ -52,13 +122,13 @@
|
|
52
122
|
* Added {String#js_escape}.
|
53
123
|
* Added {String#js_unescape}.
|
54
124
|
* Added {String#format_js}.
|
55
|
-
* Added
|
56
|
-
* Added
|
57
|
-
* Added
|
58
|
-
* Added
|
125
|
+
* Added `Net.smtp_send_message`.
|
126
|
+
* Added `Net.http_status`.
|
127
|
+
* Added `Net.http_get_headers`.
|
128
|
+
* Added `Net.http_post_headers`.
|
59
129
|
* Added YARD `@api` tags to define the public, semi-public and private APIs.
|
60
130
|
* Renamed `Kernel#attempt` to {Kernel#try}.
|
61
|
-
* Allow `:method` to be used with
|
131
|
+
* Allow `:method` to be used with `Net.http_ok?`.
|
62
132
|
* Fixed a bug in {Ronin::Network::HTTP.expand_url} where `:host` and `:port`
|
63
133
|
options were being overridden.
|
64
134
|
* Improved the performance of {Integer#bytes}.
|
@@ -68,8 +138,8 @@
|
|
68
138
|
for unicode characters.
|
69
139
|
* Deprecated {String#common_postfix}, in favor of {String#common_suffix}.
|
70
140
|
{String#common_postfix} will be removed in ronin-support 1.0.0.
|
71
|
-
*
|
72
|
-
*
|
141
|
+
* `Net.http_get_body` no longer accepts a block.
|
142
|
+
* `Net.http_post_body` no longer accepts a block.
|
73
143
|
|
74
144
|
### 0.1.0 / 2011-03-20
|
75
145
|
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ or payloads over many common Source-Code-Management (SCM) systems.
|
|
26
26
|
* HTML
|
27
27
|
* JavaScript
|
28
28
|
* SQL
|
29
|
-
*
|
29
|
+
* Fuzzing
|
30
30
|
* Networking:
|
31
31
|
* TCP
|
32
32
|
* UDP
|
@@ -40,6 +40,13 @@ or payloads over many common Source-Code-Management (SCM) systems.
|
|
40
40
|
* CIDR / globbed ranges.
|
41
41
|
* (Un-)Hexdumping data.
|
42
42
|
* Handling exceptions.
|
43
|
+
* Provides Modules/Classes for:
|
44
|
+
* Paths
|
45
|
+
* Wordlists
|
46
|
+
* Erb Templates
|
47
|
+
* UI:
|
48
|
+
* Terminal Output
|
49
|
+
* Custom Shells
|
43
50
|
|
44
51
|
## Examples
|
45
52
|
|
@@ -56,16 +63,25 @@ please see [Everyday Ronin](http://ronin-ruby.github.com/guides/everyday_ronin.h
|
|
56
63
|
* [combinatorics](http://github.com/postmodern/combinatorics#readme)
|
57
64
|
~> 0.4
|
58
65
|
* [uri-query_params](http://github.com/postmodern/uri-query_params#readme)
|
59
|
-
~> 0.
|
66
|
+
~> 0.6
|
60
67
|
* [data_paths](http://github.com/postmodern/data_paths#readme)
|
61
68
|
~> 0.3
|
62
69
|
* [parameters](http://github.com/postmodern/parameters#readme)
|
63
|
-
~> 0.
|
70
|
+
~> 0.4
|
64
71
|
|
65
72
|
## Install
|
66
73
|
|
74
|
+
### Stable
|
75
|
+
|
67
76
|
$ gem install ronin-support
|
68
77
|
|
78
|
+
### Edge
|
79
|
+
|
80
|
+
$ git clone git://github.com/ronin-ruby/ronin-support.git
|
81
|
+
$ cd ronin-support/
|
82
|
+
$ bundle install
|
83
|
+
$ rake console
|
84
|
+
|
69
85
|
## License
|
70
86
|
|
71
87
|
Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
|
data/gemspec.yml
CHANGED
@@ -16,9 +16,9 @@ dependencies:
|
|
16
16
|
chars: ~> 0.2
|
17
17
|
hexdump: ~> 0.1
|
18
18
|
combinatorics: ~> 0.4
|
19
|
-
uri-query_params: ~> 0.
|
19
|
+
uri-query_params: ~> 0.6
|
20
20
|
data_paths: ~> 0.3
|
21
|
-
parameters: ~> 0.
|
21
|
+
parameters: ~> 0.4
|
22
22
|
|
23
23
|
development_dependencies:
|
24
24
|
bundler: ~> 1.0.10
|
@@ -21,11 +21,14 @@ require 'ronin/extensions/resolv'
|
|
21
21
|
|
22
22
|
class Regexp
|
23
23
|
|
24
|
+
# Regular expression for finding a decimal octet (0 - 255)
|
25
|
+
OCTET = /25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9]/
|
26
|
+
|
24
27
|
# Regular expression for finding MAC addresses in text
|
25
28
|
MAC = /[0-9a-fA-F]{2}(?::[0-9a-fA-F]{2}){5}/
|
26
29
|
|
27
30
|
# A regular expression for matching IPv4 Addresses.
|
28
|
-
IPv4 =
|
31
|
+
IPv4 = /#{OCTET}(?:\.#{OCTET}){3}/
|
29
32
|
|
30
33
|
# A regular expression for matching IPv6 Addresses.
|
31
34
|
IPv6 = /:(:[0-9a-f]{1,4}){1,7}|([0-9a-f]{1,4}::?){1,7}[0-9a-f]{1,4}(:#{IPv4})?/
|
@@ -34,7 +37,7 @@ class Regexp
|
|
34
37
|
IP = /#{IPv4}|#{IPv6}/
|
35
38
|
|
36
39
|
# Regular expression used to find host-names in text
|
37
|
-
HOST_NAME = /(?:[a-zA-Z0-9]+(?:[_-][a-zA-Z0-9]+)*\.)+(?:#{union(Resolv::TLDS)})/
|
40
|
+
HOST_NAME = /(?:[a-zA-Z0-9]+(?:[_-][a-zA-Z0-9]+)*\.)+(?:#{union(Resolv::TLDS)})/i
|
38
41
|
|
39
42
|
# Regular expression to match a word in the username of an email address
|
40
43
|
USER_NAME = /[A-Za-z](?:[A-Za-z0-9]+[\._-])*[A-Za-z0-9]+/
|
@@ -42,4 +45,49 @@ class Regexp
|
|
42
45
|
# Regular expression to find email addresses in text
|
43
46
|
EMAIL_ADDR = /#{USER_NAME}(?:\.#{USER_NAME})*\@#{HOST_NAME}/
|
44
47
|
|
48
|
+
# Regular expression to find deliminators in text
|
49
|
+
DELIM = /[;&\n\r]/
|
50
|
+
|
51
|
+
# Regular expression to find identifier in text
|
52
|
+
IDENTIFIER = /[_a-zA-Z][a-zA-Z0-9_-]*/
|
53
|
+
|
54
|
+
# Regular expression to find File extensions in text
|
55
|
+
FILE_EXT = /(?:\.[A-Za-z0-9_-]+)+/
|
56
|
+
|
57
|
+
# Regular expression to find File names in text
|
58
|
+
FILE_NAME = /(?:[^\/\\\. ]|\\[\/\\ ])+/
|
59
|
+
|
60
|
+
# Regular expression to find Files in text
|
61
|
+
FILE = /#{FILE_NAME}(?:#{FILE_EXT})?/
|
62
|
+
|
63
|
+
# Regular expression to find Directory names in text
|
64
|
+
DIRECTORY = /(?:\.\.|\.|#{FILE})/
|
65
|
+
|
66
|
+
# Regular expression to find local UNIX Paths in text
|
67
|
+
LOCAL_UNIX_PATH = /(?:#{DIRECTORY}\/)+#{DIRECTORY}\/?/
|
68
|
+
|
69
|
+
# Regular expression to find absolute UNIX Paths in text
|
70
|
+
ABSOLUTE_UNIX_PATH = /(?:\/#{FILE})+\/?/
|
71
|
+
|
72
|
+
# Regular expression to find UNIX Paths in text
|
73
|
+
UNIX_PATH = /#{ABSOLUTE_UNIX_PATH}|#{LOCAL_UNIX_PATH}/
|
74
|
+
|
75
|
+
# Regular expression to find local Windows Paths in text
|
76
|
+
LOCAL_WINDOWS_PATH = /(?:#{DIRECTORY}\\)+#{DIRECTORY}\\?/
|
77
|
+
|
78
|
+
# Regular expression to find absolute Windows Paths in text
|
79
|
+
ABSOLUTE_WINDOWS_PATH = /[A-Za-z]:(?:\\#{DIRECTORY})+\\?/
|
80
|
+
|
81
|
+
# Regular expression to find Windows Paths in text
|
82
|
+
WINDOWS_PATH = /#{ABSOLUTE_WINDOWS_PATH}|#{LOCAL_WINDOWS_PATH}/
|
83
|
+
|
84
|
+
# Regular expression to find local Paths in text
|
85
|
+
LOCAL_PATH = /#{LOCAL_UNIX_PATH}|#{LOCAL_WINDOWS_PATH}/
|
86
|
+
|
87
|
+
# Regular expression to find absolute Paths in text
|
88
|
+
ABSOLUTE_PATH = /#{ABSOLUTE_UNIX_PATH}|#{ABSOLUTE_WINDOWS_PATH}/
|
89
|
+
|
90
|
+
# Regular expression to find Paths in text
|
91
|
+
PATH = /#{UNIX_PATH}|#{WINDOWS_PATH}/
|
92
|
+
|
45
93
|
end
|
data/lib/ronin/formatting.rb
CHANGED
@@ -232,6 +232,13 @@ class String
|
|
232
232
|
#
|
233
233
|
# Base64 encodes a string.
|
234
234
|
#
|
235
|
+
# @param [Symbol, nil] mode
|
236
|
+
# The base64 mode to use. May be either:
|
237
|
+
#
|
238
|
+
# * `:normal`
|
239
|
+
# * `:strict`
|
240
|
+
# * `:url` / `:urlsafe`
|
241
|
+
#
|
235
242
|
# @return [String]
|
236
243
|
# The base64 encoded form of the string.
|
237
244
|
#
|
@@ -241,24 +248,68 @@ class String
|
|
241
248
|
#
|
242
249
|
# @api public
|
243
250
|
#
|
244
|
-
def base64_encode
|
245
|
-
|
251
|
+
def base64_encode(mode=nil)
|
252
|
+
case mode
|
253
|
+
when :strict
|
254
|
+
if RUBY_VERSION < '1.9'
|
255
|
+
# backported from Ruby 1.9.2
|
256
|
+
[self].pack("m")
|
257
|
+
else
|
258
|
+
Base64.strict_encode64(self)
|
259
|
+
end
|
260
|
+
when :url, :urlsafe
|
261
|
+
if RUBY_VERSION < '1.9'
|
262
|
+
# backported from Ruby 1.9.2
|
263
|
+
[self].pack("m").tr("+/", "-_")
|
264
|
+
else
|
265
|
+
Base64.urlsafe_encode64(self)
|
266
|
+
end
|
267
|
+
else
|
268
|
+
Base64.encode64(self)
|
269
|
+
end
|
246
270
|
end
|
247
271
|
|
248
272
|
#
|
249
273
|
# Base64 decodes a string.
|
250
274
|
#
|
275
|
+
# @param [Symbol, nil] mode
|
276
|
+
# The base64 mode to use. May be either:
|
277
|
+
#
|
278
|
+
# * `nil`
|
279
|
+
# * `:strict`
|
280
|
+
# * `:url` / `:urlsafe`
|
281
|
+
#
|
251
282
|
# @return [String]
|
252
283
|
# The base64 decoded form of the string.
|
253
284
|
#
|
285
|
+
# @note
|
286
|
+
# `mode` argument is only available on Ruby >= 1.9.
|
287
|
+
#
|
254
288
|
# @example
|
255
|
-
# "aGVsbG8=\n"
|
289
|
+
# "aGVsbG8=\n".base64_decode
|
256
290
|
# # => "hello"
|
257
291
|
#
|
258
292
|
# @api public
|
259
293
|
#
|
260
|
-
def base64_decode
|
261
|
-
|
294
|
+
def base64_decode(mode=nil)
|
295
|
+
case mode
|
296
|
+
when :strict
|
297
|
+
if RUBY_VERSION < '1.9'
|
298
|
+
# backported from Ruby 1.9.2
|
299
|
+
unpack("m0").first
|
300
|
+
else
|
301
|
+
Base64.strict_decode64(self)
|
302
|
+
end
|
303
|
+
when :url, :urlsafe
|
304
|
+
if RUBY_VERSION < '1.9'
|
305
|
+
# backported from Ruby 1.9.2
|
306
|
+
tr("-_", "+/").unpack("m0").first
|
307
|
+
else
|
308
|
+
Base64.urlsafe_decode64(self)
|
309
|
+
end
|
310
|
+
else
|
311
|
+
Base64.decode64(self)
|
312
|
+
end
|
262
313
|
end
|
263
314
|
|
264
315
|
#
|
@@ -152,16 +152,15 @@ class String
|
|
152
152
|
def js_unescape
|
153
153
|
unescaped = ''
|
154
154
|
|
155
|
-
scan(/([\\%]u[0-9a-fA-F]{4}|[\\%][0-9a-fA-F]{2}|\\[btnfr"\\]|.)/).each do |match|
|
155
|
+
scan(/([\\%]u[0-9a-fA-F]{1,4}|[\\%][0-9a-fA-F]{1,2}|\\[btnfr"\\]|.)/).each do |match|
|
156
156
|
c = match[0]
|
157
157
|
|
158
|
-
unescaped <<
|
159
|
-
when 6
|
160
|
-
c[2,4].to_i(16)
|
161
|
-
when 3
|
162
|
-
c[1,2].to_i(16)
|
163
|
-
when 2
|
158
|
+
unescaped << if JS_BACKSLASHED_CHARS.has_key?(c)
|
164
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)
|
165
164
|
else
|
166
165
|
c
|
167
166
|
end
|
@@ -95,4 +95,38 @@ class String
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
#
|
99
|
+
# Prepares the String for injection into a SQL expression.
|
100
|
+
#
|
101
|
+
# @return [String]
|
102
|
+
# The SQL injection ready String.
|
103
|
+
#
|
104
|
+
# @example
|
105
|
+
# "'1' OR '1'='1'".sql_inject
|
106
|
+
# # => "1' OR '1'='1"
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# "'1' OR 1=1".sql_inject
|
110
|
+
# # => "1' OR 1=1 OR '"
|
111
|
+
#
|
112
|
+
# @example
|
113
|
+
# "'1' OR 1=1".sql_inject(:terminate => true)
|
114
|
+
# # => "1' OR 1=1 --"
|
115
|
+
#
|
116
|
+
# @api public
|
117
|
+
#
|
118
|
+
# @since 0.4.0
|
119
|
+
#
|
120
|
+
def sql_inject
|
121
|
+
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]}--"
|
126
|
+
end
|
127
|
+
else
|
128
|
+
self
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
98
132
|
end
|
@@ -17,190 +17,10 @@
|
|
17
17
|
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
-
require 'combinatorics/list_comprehension'
|
21
|
-
require 'combinatorics/generator'
|
22
|
-
require 'chars'
|
23
20
|
require 'set'
|
24
21
|
|
25
22
|
class String
|
26
23
|
|
27
|
-
#
|
28
|
-
# Generate permutations of Strings from a format template.
|
29
|
-
#
|
30
|
-
# @param [Array(<String, Symbol, Enumerable>, <Integer, Enumerable>)] template
|
31
|
-
# The template which defines the string or character sets which will
|
32
|
-
# make up parts of the String.
|
33
|
-
#
|
34
|
-
# @yield [string]
|
35
|
-
# The given block will be passed each unique String.
|
36
|
-
#
|
37
|
-
# @yieldparam [String] string
|
38
|
-
# A newly generated String.
|
39
|
-
#
|
40
|
-
# @return [Enumerator]
|
41
|
-
# If no block is given, an Enumerator will be returned.
|
42
|
-
#
|
43
|
-
# @raise [ArgumentError]
|
44
|
-
# A given character set name was unknown.
|
45
|
-
#
|
46
|
-
# @raise [TypeError]
|
47
|
-
# A given string set was not a String, Symbol or Enumerable.
|
48
|
-
# A given string set length was not an Integer or Enumerable.
|
49
|
-
#
|
50
|
-
# @example Generate Strings with ranges of repeating sub-strings.
|
51
|
-
#
|
52
|
-
# @example Generate Strings with three alpha chars and one numeric chars.
|
53
|
-
# String.generate([:alpha, 3], :numeric) do |password|
|
54
|
-
# puts password
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# @example Generate Strings with two to four alpha chars.
|
58
|
-
# String.generate([:alpha, 2..4]) do |password|
|
59
|
-
# puts password
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# @example Generate Strings using alpha and punctuation chars.
|
63
|
-
# String.generate([Chars.alpha + Chars.punctuation, 4]) do |password|
|
64
|
-
# puts password
|
65
|
-
# end
|
66
|
-
#
|
67
|
-
# @example Generate Strings from a custom char set.
|
68
|
-
# String.generate([['a', 'b', 'c'], 3], [['1', '2', '3'], 3]) do |password|
|
69
|
-
# puts password
|
70
|
-
# end
|
71
|
-
#
|
72
|
-
# @example Generate Strings containing known Strings.
|
73
|
-
# String.generate("rock", [:numeric, 4]) do |password|
|
74
|
-
# puts password
|
75
|
-
# end
|
76
|
-
#
|
77
|
-
# @example Generate Strings with ranges of repeating sub-strings.
|
78
|
-
# String.generate(['/AA', (1..100).step(5)]) do |path|
|
79
|
-
# puts path
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# @since 0.3.0
|
83
|
-
#
|
84
|
-
# @api public
|
85
|
-
#
|
86
|
-
def self.generate(*template)
|
87
|
-
return enum_for(:generate,*template) unless block_given?
|
88
|
-
|
89
|
-
sets = []
|
90
|
-
|
91
|
-
template.each do |pattern|
|
92
|
-
set, length = pattern
|
93
|
-
set = case set
|
94
|
-
when String
|
95
|
-
[set].each
|
96
|
-
when Symbol
|
97
|
-
name = set.to_s.upcase
|
98
|
-
|
99
|
-
unless Chars.const_defined?(name)
|
100
|
-
raise(ArgumentError,"unknown charset #{set.inspect}")
|
101
|
-
end
|
102
|
-
|
103
|
-
Chars.const_get(name).each_char
|
104
|
-
when Enumerable
|
105
|
-
Chars::CharSet.new(set).each_char
|
106
|
-
else
|
107
|
-
raise(TypeError,"set must be a String, Symbol or Enumerable")
|
108
|
-
end
|
109
|
-
|
110
|
-
case length
|
111
|
-
when Integer
|
112
|
-
length.times { sets << set.dup }
|
113
|
-
when Enumerable
|
114
|
-
sets << Combinatorics::Generator.new do |g|
|
115
|
-
length.each do |sublength|
|
116
|
-
superset = Array.new(sublength) { set.dup }
|
117
|
-
|
118
|
-
superset.comprehension { |strings| g.yield strings.join }
|
119
|
-
end
|
120
|
-
end
|
121
|
-
when nil
|
122
|
-
sets << set
|
123
|
-
else
|
124
|
-
raise(TypeError,"length must be an Integer or Enumerable")
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
sets.comprehension { |strings| yield strings.join }
|
129
|
-
return nil
|
130
|
-
end
|
131
|
-
|
132
|
-
#
|
133
|
-
# Incrementally fuzzes the String.
|
134
|
-
#
|
135
|
-
# @param [Hash{Regexp,String,Integer,Enumerable => #each}] mutations
|
136
|
-
# Patterns and their substitutions.
|
137
|
-
#
|
138
|
-
# @yield [fuzz]
|
139
|
-
# The given block will be passed every fuzzed String.
|
140
|
-
#
|
141
|
-
# @yieldparam [String] fuzz
|
142
|
-
# A fuzzed String.
|
143
|
-
#
|
144
|
-
# @return [Enumerator]
|
145
|
-
# If no block is given, an Enumerator will be returned.
|
146
|
-
#
|
147
|
-
# @example Replace every `e`, `i`, `o`, `u` with `(`, 100 `A`s and a `\0`:
|
148
|
-
# "the quick brown fox".fuzz(/[eiou]/ => ['(', ('A' * 100), "\0"]) do |str|
|
149
|
-
# p str
|
150
|
-
# end
|
151
|
-
#
|
152
|
-
# @example {String.generate} with {String.fuzz}:
|
153
|
-
# "GET /".fuzz('/' => String.generate(['A', 1..100])) do |str|
|
154
|
-
# p str
|
155
|
-
# end
|
156
|
-
#
|
157
|
-
# @since 0.3.0
|
158
|
-
#
|
159
|
-
# @api public
|
160
|
-
#
|
161
|
-
def fuzz(mutations={})
|
162
|
-
return enum_for(:fuzz,mutations) unless block_given?
|
163
|
-
|
164
|
-
mutations.each do |pattern,substitution|
|
165
|
-
pattern = case pattern
|
166
|
-
when Regexp
|
167
|
-
pattern
|
168
|
-
when String
|
169
|
-
Regexp.new(Regexp.escape(pattern))
|
170
|
-
when Integer
|
171
|
-
Regexp.new(pattern.chr)
|
172
|
-
when Enumerable
|
173
|
-
Regexp.union(pattern.map { |s| Regexp.escape(s.to_s) })
|
174
|
-
else
|
175
|
-
raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp")
|
176
|
-
end
|
177
|
-
|
178
|
-
scanner = StringScanner.new(self)
|
179
|
-
indices = []
|
180
|
-
|
181
|
-
while scanner.scan_until(pattern)
|
182
|
-
indices << [scanner.pos - scanner.matched_size, scanner.matched_size]
|
183
|
-
end
|
184
|
-
|
185
|
-
indices.each do |index,length|
|
186
|
-
substitution.each do |substitute|
|
187
|
-
substitute = case substitute
|
188
|
-
when Proc
|
189
|
-
substitute.call(self[index,length])
|
190
|
-
when Integer
|
191
|
-
substitute.chr
|
192
|
-
else
|
193
|
-
substitute.to_s
|
194
|
-
end
|
195
|
-
|
196
|
-
fuzzed = dup
|
197
|
-
fuzzed[index,length] = substitute
|
198
|
-
yield fuzzed
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
24
|
#
|
205
25
|
# Creates a new String by formatting each byte.
|
206
26
|
#
|