ronin-support 0.4.1 → 0.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/ChangeLog.md +75 -32
  2. data/Gemfile +17 -18
  3. data/README.md +9 -10
  4. data/Rakefile +10 -2
  5. data/gemspec.yml +1 -1
  6. data/lib/ronin/binary.rb +21 -0
  7. data/lib/ronin/binary/hexdump.rb +20 -0
  8. data/lib/ronin/binary/hexdump/parser.rb +411 -0
  9. data/lib/ronin/binary/struct.rb +579 -0
  10. data/lib/ronin/binary/template.rb +437 -0
  11. data/lib/ronin/extensions/ip_addr.rb +17 -13
  12. data/lib/ronin/extensions/regexp.rb +45 -0
  13. data/lib/ronin/extensions/string.rb +3 -3
  14. data/lib/ronin/formatting/extensions/binary.rb +1 -0
  15. data/lib/ronin/formatting/extensions/binary/array.rb +63 -0
  16. data/lib/ronin/formatting/extensions/binary/base64.rb +106 -0
  17. data/lib/ronin/formatting/extensions/binary/file.rb +39 -6
  18. data/lib/ronin/formatting/extensions/binary/float.rb +65 -0
  19. data/lib/ronin/formatting/extensions/binary/integer.rb +56 -43
  20. data/lib/ronin/formatting/extensions/binary/string.rb +75 -187
  21. data/lib/ronin/formatting/extensions/text/string.rb +61 -0
  22. data/lib/ronin/fuzzing/extensions/string.rb +21 -8
  23. data/lib/ronin/fuzzing/fuzzing.rb +19 -17
  24. data/lib/ronin/network.rb +2 -1
  25. data/lib/ronin/network/dns.rb +57 -15
  26. data/lib/ronin/network/extensions.rb +0 -1
  27. data/lib/ronin/network/ftp.rb +145 -0
  28. data/lib/ronin/network/http/http.rb +13 -14
  29. data/lib/ronin/network/imap.rb +11 -10
  30. data/lib/ronin/network/mixins.rb +1 -0
  31. data/lib/ronin/network/mixins/ftp.rb +155 -0
  32. data/lib/ronin/network/mixins/ssl.rb +1 -1
  33. data/lib/ronin/network/mixins/tcp.rb +39 -6
  34. data/lib/ronin/network/mixins/udp.rb +121 -1
  35. data/lib/ronin/network/mixins/unix.rb +279 -0
  36. data/lib/ronin/network/pop3.rb +5 -5
  37. data/lib/ronin/network/proxy.rb +578 -0
  38. data/lib/ronin/network/smtp/email.rb +1 -1
  39. data/lib/ronin/network/smtp/smtp.rb +7 -8
  40. data/lib/ronin/network/ssl.rb +1 -6
  41. data/lib/ronin/network/tcp.rb +2 -305
  42. data/lib/ronin/network/tcp/proxy.rb +377 -0
  43. data/lib/ronin/network/tcp/tcp.rb +435 -0
  44. data/lib/ronin/network/telnet.rb +27 -23
  45. data/lib/ronin/network/udp.rb +2 -266
  46. data/lib/ronin/network/udp/proxy.rb +169 -0
  47. data/lib/ronin/network/udp/udp.rb +442 -0
  48. data/lib/ronin/network/unix.rb +287 -0
  49. data/lib/ronin/path.rb +2 -2
  50. data/lib/ronin/spec/ui/output.rb +1 -7
  51. data/lib/ronin/support.rb +1 -0
  52. data/lib/ronin/support/inflector.rb +3 -7
  53. data/lib/ronin/support/support.rb +2 -1
  54. data/lib/ronin/support/version.rb +1 -1
  55. data/lib/ronin/ui/output/helpers.rb +13 -15
  56. data/lib/ronin/ui/output/output.rb +2 -2
  57. data/lib/ronin/ui/output/terminal/color.rb +10 -4
  58. data/lib/ronin/wordlist.rb +92 -17
  59. data/ronin-support.gemspec +38 -109
  60. data/spec/binary/hexdump/helpers/hexdumps.rb +13 -0
  61. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/ascii.bin +0 -0
  62. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_decimal_shorts.txt +0 -0
  63. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_bytes.txt +0 -0
  64. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_shorts.txt +0 -0
  65. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_bytes.txt +0 -0
  66. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_shorts.txt +0 -0
  67. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_repeated.txt +0 -0
  68. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_bytes.txt +0 -0
  69. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_ints.txt +0 -0
  70. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_quads.txt +0 -0
  71. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_shorts.txt +0 -0
  72. data/spec/binary/hexdump/helpers/hexdumps/od_doubles.txt +17 -0
  73. data/spec/binary/hexdump/helpers/hexdumps/od_floats.txt +17 -0
  74. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_bytes.txt +0 -0
  75. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_ints.txt +0 -0
  76. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_quads.txt +0 -0
  77. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_shorts.txt +0 -0
  78. data/spec/binary/hexdump/helpers/hexdumps/od_named_chars.txt +17 -0
  79. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_bytes.txt +0 -0
  80. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_ints.txt +0 -0
  81. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_quads.txt +0 -0
  82. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_shorts.txt +0 -0
  83. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_repeated.txt +0 -0
  84. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/repeated.bin +0 -0
  85. data/spec/binary/hexdump/parser_spec.rb +302 -0
  86. data/spec/binary/struct_spec.rb +496 -0
  87. data/spec/binary/template_spec.rb +400 -0
  88. data/spec/extensions/ip_addr_spec.rb +58 -32
  89. data/spec/extensions/regexp_spec.rb +60 -0
  90. data/spec/extensions/string_spec.rb +1 -1
  91. data/spec/formatting/binary/array_spec.rb +22 -0
  92. data/spec/formatting/binary/base64_spec.rb +50 -0
  93. data/spec/formatting/binary/float_spec.rb +30 -0
  94. data/spec/formatting/binary/integer_spec.rb +54 -40
  95. data/spec/formatting/binary/string_spec.rb +69 -182
  96. data/spec/formatting/text/string_spec.rb +30 -0
  97. data/spec/network/dns_spec.rb +64 -0
  98. data/spec/network/ftp_spec.rb +65 -0
  99. data/spec/network/proxy_spec.rb +121 -0
  100. data/spec/network/shared/unix_server.rb +31 -0
  101. data/spec/network/tcp/proxy_spec.rb +116 -0
  102. data/spec/network/{tcp_spec.rb → tcp/tcp_spec.rb} +24 -1
  103. data/spec/network/telnet_spec.rb +67 -0
  104. data/spec/network/{udp_spec.rb → udp/udp_spec.rb} +24 -1
  105. data/spec/network/unix_spec.rb +183 -0
  106. data/spec/wordlist_spec.rb +74 -13
  107. metadata +129 -85
  108. data/spec/formatting/binary/helpers/hexdumps.rb +0 -16
@@ -26,13 +26,13 @@ module Ronin
26
26
  # Controls {Output} from Ronin.
27
27
  #
28
28
  module Output
29
- @mode = if ($VERBOSE || $DEBUG || ENV['VERBOSE'])
29
+ @mode = if ($VERBOSE || $DEBUG)
30
30
  :verbose
31
31
  else
32
32
  :quiet
33
33
  end
34
34
 
35
- @handler = if $stdout.tty?
35
+ @handler = if STDOUT.tty?
36
36
  Terminal::Color
37
37
  else
38
38
  Terminal::Raw
@@ -38,6 +38,12 @@ module Ronin
38
38
  # ANSI Red code
39
39
  RED = "\e[31m"
40
40
 
41
+ # ANSI Bright code
42
+ BRIGHT = "\e[1m"
43
+
44
+ # ANSI Bright-Off code
45
+ BRIGHT_OFF = "\e[21m"
46
+
41
47
  # ANSI Clear code
42
48
  CLEAR = "\e[0m"
43
49
 
@@ -66,7 +72,7 @@ module Ronin
66
72
  # @api private
67
73
  #
68
74
  def self.print_info(message)
69
- $stdout.puts "#{GREEN}[-] #{message}#{CLEAR}"
75
+ $stdout.puts "#{GREEN}#{BRIGHT}[-]#{BRIGHT_OFF} #{message}#{CLEAR}"
70
76
  end
71
77
 
72
78
  #
@@ -80,7 +86,7 @@ module Ronin
80
86
  # @api private
81
87
  #
82
88
  def self.print_debug(message)
83
- $stdout.puts "#{CYAN}[=] #{message}#{CLEAR}"
89
+ $stdout.puts "#{CYAN}#{BRIGHT}[=]#{BRIGHT_OFF} #{message}#{CLEAR}"
84
90
  end
85
91
 
86
92
  #
@@ -94,7 +100,7 @@ module Ronin
94
100
  # @api private
95
101
  #
96
102
  def self.print_warning(message)
97
- $stdout.puts "#{YELLOW}[*] #{message}#{CLEAR}"
103
+ $stdout.puts "#{YELLOW}#{BRIGHT}[*]#{BRIGHT_OFF} #{message}#{CLEAR}"
98
104
  end
99
105
 
100
106
  #
@@ -108,7 +114,7 @@ module Ronin
108
114
  # @api private
109
115
  #
110
116
  def self.print_error(message)
111
- $stdout.puts "#{RED}[!] #{message}#{CLEAR}"
117
+ $stdout.puts "#{RED}#{BRIGHT}[!]#{BRIGHT_OFF} #{message}#{CLEAR}"
112
118
  end
113
119
 
114
120
  end
@@ -17,6 +17,7 @@
17
17
  # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
+ require 'ronin/extensions/regexp'
20
21
  require 'ronin/fuzzing/extensions'
21
22
 
22
23
  require 'set'
@@ -31,8 +32,15 @@ module Ronin
31
32
 
32
33
  include Enumerable
33
34
 
34
- # The path to the wordlist file or a list of words
35
- attr_accessor :list
35
+ # The path to the wordlist file
36
+ #
37
+ # @since 0.5.0
38
+ attr_reader :path
39
+
40
+ # The words for the list
41
+ #
42
+ # @since 0.5.0
43
+ attr_reader :words
36
44
 
37
45
  # Mutation rules to apply to every word in the list
38
46
  attr_reader :mutations
@@ -40,7 +48,7 @@ module Ronin
40
48
  #
41
49
  # Initializes the wordlist.
42
50
  #
43
- # @param [String, Enumerable] list
51
+ # @param [String, Enumerable] wordlist
44
52
  # The path of the wordlist or list of words.
45
53
  #
46
54
  # @param [Hash{Regexp,String,Symbol => Symbol,#each}] mutations
@@ -52,6 +60,9 @@ module Ronin
52
60
  # @yieldparam [Wordlist] wordlist
53
61
  # The new wordlist object.
54
62
  #
63
+ # @raise [TypeError]
64
+ # The list was not a path to a wordlist file, nor a list of words.
65
+ #
55
66
  # @example Use a file wordlist
56
67
  # wordlist = Wordlist.new('passwords.txt')
57
68
  #
@@ -65,10 +76,19 @@ module Ronin
65
76
  #
66
77
  # @api public
67
78
  #
68
- def initialize(list,mutations={})
69
- @list = list
70
- @mutations = {}
71
- @mutations.merge!(mutations)
79
+ def initialize(wordlist,mutations={})
80
+ case wordlist
81
+ when String
82
+ @path = wordlist
83
+ @words = nil
84
+ when Enumerable
85
+ @path = nil
86
+ @words = wordlist
87
+ else
88
+ raise(TypeError,"wordlist must be a path or Enumerable")
89
+ end
90
+
91
+ @mutations = mutations
72
92
 
73
93
  yield self if block_given?
74
94
  end
@@ -93,7 +113,7 @@ module Ronin
93
113
  words_seen = SortedSet[]
94
114
 
95
115
  text.each_line do |line|
96
- line.split.each do |word|
116
+ line.scan(Regexp::WORD) do |word|
97
117
  if block_given?
98
118
  yield word unless words_seen.include?(word)
99
119
  end
@@ -121,6 +141,41 @@ module Ronin
121
141
  new(parse(text),mutations)
122
142
  end
123
143
 
144
+ #
145
+ # Creates a new wordlist file.
146
+ #
147
+ # @param [String] path
148
+ # The path to the wordlist file.
149
+ #
150
+ # @param [String] text
151
+ # The text to parse.
152
+ #
153
+ # @param [Hash{Regexp,String,Symbol => Symbol,#each}] mutations
154
+ # Additional mutations for the wordlist.
155
+ #
156
+ # @return [Wordlist]
157
+ # The newly built wordlist.
158
+ #
159
+ # @since 0.5.0
160
+ #
161
+ def self.create(path,text,mutations={})
162
+ wordlist = build(text,mutations)
163
+
164
+ return wordlist.save(path)
165
+ end
166
+
167
+ #
168
+ # The wordlist file or list of words.
169
+ #
170
+ # @return [String, Enumerable]
171
+ # The path to the wordlist file or list of words.
172
+ #
173
+ # @api semipublic
174
+ #
175
+ def list
176
+ @path || @words
177
+ end
178
+
124
179
  #
125
180
  # Iterates over each word in the list.
126
181
  #
@@ -133,25 +188,22 @@ module Ronin
133
188
  # @return [Enumerator]
134
189
  # If no block is given, an Enumerator will be returned.
135
190
  #
136
- # @raise [TypeError]
137
- # The list was not a path to a wordlist file, nor a list of words.
191
+ # @raise [RuntimeError]
192
+ # {#path} or {#words} must be set.
138
193
  #
139
194
  # @api public
140
195
  #
141
196
  def each_word(&block)
142
197
  return enum_for(:each_word) unless block
143
198
 
144
- case @list
145
- when String
146
- File.open(@list) do |file|
199
+ if @path
200
+ File.open(@path) do |file|
147
201
  file.each_line do |line|
148
202
  yield line.chomp
149
203
  end
150
204
  end
151
- when Enumerable
152
- @list.each(&block)
153
- else
154
- raise(TypeError,"list must be a path or Enumerable")
205
+ elsif @words
206
+ @words.each(&block)
155
207
  end
156
208
  end
157
209
 
@@ -203,5 +255,28 @@ module Ronin
203
255
  String.generate([each, n],&block)
204
256
  end
205
257
 
258
+ #
259
+ # Saves the words to a new file.
260
+ #
261
+ # @param [String] path
262
+ # The path to the new wordlist file.
263
+ #
264
+ # @return [Wordlist]
265
+ # The wordlist object.
266
+ #
267
+ # @see #each
268
+ #
269
+ # @since 0.5.0
270
+ #
271
+ # @api public
272
+ #
273
+ def save(path)
274
+ File.open(path,'w') do |file|
275
+ each { |word| file.puts word }
276
+ end
277
+
278
+ return self
279
+ end
280
+
206
281
  end
207
282
  end
@@ -2,130 +2,59 @@
2
2
 
3
3
  require 'yaml'
4
4
 
5
- Gem::Specification.new do |gemspec|
6
- root = File.dirname(__FILE__)
7
- lib_dir = File.join(root,'lib')
8
- files = if File.directory?('.git')
9
- `git ls-files`.split($/)
10
- elsif File.directory?('.hg')
11
- `hg manifest`.split($/)
12
- elsif File.directory?('.svn')
13
- `svn ls -R`.split($/).select { |path| File.file?(path) }
14
- else
15
- Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
16
- end
5
+ Gem::Specification.new do |gem|
6
+ gemspec = YAML.load_file('gemspec.yml')
17
7
 
18
- filter_files = lambda { |paths|
19
- case paths
20
- when Array
21
- (files & paths)
22
- when String
23
- (files & Dir[paths])
24
- end
25
- }
26
-
27
- version = {
28
- :file => 'ronin/support/version',
29
- :constant => 'Ronin::Support::VERSION'
30
- }
31
-
32
- defaults = {
33
- 'name' => File.basename(root),
34
- 'files' => files,
35
- 'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
36
- 'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
37
- 'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
38
- }
8
+ gem.name = gemspec.fetch('name')
9
+ gem.version = gemspec.fetch('version') do
10
+ lib_dir = File.join(File.dirname(__FILE__),'lib')
11
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
39
12
 
40
- metadata = defaults.merge(YAML.load_file('gemspec.yml'))
13
+ require 'ronin/support/version'
14
+ Ronin::Support::VERSION
15
+ end
41
16
 
42
- gemspec.name = metadata.fetch('name',defaults[:name])
43
- gemspec.version = if metadata['version']
44
- metadata['version']
45
- else
46
- $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
17
+ gem.summary = gemspec['summary']
18
+ gem.description = gemspec['description']
19
+ gem.licenses = Array(gemspec['license'])
20
+ gem.authors = Array(gemspec['authors'])
21
+ gem.email = gemspec['email']
22
+ gem.homepage = gemspec['homepage']
47
23
 
48
- require version[:file]
49
- eval(version[:constant])
50
- end
24
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
51
25
 
52
- gemspec.summary = metadata.fetch('summary',metadata['description'])
53
- gemspec.description = metadata.fetch('description',metadata['summary'])
26
+ gem.files = `git ls-files`.split($/)
27
+ gem.files = glob[gemspec['files']] if gemspec['files']
54
28
 
55
- case metadata['license']
56
- when Array
57
- gemspec.licenses = metadata['license']
58
- when String
59
- gemspec.license = metadata['license']
29
+ gem.executables = gemspec.fetch('executables') do
30
+ glob['bin/*'].map { |path| File.basename(path) }
60
31
  end
32
+ gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
61
33
 
62
- case metadata['authors']
63
- when Array
64
- gemspec.authors = metadata['authors']
65
- when String
66
- gemspec.author = metadata['authors']
67
- end
68
-
69
- gemspec.email = metadata['email']
70
- gemspec.homepage = metadata['homepage']
34
+ gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
35
+ gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
36
+ gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
71
37
 
72
- case metadata['require_paths']
73
- when Array
74
- gemspec.require_paths = metadata['require_paths']
75
- when String
76
- gemspec.require_path = metadata['require_paths']
77
- end
38
+ gem.require_paths = Array(gemspec.fetch('require_paths') {
39
+ %w[ext lib].select { |dir| File.directory?(dir) }
40
+ })
78
41
 
79
- gemspec.files = filter_files[metadata['files']]
42
+ gem.requirements = gemspec['requirements']
43
+ gem.required_ruby_version = gemspec['required_ruby_version']
44
+ gem.required_rubygems_version = gemspec['required_rubygems_version']
45
+ gem.post_install_message = gemspec['post_install_message']
80
46
 
81
- gemspec.executables = metadata['executables']
82
- gemspec.extensions = metadata['extensions']
83
-
84
- if Gem::VERSION < '1.7.'
85
- gemspec.default_executable = gemspec.executables.first
86
- end
87
-
88
- gemspec.test_files = filter_files[metadata['test_files']]
89
-
90
- unless gemspec.files.include?('.document')
91
- gemspec.extra_rdoc_files = metadata['extra_doc_files']
92
- end
93
-
94
- gemspec.post_install_message = metadata['post_install_message']
95
- gemspec.requirements = metadata['requirements']
96
-
97
- if gemspec.respond_to?(:required_ruby_version=)
98
- gemspec.required_ruby_version = metadata['required_ruby_version']
99
- end
100
-
101
- if gemspec.respond_to?(:required_rubygems_version=)
102
- gemspec.required_rubygems_version = metadata['required_rubygems_version']
103
- end
104
-
105
- parse_versions = lambda { |versions|
106
- case versions
107
- when Array
108
- versions.map { |v| v.to_s }
109
- when String
110
- versions.split(/,\s*/)
111
- end
112
- }
113
-
114
- if metadata['dependencies']
115
- metadata['dependencies'].each do |name,versions|
116
- gemspec.add_dependency(name,parse_versions[versions])
117
- end
118
- end
47
+ split = lambda { |string| string.split(/,\s*/) }
119
48
 
120
- if metadata['runtime_dependencies']
121
- metadata['runtime_dependencies'].each do |name,versions|
122
- gemspec.add_runtime_dependency(name,parse_versions[versions])
49
+ if gemspec['dependencies']
50
+ gemspec['dependencies'].each do |name,versions|
51
+ gem.add_dependency(name,split[versions])
123
52
  end
124
53
  end
125
54
 
126
- if metadata['development_dependencies']
127
- metadata['development_dependencies'].each do |name,versions|
128
- gemspec.add_development_dependency(name,parse_versions[versions])
55
+ if gemspec['development_dependencies']
56
+ gemspec['development_dependencies'].each do |name,versions|
57
+ gem.add_development_dependency(name,split[versions])
129
58
  end
130
59
  end
131
60
  end
@@ -0,0 +1,13 @@
1
+ module Helpers
2
+ DIRECTORY = File.join(File.dirname(__FILE__),'hexdumps')
3
+
4
+ def load_binary_data(name)
5
+ File.open(File.join(DIRECTORY,"#{name}.bin"),'rb') do |file|
6
+ file.read
7
+ end
8
+ end
9
+
10
+ def load_hexdump(name)
11
+ File.read(File.join(DIRECTORY,"#{name}.txt"))
12
+ end
13
+ end