ronin-support 0.3.0 → 0.4.0.rc1
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 +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
|
#
|