|
7 | 7 | require 'msf_matchers' |
8 | 8 | require 'msf_test_case' |
9 | 9 |
|
10 | | - |
11 | 10 | module MsfTest |
| 11 | + include MsfTest::MsfMatchers |
12 | 12 |
|
13 | | -include MsfTest::MsfMatchers |
| 13 | + ## This spec exists to help us describe the behavior of msfconsole - TODO |
14 | 14 |
|
| 15 | + describe "Msfconsole" do |
| 16 | + ### |
| 17 | + # Setup! |
| 18 | + ### |
15 | 19 |
|
16 | | -## This spec exists to help us describe the behavior of msfconsole - TODO |
| 20 | + before :all do |
| 21 | + @working_directory = File.dirname(__FILE__) |
17 | 22 |
|
18 | | -describe "Msfconsole" do |
19 | | - |
20 | | - ### |
21 | | - # Setup! |
22 | | - ### |
23 | | - |
24 | | - before :all do |
25 | | - |
26 | | - @working_directory = File.dirname(__FILE__) |
| 23 | + ## Static specs will make use of RC files here |
| 24 | + @static_resource_directory = "#{@working_directory}/msftest/resource" |
27 | 25 |
|
28 | | - ## Static specs will make use of RC files here |
29 | | - @static_resource_directory = "#{@working_directory}/msftest/resource" |
| 26 | + ## Directories for the generated specs |
| 27 | + @temp_directory = "#{@working_directory}/msfconsole_specs" |
| 28 | + @temp_input_directory = "#{@temp_directory}/generated_rc" |
30 | 29 |
|
31 | | - ## Directories for the generated specs |
32 | | - @temp_directory = "#{@working_directory}/msfconsole_specs" |
33 | | - @temp_input_directory = "#{@temp_directory}/generated_rc" |
| 30 | + ## Where all output from the runs will go |
| 31 | + @temp_output_directory = "#{@temp_directory}/output" |
34 | 32 |
|
35 | | - ## Where all output from the runs will go |
36 | | - @temp_output_directory = "#{@temp_directory}/output" |
| 33 | + ## Create a framework object |
| 34 | + @framework = ::Msf::Simple::Framework.create |
| 35 | + end |
37 | 36 |
|
38 | | - ## Create a framework object |
39 | | - @framework = ::Msf::Simple::Framework.create |
40 | | - end |
| 37 | + before :each do |
| 38 | + end |
41 | 39 |
|
42 | | - before :each do |
43 | | - end |
| 40 | + after :each do |
| 41 | + end |
44 | 42 |
|
45 | | - after :each do |
46 | | - |
47 | | - end |
| 43 | + after :all do |
| 44 | + ## Clean up |
| 45 | + # FileUtils.rm_rf(@temp_directory) |
| 46 | + end |
48 | 47 |
|
49 | | - after :all do |
50 | | - ## Clean up |
51 | | - #FileUtils.rm_rf(@temp_directory) |
52 | | - end |
| 48 | + ### |
| 49 | + # Static Test cases! |
| 50 | + ### |
53 | 51 |
|
54 | | - ### |
55 | | - # Static Test cases! |
56 | | - ### |
| 52 | + it "should start and let us run help" do |
| 53 | + data = start_console_and_run_rc("help", "#{@static_resource_directory}/help.rc") |
57 | 54 |
|
58 | | - it "should start and let us run help" do |
59 | | - data = start_console_and_run_rc("help","#{@static_resource_directory}/help.rc") |
60 | | - |
61 | | - success_strings = [ 'help', |
62 | | - 'Database Backend Commands', |
63 | | - 'Core Commands' ] |
| 55 | + success_strings = [ |
| 56 | + 'help', |
| 57 | + 'Database Backend Commands', |
| 58 | + 'Core Commands' |
| 59 | + ] |
64 | 60 | failure_strings = [] | generic_failure_strings |
65 | 61 | failure_exception_strings = [] | generic_failure_exception_strings |
66 | 62 |
|
67 | 63 | data.should contain_all_successes(success_strings) |
68 | 64 | data.should contain_no_failures_except(failure_strings, failure_exception_strings) |
69 | | - end |
| 65 | + end |
| 66 | + |
| 67 | + it "should generate a meterpreter session against a vulnerable win32 host" do |
| 68 | + ## Set input & output to something sane |
| 69 | + input = Rex::Ui::Text::Input::Stdio.new |
| 70 | + output = Rex::Ui::Text::Output::File.new("temp.output") |
| 71 | + session = generate_x86_meterpreter_session(input, output) |
70 | 72 |
|
71 | | - it "should generate a meterpreter session against a vulnerable win32 host" do |
72 | | - ## Set input & output to something sane |
73 | | - input = Rex::Ui::Text::Input::Stdio.new |
74 | | - output = Rex::Ui::Text::Output::File.new("temp.output") |
75 | | - session = generate_x86_meterpreter_session(input, output) |
| 73 | + session.should_not be_nil |
76 | 74 |
|
77 | | - session.should_not be_nil |
78 | | - |
79 | | - if session |
80 | | - session.load_stdapi |
81 | | - session.run_cmd("help") |
82 | | - else |
83 | | - flunk "Error interacting with session" |
| 75 | + if session |
| 76 | + session.load_stdapi |
| 77 | + session.run_cmd("help") |
| 78 | + else |
| 79 | + flunk "Error interacting with session" |
| 80 | + end |
84 | 81 | end |
85 | | - end |
86 | | - |
87 | | - ### |
88 | | - # Dynamic Test Cases!! |
89 | | - ### |
90 | 82 |
|
91 | | - @working_directory = File.dirname(__FILE__) |
| 83 | + ### |
| 84 | + # Dynamic Test Cases!! |
| 85 | + ### |
92 | 86 |
|
93 | | - ## Directories for the generated specs |
94 | | - @temp_directory = "#{@working_directory}/msfconsole_specs" |
95 | | - @temp_input_directory = "#{@temp_directory}/generated_rc" |
| 87 | + @working_directory = File.dirname(__FILE__) |
96 | 88 |
|
97 | | - ## Where all output from the runs will go |
98 | | - @temp_output_directory = "#{@temp_directory}/output" |
| 89 | + ## Directories for the generated specs |
| 90 | + @temp_directory = "#{@working_directory}/msfconsole_specs" |
| 91 | + @temp_input_directory = "#{@temp_directory}/generated_rc" |
99 | 92 |
|
100 | | - if File.directory? @temp_directory |
101 | | - FileUtils.rm_rf(@temp_directory) |
102 | | - end |
| 93 | + ## Where all output from the runs will go |
| 94 | + @temp_output_directory = "#{@temp_directory}/output" |
103 | 95 |
|
104 | | - Dir.mkdir(@temp_directory) |
105 | | - Dir.mkdir(@temp_input_directory) |
106 | | - Dir.mkdir(@temp_output_directory) |
107 | | - |
108 | | - Dir.glob("#{@working_directory}/msftest/*.msftest").each do |filename| |
109 | | - |
110 | | - ## Parse this test case |
111 | | - test_case = MsfTestCase.new(filename) |
112 | | - puts "Found #{test_case.name} in: #{filename}" |
113 | | - |
114 | | - ## Write the commands back to a temporary RC file |
115 | | - puts "Writing #{@temp_input_directory}/#{test_case.name}.rc" |
116 | | - File.open("#{@temp_input_directory}/#{test_case.name}.rc", 'w') { |f| f.puts test_case.commands } |
117 | | - |
118 | | - ## Create the rspec Test Case |
119 | | - it "should #{test_case.name}" do |
120 | | - |
121 | | - ## Gather the success / failure strings, and combine with the generics |
122 | | - success_strings = test_case.expected_successes |
123 | | - failure_strings = test_case.expected_failures | generic_failure_strings |
124 | | - failure_exception_strings = test_case.expected_failure_exceptions | generic_failure_exception_strings |
125 | | - |
126 | | - ## run the commands |
127 | | - data = start_console_and_run_rc( test_case.name, "#{@temp_input_directory}/#{test_case.name}.rc") |
128 | | - |
129 | | - ## check the output |
130 | | - data.should contain_all_successes(success_strings) |
131 | | - data.should contain_no_failures_except(failure_strings, failure_exception_strings) |
132 | | - |
133 | | - ## Clean up |
134 | | - #File.delete("#{@temp_input_directory}/#{test_case.name}.rc") |
135 | | - #File.delete("#{@temp_output_directory}/#{test_case.name}") |
| 96 | + if File.directory? @temp_directory |
| 97 | + FileUtils.rm_rf(@temp_directory) |
136 | 98 | end |
137 | | - end |
138 | 99 |
|
139 | | - ### |
140 | | - # Test case helpers: |
141 | | - ### |
142 | | - def generic_success_strings |
143 | | - [] |
144 | | - end |
145 | | - |
146 | | - def generic_failure_strings |
147 | | - ['fatal', 'fail', 'error', 'exception'] |
148 | | - end |
149 | | - |
150 | | - def generic_failure_exception_strings |
151 | | - [] |
152 | | - end |
| 100 | + Dir.mkdir(@temp_directory) |
| 101 | + Dir.mkdir(@temp_input_directory) |
| 102 | + Dir.mkdir(@temp_output_directory) |
| 103 | + |
| 104 | + Dir.glob("#{@working_directory}/msftest/*.msftest").each do |filename| |
| 105 | + ## Parse this test case |
| 106 | + test_case = MsfTestCase.new(filename) |
| 107 | + puts "Found #{test_case.name} in: #{filename}" |
| 108 | + |
| 109 | + ## Write the commands back to a temporary RC file |
| 110 | + puts "Writing #{@temp_input_directory}/#{test_case.name}.rc" |
| 111 | + File.open("#{@temp_input_directory}/#{test_case.name}.rc", 'w') { |f| f.puts test_case.commands } |
| 112 | + |
| 113 | + ## Create the rspec Test Case |
| 114 | + it "should #{test_case.name}" do |
| 115 | + ## Gather the success / failure strings, and combine with the generics |
| 116 | + success_strings = test_case.expected_successes |
| 117 | + failure_strings = test_case.expected_failures | generic_failure_strings |
| 118 | + failure_exception_strings = test_case.expected_failure_exceptions | generic_failure_exception_strings |
| 119 | + |
| 120 | + ## run the commands |
| 121 | + data = start_console_and_run_rc(test_case.name, "#{@temp_input_directory}/#{test_case.name}.rc") |
| 122 | + |
| 123 | + ## check the output |
| 124 | + data.should contain_all_successes(success_strings) |
| 125 | + data.should contain_no_failures_except(failure_strings, failure_exception_strings) |
| 126 | + |
| 127 | + ## Clean up |
| 128 | + # File.delete("#{@temp_input_directory}/#{test_case.name}.rc") |
| 129 | + # File.delete("#{@temp_output_directory}/#{test_case.name}") |
| 130 | + end |
| 131 | + end |
153 | 132 |
|
154 | | - def start_console_and_run_rc(name,rc_file, database_file=false) |
155 | | - output_file = "#{@temp_output_directory}/#{name}" |
| 133 | + ### |
| 134 | + # Test case helpers: |
| 135 | + ### |
| 136 | + def generic_success_strings |
| 137 | + [] |
| 138 | + end |
156 | 139 |
|
157 | | - if database_file |
158 | | - msfconsole_string = "ruby #{@working_directory}/../../../msfconsole -o #{output_file} -r #{rc_file} -y #{database_file}" |
159 | | - else |
160 | | - msfconsole_string = "ruby #{@working_directory}/../../../msfconsole -o #{output_file} -r #{rc_file}" |
| 140 | + def generic_failure_strings |
| 141 | + ['fatal', 'fail', 'error', 'exception'] |
161 | 142 | end |
162 | | - |
163 | | - system("#{msfconsole_string}") |
164 | 143 |
|
165 | | - data = hlp_file_to_string("#{output_file}") |
166 | | - end |
167 | | - |
168 | | - def generate_x86_meterpreter_session(input, output) |
169 | | - ## Setup for win32 |
170 | | - exploit_name = 'windows/smb/psexec' |
171 | | - payload_name = 'windows/meterpreter/bind_tcp' |
172 | | - |
173 | | - ## Fire it off against a known-vulnerable host |
174 | | - session = @framework.exploits.create(exploit_name).exploit_simple( |
175 | | - 'Options' => {'RHOST' => "vulnerable", "SMBUser" => "administrator", "SMBPass" => ""}, |
176 | | - 'Payload' => payload_name, |
177 | | - 'LocalInput' => input, |
178 | | - 'LocalOutput' => output) |
179 | | - |
180 | | - ## If a session came back, try to interact with it. |
181 | | - if session |
182 | | - return session |
183 | | - else |
184 | | - return nil |
| 144 | + def generic_failure_exception_strings |
| 145 | + [] |
185 | 146 | end |
186 | | - end |
187 | 147 |
|
188 | | - def generate_win64_meterpreter_session(input, output) |
189 | | - raise "Not Implemented" |
190 | | - end |
| 148 | + def start_console_and_run_rc(name, rc_file, database_file = false) |
| 149 | + output_file = "#{@temp_output_directory}/#{name}" |
191 | 150 |
|
| 151 | + if database_file |
| 152 | + msfconsole_string = "ruby #{@working_directory}/../../../msfconsole -o #{output_file} -r #{rc_file} -y #{database_file}" |
| 153 | + else |
| 154 | + msfconsole_string = "ruby #{@working_directory}/../../../msfconsole -o #{output_file} -r #{rc_file}" |
| 155 | + end |
192 | 156 |
|
193 | | - def generate_java_meterpreter_session(input, output) |
194 | | - raise "Not Implemented" |
195 | | - end |
196 | | - |
197 | | - def generate_php_meterpreter_session(input, output) |
198 | | - raise "Not Implemented" |
199 | | - end |
| 157 | + system("#{msfconsole_string}") |
| 158 | + |
| 159 | + data = hlp_file_to_string("#{output_file}") |
| 160 | + end |
| 161 | + |
| 162 | + def generate_x86_meterpreter_session(input, output) |
| 163 | + ## Setup for win32 |
| 164 | + exploit_name = 'windows/smb/psexec' |
| 165 | + payload_name = 'windows/meterpreter/bind_tcp' |
| 166 | + |
| 167 | + ## Fire it off against a known-vulnerable host |
| 168 | + session = @framework.exploits.create(exploit_name).exploit_simple( |
| 169 | + 'Options' => { 'RHOST' => "vulnerable", "SMBUser" => "administrator", "SMBPass" => "" }, |
| 170 | + 'Payload' => payload_name, |
| 171 | + 'LocalInput' => input, |
| 172 | + 'LocalOutput' => output |
| 173 | + ) |
| 174 | + |
| 175 | + ## If a session came back, try to interact with it. |
| 176 | + if session |
| 177 | + return session |
| 178 | + else |
| 179 | + return nil |
| 180 | + end |
| 181 | + end |
| 182 | + |
| 183 | + def generate_win64_meterpreter_session(input, output) |
| 184 | + raise "Not Implemented" |
| 185 | + end |
| 186 | + |
| 187 | + def generate_java_meterpreter_session(input, output) |
| 188 | + raise "Not Implemented" |
| 189 | + end |
200 | 190 |
|
201 | | - def hlp_file_to_string(filename) |
202 | | - data = "" |
203 | | - f = File.open(filename, "r") |
204 | | - f.each_line do |line| |
205 | | - data += line |
| 191 | + def generate_php_meterpreter_session(input, output) |
| 192 | + raise "Not Implemented" |
| 193 | + end |
| 194 | + |
| 195 | + def hlp_file_to_string(filename) |
| 196 | + data = "" |
| 197 | + f = File.open(filename, "r") |
| 198 | + f.each_line do |line| |
| 199 | + data += line |
| 200 | + end |
| 201 | + return data |
206 | 202 | end |
207 | | - return data |
208 | 203 | end |
209 | 204 | end |
210 | | -end |
0 commit comments