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
@@ -17,6 +17,29 @@ describe Network::TCP do
17
17
  obj
18
18
  end
19
19
 
20
+ describe "#tcp_open?" do
21
+ let(:host) { 'example.com' }
22
+ let(:port) { 80 }
23
+
24
+ it "should return true for open ports" do
25
+ subject.tcp_open?(host,port).should == true
26
+ end
27
+
28
+ it "should return false for closed ports" do
29
+ subject.tcp_open?('localhost',rand(1024) + 1).should == false
30
+ end
31
+
32
+ it "should have a timeout for firewalled ports" do
33
+ timeout = 2
34
+
35
+ t1 = Time.now
36
+ subject.tcp_open?(host,1337,nil,nil,timeout)
37
+ t2 = Time.now
38
+
39
+ (t2 - t1).to_i.should <= timeout
40
+ end
41
+ end
42
+
20
43
  describe "#tcp_connect" do
21
44
  let(:local_port) { 1024 + rand(65535 - 1024) }
22
45
 
@@ -238,7 +261,7 @@ describe Network::TCP do
238
261
  end
239
262
  end
240
263
 
241
- describe "#tcp_single_server" do
264
+ describe "#tcp_accept" do
242
265
  let(:server_port) { 1024 + rand(65535 - 1024) }
243
266
 
244
267
  pending "need to automate connecting to the TCPServer"
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'ronin/network/telnet'
3
+
4
+ describe Network::Telnet do
5
+ describe "helpers", :network do
6
+ let(:host) { 'towel.blinkenlights.nl' }
7
+
8
+ subject do
9
+ obj = Object.new
10
+ obj.extend described_class
11
+ obj
12
+ end
13
+
14
+ describe "#telnet_connect" do
15
+ it "should return a Net::Telnet object" do
16
+ telnet = subject.telnet_connect(host)
17
+
18
+ telnet.should be_kind_of(Net::Telnet)
19
+ telnet.close
20
+ end
21
+
22
+ it "should connect to a telnet service on port 23" do
23
+ telnet = subject.telnet_connect(host)
24
+
25
+ telnet.close
26
+ end
27
+
28
+ context "when given a block" do
29
+ it "should yield the new Net::Telnet object" do
30
+ telnet = nil
31
+
32
+ subject.telnet_connect(host) do |telnet_object|
33
+ telnet = telnet_object
34
+ end
35
+
36
+ telnet.should be_kind_of(Net::Telnet)
37
+ telnet.close
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#telnet_session" do
43
+ it "should yield a new Net::Telnet object" do
44
+ yielded_telnet = nil
45
+
46
+ subject.telnet_session(host) do |telnet|
47
+ yielded_telnet = telnet
48
+ end
49
+
50
+ yielded_telnet.should be_kind_of(Net::Telnet)
51
+ end
52
+
53
+ it "should close the Telnet session after yielding it" do
54
+ session = nil
55
+ was_open = nil
56
+
57
+ subject.telnet_session(host) do |telnet|
58
+ session = telnet
59
+ was_open = !telnet.sock.closed?
60
+ end
61
+
62
+ was_open.should == true
63
+ session.sock.should be_closed
64
+ end
65
+ end
66
+ end
67
+ end
@@ -17,6 +17,29 @@ describe Network::UDP do
17
17
  obj
18
18
  end
19
19
 
20
+ describe "#udp_open?" do
21
+ let(:host) { '4.2.2.1' }
22
+ let(:port) { 53 }
23
+
24
+ it "should return true for open ports" do
25
+ subject.udp_open?(host,port).should == true
26
+ end
27
+
28
+ it "should return false for closed ports" do
29
+ subject.udp_open?('localhost',rand(1024) + 1).should == false
30
+ end
31
+
32
+ it "should have a timeout for firewalled ports" do
33
+ timeout = 2
34
+
35
+ t1 = Time.now
36
+ subject.udp_open?(host,1337,nil,nil,timeout)
37
+ t2 = Time.now
38
+
39
+ (t2 - t1).to_i.should <= timeout
40
+ end
41
+ end
42
+
20
43
  describe "#udp_connect" do
21
44
  let(:local_port) { 1024 + rand(65535 - 1024) }
22
45
 
@@ -241,7 +264,7 @@ describe Network::UDP do
241
264
  end
242
265
  end
243
266
 
244
- describe "#udp_single_server" do
267
+ describe "#udp_recv" do
245
268
  let(:server_port) { 1024 + rand(65535 - 1024) }
246
269
  end
247
270
  end
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+ require 'network/shared/unix_server'
3
+ require 'ronin/network/unix'
4
+
5
+ require 'fileutils'
6
+
7
+ describe Network::UNIX do
8
+ describe "helper methods", :network do
9
+ subject do
10
+ obj = Object.new
11
+ obj.extend described_class
12
+ obj
13
+ end
14
+
15
+ describe "#unix_open?" do
16
+ include_context "UNIX Server"
17
+
18
+ let(:old_path) { socket_path('ronin_old_unix_socket') }
19
+ let(:bad_path) { socket_path('ronin_bad_unix_socket') }
20
+
21
+ before(:all) { UNIXServer.new(old_path).close }
22
+
23
+ it "should return true for listening UNIX sockets" do
24
+ subject.unix_open?(path).should == true
25
+ end
26
+
27
+ it "should return false for closed UNIX sockets" do
28
+ subject.unix_open?(old_path).should == false
29
+ end
30
+
31
+ it "should have a timeout for non-existent UNIX sockets" do
32
+ timeout = 2
33
+
34
+ t1 = Time.now
35
+ subject.unix_open?(bad_path,timeout)
36
+ t2 = Time.now
37
+
38
+ (t2 - t1).to_i.should <= timeout
39
+ end
40
+
41
+ after(:all) { FileUtils.rm(old_path) }
42
+ end
43
+
44
+ describe "#unix_connect" do
45
+ include_context "UNIX Server"
46
+
47
+ it "should open a UNIXSocket" do
48
+ socket = subject.unix_connect(path)
49
+
50
+ socket.should be_kind_of(UNIXSocket)
51
+ socket.should_not be_closed
52
+
53
+ socket.close
54
+ end
55
+
56
+ it "should yield the new UNIXSocket" do
57
+ socket = nil
58
+
59
+ subject.unix_connect(path) do |yielded_socket|
60
+ socket = yielded_socket
61
+ end
62
+
63
+ socket.should_not be_closed
64
+ socket.close
65
+ end
66
+ end
67
+
68
+ describe "#unix_connect_and_send" do
69
+ include_context "UNIX Server"
70
+
71
+ let(:data) { "HELO ronin\n" }
72
+
73
+ it "should connect and then send data" do
74
+ socket = subject.unix_connect_and_send(data,path)
75
+ response = socket.readline
76
+
77
+ response.should == data
78
+
79
+ socket.close
80
+ end
81
+
82
+ it "should yield the UNIXSocket" do
83
+ response = nil
84
+
85
+ socket = subject.unix_connect_and_send(data,path) do |socket|
86
+ response = socket.readline
87
+ end
88
+
89
+ response.should == data
90
+
91
+ socket.close
92
+ end
93
+ end
94
+
95
+ describe "#unix_session" do
96
+ include_context "UNIX Server"
97
+
98
+ it "should open then close a UNIXSocket" do
99
+ socket = nil
100
+
101
+ subject.unix_session(path) do |yielded_socket|
102
+ socket = yielded_socket
103
+ end
104
+
105
+ socket.should be_kind_of(UNIXSocket)
106
+ socket.should be_closed
107
+ end
108
+ end
109
+
110
+ describe "#unix_send" do
111
+ let(:server_path) { File.join(Dir.tmpdir,'ronin_unix_server') }
112
+ let(:data) { "hello\n" }
113
+
114
+ before(:each) { @server = UNIXServer.new(server_path) }
115
+
116
+ it "should send data to a service" do
117
+ subject.unix_send(data,server_path)
118
+
119
+ client = @server.accept
120
+ sent = client.readline
121
+
122
+ client.close
123
+
124
+ sent.should == data
125
+ end
126
+
127
+ after(:each) do
128
+ @server.close
129
+
130
+ FileUtils.rm(server_path)
131
+ end
132
+ end
133
+
134
+ describe "#unix_server" do
135
+ let(:server_path) { File.join(Dir.tmpdir,'ronin_unix_server') }
136
+
137
+ it "should create a new UNIXServer" do
138
+ server = subject.unix_server(server_path)
139
+
140
+ server.should be_kind_of(UNIXServer)
141
+ server.should_not be_closed
142
+
143
+ server.close
144
+ end
145
+
146
+ it "should yield the new UNIXServer" do
147
+ server = nil
148
+
149
+ subject.unix_server(server_path) do |yielded_server|
150
+ server = yielded_server
151
+ end
152
+
153
+ server.should be_kind_of(UNIXServer)
154
+ server.should_not be_closed
155
+
156
+ server.close
157
+ end
158
+
159
+ after(:each) { FileUtils.rm(server_path) }
160
+ end
161
+
162
+ describe "#unix_server_session" do
163
+ let(:server_path) { File.join(Dir.tmpdir,'ronin_unix_server') }
164
+
165
+ it "should create a temporary UNIXServer" do
166
+ server = nil
167
+
168
+ subject.unix_server_session(server_path) do |yielded_server|
169
+ server = yielded_server
170
+ end
171
+
172
+ server.should be_kind_of(UNIXServer)
173
+ server.should be_closed
174
+ end
175
+
176
+ after(:each) { FileUtils.rm(server_path) }
177
+ end
178
+
179
+ describe "#unix_accept" do
180
+ pending "need to automate connecting to the UNIXServer"
181
+ end
182
+ end
183
+ end
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
  require 'ronin/wordlist'
3
3
 
4
- require 'tempfile'
4
+ require 'tmpdir'
5
5
 
6
6
  describe Wordlist do
7
7
  let(:words) { %w[foo bar baz] }
8
+ let(:path) { File.join(Dir.tmpdir,'ronin-support-wordlist') }
8
9
 
9
10
  before(:all) do
10
- Tempfile.open('ronin-support-wordlist') do |file|
11
- words.each { |word| file.puts word }
12
-
13
- @path = file.path
11
+ File.open(path,'w') do |file|
12
+ file.puts(*words)
14
13
  end
15
14
  end
16
15
 
@@ -41,28 +40,73 @@ describe Wordlist do
41
40
  end
42
41
  end
43
42
 
43
+ describe "create" do
44
+ let(:created_path) { File.join(Dir.tmpdir,'ronin-support-created-wordlist') }
45
+ let(:text) { words.join(' ') }
46
+
47
+ it "should return the new Wordlist object" do
48
+ wordlist = described_class.create(created_path,text)
49
+
50
+ wordlist.to_a.should =~ words
51
+ end
52
+
53
+ it "should create a wordlist file from text" do
54
+ described_class.create(created_path,text)
55
+
56
+ saved_words = File.open(created_path).each_line.map(&:chomp)
57
+
58
+ saved_words.should =~ words
59
+ end
60
+
61
+ it "should apply mutations to the created wordlist" do
62
+ described_class.create(created_path,text, 'o' => ['0'])
63
+
64
+ saved_words = File.open(created_path).each_line.map(&:chomp)
65
+
66
+ saved_words.should =~ %w[foo f0o fo0 f00 bar baz]
67
+ end
68
+
69
+ after(:all) { FileUtils.rm(created_path) }
70
+ end
71
+
44
72
  describe "#initialize" do
45
73
  it "should accept a list of words" do
46
- subject.to_a.should == words
74
+ wordlist = described_class.new(path)
75
+
76
+ wordlist.to_a.should == words
47
77
  end
48
78
 
49
79
  it "should accept a path to a wordlist file" do
50
- file = described_class.new(@path)
80
+ wordlist = described_class.new(path)
51
81
 
52
- file.to_a.should == words
82
+ wordlist.to_a.should == words
53
83
  end
54
- end
55
84
 
56
- describe "#each_word" do
57
85
  it "should raise a TypeError for non-String / non-Enumerable objects" do
58
- wordlist = described_class.new(Object.new)
59
-
60
86
  lambda {
61
- wordlist.each_word { |word| }
87
+ described_class.new(Object.new)
62
88
  }.should raise_error(TypeError)
63
89
  end
64
90
  end
65
91
 
92
+ describe "#each_word" do
93
+ context "with wordlist file" do
94
+ subject { described_class.new(path) }
95
+
96
+ it "should enumerate over the words" do
97
+ subject.each_word.to_a.should == words
98
+ end
99
+ end
100
+
101
+ context "with words" do
102
+ subject { described_class.new(words) }
103
+
104
+ it "should enumerate over the words" do
105
+ subject.each_word.to_a.should == words
106
+ end
107
+ end
108
+ end
109
+
66
110
  describe "#each" do
67
111
  it "should rewind file lists" do
68
112
  subject.each { |word| }
@@ -87,4 +131,21 @@ describe Wordlist do
87
131
  ]
88
132
  end
89
133
  end
134
+
135
+ describe "#save" do
136
+ let(:saved_path) { File.join(Dir.tmpdir,'ronin-support-saved-wordlist') }
137
+
138
+ it "should save the words with mutations to a file" do
139
+ subject.save(saved_path)
140
+
141
+ saved_words = File.open(saved_path).each_line.map(&:chomp)
142
+ expected_words = subject.to_a
143
+
144
+ saved_words.should == expected_words
145
+ end
146
+
147
+ after(:all) { FileUtils.rm(saved_path) }
148
+ end
149
+
150
+ after(:all) { FileUtils.rm(path) }
90
151
  end