lab 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +4 -0
  2. data/config/test_lab.yml +11 -0
  3. data/config/test_targets.yml +21 -0
  4. data/lib/lab/controller/dynagen_controller.rb +6 -6
  5. data/lib/lab/controller/remote_esx_controller.rb +51 -51
  6. data/lib/lab/controller/remote_esxi_controller.rb +62 -0
  7. data/lib/lab/controller/remote_workstation_controller.rb +12 -12
  8. data/lib/lab/controller/virtualbox_controller.rb +16 -16
  9. data/lib/lab/controller/workstation_controller.rb +9 -9
  10. data/lib/lab/controller/workstation_vixr_controller.rb +9 -9
  11. data/lib/lab/controllers.rb +1 -3
  12. data/lib/lab/driver/dynagen_driver.rb +32 -32
  13. data/lib/lab/driver/fog_driver.rb +144 -144
  14. data/lib/lab/driver/remote_esxi_driver.rb +177 -0
  15. data/lib/lab/driver/remote_workstation_driver.rb +181 -181
  16. data/lib/lab/driver/virtualbox_driver.rb +132 -132
  17. data/lib/lab/driver/vm_driver.rb +177 -177
  18. data/lib/lab/driver/workstation_driver.rb +218 -218
  19. data/lib/lab/driver/workstation_vixr_driver.rb +108 -108
  20. data/lib/lab/drivers.rb +1 -1
  21. data/lib/lab/modifier/backtrack5_modifier.rb +8 -8
  22. data/lib/lab/modifier/dos_modifier.rb +3 -3
  23. data/lib/lab/modifier/test_modifier.rb +6 -6
  24. data/lib/lab/version.rb +1 -1
  25. data/lib/lab/vm.rb +242 -242
  26. data/lib/lab/vm_controller.rb +217 -211
  27. data/src/Gemfile +4 -0
  28. data/src/README.md +80 -0
  29. data/src/Rakefile +1 -0
  30. data/src/TODO +15 -0
  31. data/src/config/test_lab.yml +11 -0
  32. data/src/config/test_targets.yml +21 -0
  33. data/src/lab.gemspec +35 -0
  34. data/src/lib/lab.rb +2 -0
  35. data/src/lib/lab/controller/dynagen_controller.rb +14 -0
  36. data/src/lib/lab/controller/fog_controller.rb +6 -0
  37. data/src/lib/lab/controller/remote_esxi_controller.rb +62 -0
  38. data/src/lib/lab/controller/remote_workstation_controller.rb +22 -0
  39. data/src/lib/lab/controller/virtualbox_controller.rb +25 -0
  40. data/src/lib/lab/controller/vsphere_controller.rb +18 -0
  41. data/src/lib/lab/controller/workstation_controller.rb +17 -0
  42. data/src/lib/lab/controller/workstation_vixr_controller.rb +19 -0
  43. data/src/lib/lab/controllers.rb +9 -0
  44. data/src/lib/lab/driver/dynagen_driver.rb +47 -0
  45. data/src/lib/lab/driver/fog_driver.rb +104 -0
  46. data/src/lib/lab/driver/remote_esxi_driver.rb +177 -0
  47. data/src/lib/lab/driver/remote_workstation_driver.rb +197 -0
  48. data/src/lib/lab/driver/virtualbox_driver.rb +142 -0
  49. data/src/lib/lab/driver/vm_driver.rb +195 -0
  50. data/src/lib/lab/driver/vsphere_driver.rb +120 -0
  51. data/src/lib/lab/driver/workstation_driver.rb +234 -0
  52. data/src/lib/lab/driver/workstation_vixr_driver.rb +126 -0
  53. data/src/lib/lab/drivers.rb +9 -0
  54. data/src/lib/lab/modifier/backtrack5_modifier.rb +16 -0
  55. data/src/lib/lab/modifier/dos_modifier.rb +14 -0
  56. data/src/lib/lab/modifier/test_modifier.rb +16 -0
  57. data/src/lib/lab/modifiers.rb +3 -0
  58. data/src/lib/lab/version.rb +3 -0
  59. data/src/lib/lab/vm.rb +269 -0
  60. data/src/lib/lab/vm_controller.rb +275 -0
  61. data/src/test/.gitkeep +0 -0
  62. metadata +51 -12
  63. data/lib/lab/driver/remote_esx_driver.rb +0 -177
@@ -26,216 +26,222 @@ require 'net/ssh'
26
26
 
27
27
  module Lab
28
28
  module Controllers
29
- class VmController
30
-
31
- include Enumerable
32
- include Lab::Controllers::WorkstationController
33
- include Lab::Controllers::VirtualBoxController
34
- include Lab::Controllers::FogController
35
- include Lab::Controllers::DynagenController
36
- include Lab::Controllers::RemoteEsxController
37
- include Lab::Controllers::RemoteWorkstationController
38
- #include Lab::Controllers::QemuController
39
- #include Lab::Controllers::QemudoController
40
- def initialize (labdef=nil)
41
-
42
- # Start with an empty array of vm objects
43
- @vms = []
44
-
45
- # labdef is a just a big array of hashes
46
- load_vms(labdef) if labdef
47
- end
48
-
49
- def clear!
50
- @vms = []
51
- end
52
-
53
- def [](x)
54
- # Support indexing by both names and number
55
- if x.class == String
56
- find_by_vmid(x)
57
- else
58
- return @vms[x]
59
- end
60
- end
61
-
62
- def find_by_vmid(vmid)
63
- @vms.each do |vm|
64
- if (vm.hostname.to_s.downcase == vmid.to_s.downcase)
65
- return vm
66
- end
67
- end
68
- return nil
69
- end
70
-
71
- def add_vm(vmid, location=nil, os=nil, tools=nil, credentials=nil, user=nil, host=nil)
72
- @vms << Vm.new( { 'vmid' => vmid,
73
- 'driver' => type,
74
- 'location' => location,
75
- 'credentials' => credentials,
76
- 'user' => user,
77
- 'host' => host} )
78
- end
79
-
80
- def remove_by_vmid(vmid)
81
- @vms.delete(self.find_by_vmid(vmid))
82
- end
83
-
84
- def from_file(file)
85
- load_vms(YAML::load_file(file))
86
- end
87
-
88
- def load_vms(vms)
89
- vms.each do |item|
90
- vm = Vm.new(item)
91
- @vms << vm unless includes_vmid? vm.vmid
92
- end
93
- end
94
-
95
- def to_file(file)
96
- File.open(file, 'w') { |f| @vms.each { |vm| f.puts vm.to_yaml } }
97
- end
98
-
99
- def each &block
100
- @vms.each { |vm| yield vm }
101
- end
102
-
103
- def includes?(specified_vm)
104
- @vms.each { |vm| if (vm == specified_vm) then return true end }
105
- end
106
-
107
- def includes_vmid?(vmid)
108
- @vms.each do |vm|
109
- return true if (vm.vmid == vmid)
110
- end
111
- false
112
- end
113
-
114
- def build_from_dir(driver_type, dir, clear=false)
115
-
116
- if clear
117
- @vms = []
118
- end
119
-
120
- if driver_type.downcase == "workstation"
121
- vm_list = ::Lab::Controllers::WorkstationController::dir_list(dir)
122
- elsif driver_type.downcase == "virtualbox"
123
- vm_list = ::Lab::Controllers::VirtualBoxController::dir_list(dir)
124
- elsif driver_type.downcase == "fog"
125
- vm_list = ::Lab::Controllers::FogController::dir_list(dir)
126
- elsif driver_type.downcase == "Dynagen"
127
- vm_list = ::Lab::Controllers::DynagenController::dir_list(dir)
128
- elsif driver_type.downcase == "remote_workstation"
129
- vm_list = ::Lab::Controllers::RemoteWorkstationController::dir_list(dir)
130
- elsif driver_type.downcase == "remote_esx"
131
- vm_list =::Lab::Controllers::RemoteEsxController::dir_list(dir)
132
- else
133
- raise TypeError, "Unsupported VM Type"
134
- end
135
-
136
- vm_list.each_index do |index|
137
- @vms << Vm.new( {'vmid' => "vm_#{index}", 'driver' => driver_type, 'location' => vm_list[index]} )
138
- end
139
- end
140
-
141
- def build_from_running(driver_type=nil, user=nil, host=nil, clear=false)
142
-
143
- if clear
144
- @vms = []
145
- end
146
-
147
- case driver_type.intern
148
- when :workstation
149
- vm_list = ::Lab::Controllers::WorkstationController::running_list
150
-
151
- vm_list.each do |item|
152
-
153
- ## Name the VM
154
- index = @vms.count + 1
155
-
156
- ## Add it to the vm list
157
- @vms << Vm.new( { 'vmid' => "vm_#{index}",
158
- 'driver' => driver_type,
159
- 'location' => item,
160
- 'user' => user,
161
- 'host' => host } )
162
- end
163
-
164
-
165
- when :virtualbox
166
- vm_list = ::Lab::Controllers::VirtualBoxController::running_list
167
- vm_list.each do |item|
168
- ## Add it to the vm list
169
- @vms << Vm.new( { 'vmid' => "#{item}",
170
- 'driver' => driver_type,
171
- 'location' => nil })
172
- end
173
- when :fog
174
- raise "Unsupported" # TODO - figure out a way to allow this
175
- when :dynagen
176
- raise "Unsupported"
177
- when :remote_workstation
178
- vm_list = ::Lab::Controllers::RemoteWorkstationController::running_list(user, host)
179
-
180
- vm_list.each do |item|
181
-
182
- ## Name the VM
183
- index = @vms.count + 1
184
-
185
- ## Add it to the vm list
186
- @vms << Vm.new( { 'vmid' => "vm_#{index}",
187
- 'driver' => driver_type,
188
- 'location' => item,
189
- 'user' => user,
190
- 'host' => host } )
191
- end
192
- when :remote_esx
193
- vm_list = ::Lab::Controllers::RemoteEsxController::running_list(user,host)
194
-
195
- vm_list.each do |item|
196
- @vms << Vm.new( { 'vmid' => "#{item[:id]}",
197
- 'name' => "#{item[:name]}",
198
- 'driver' => driver_type,
199
- 'user' => user,
200
- 'host' => host } )
201
- end
202
-
203
- else
204
- raise TypeError, "Unsupported VM Type"
205
- end
206
-
207
- end
208
-
209
- def build_from_config(driver_type=nil, user=nil, host=nil, clear=false)
210
- if clear
211
- @vms = []
212
- end
213
-
214
- case driver_type.intern
215
- when :virtualbox
216
- vm_list = ::Lab::Controllers::VirtualBoxController::config_list
217
-
218
- vm_list.each do |item|
219
- ## Add it to the vm list
220
- @vms << Vm.new( { 'vmid' => "#{item}",
221
- 'driver' => driver_type,
222
- 'location' => nil,
223
- 'user' => user,
224
- 'host' => host } )
225
- end
226
-
227
- else
228
- raise TypeError, "Unsupported VM Type"
229
- end
230
-
231
- end
232
-
233
- def running?(vmid)
234
- if includes_vmid?(vmid)
235
- return self.find_by_vmid(vmid).running?
236
- end
237
- return false
238
- end
239
- end
29
+ class VmController
30
+
31
+ include Enumerable
32
+ include Lab::Controllers::WorkstationController
33
+ include Lab::Controllers::VirtualBoxController
34
+ include Lab::Controllers::FogController
35
+ include Lab::Controllers::DynagenController
36
+ include Lab::Controllers::RemoteEsxiController
37
+ include Lab::Controllers::RemoteWorkstationController
38
+ #include Lab::Controllers::QemuController
39
+ #include Lab::Controllers::QemudoController
40
+ def initialize (labdef=nil)
41
+
42
+ # Start with an empty array of vm objects
43
+ @vms = []
44
+
45
+ # labdef is a just a big array of hashes
46
+ load_vms(labdef) if labdef
47
+ end
48
+
49
+ def clear!
50
+ @vms = []
51
+ end
52
+
53
+ def [](x)
54
+ # Support indexing by both names and number
55
+ if x.class == String
56
+ find_by_vmid(x)
57
+ else
58
+ return @vms[x]
59
+ end
60
+ end
61
+
62
+ def find_by_vmid(vmid)
63
+ @vms.each do |vm|
64
+ if (vm.hostname.to_s.downcase == vmid.to_s.downcase)
65
+ return vm
66
+ end
67
+ end
68
+ return nil
69
+ end
70
+
71
+ def add_vm(vmid, location=nil, os=nil, tools=nil, credentials=nil, user=nil, host=nil)
72
+ @vms << Vm.new( {
73
+ 'vmid' => vmid,
74
+ 'driver' => type,
75
+ 'location' => location,
76
+ 'credentials' => credentials,
77
+ 'user' => user,
78
+ 'host' => host} )
79
+ end
80
+
81
+ def remove_by_vmid(vmid)
82
+ @vms.delete(self.find_by_vmid(vmid))
83
+ end
84
+
85
+ def from_file(file)
86
+ load_vms(YAML::load_file(file))
87
+ end
88
+
89
+ def load_vms(vms)
90
+ vms.each do |item|
91
+ vm = Vm.new(item)
92
+ @vms << vm unless includes_vmid? vm.vmid
93
+ end
94
+ end
95
+
96
+ def to_file(file)
97
+ File.open(file, 'w') { |f| @vms.each { |vm| f.puts vm.to_yaml } }
98
+ end
99
+
100
+ def each &block
101
+ @vms.each { |vm| yield vm }
102
+ end
103
+
104
+ def includes?(specified_vm)
105
+ @vms.each { |vm| if (vm == specified_vm) then return true end }
106
+ end
107
+
108
+ def includes_vmid?(vmid)
109
+ @vms.each do |vm|
110
+ return true if (vm.vmid == vmid)
111
+ end
112
+ false
113
+ end
114
+
115
+ def build_from_dir(driver_type, dir, clear=false)
116
+
117
+ if clear
118
+ @vms = []
119
+ end
120
+
121
+ if driver_type.downcase == "workstation"
122
+ vm_list = ::Lab::Controllers::WorkstationController::dir_list(dir)
123
+ elsif driver_type.downcase == "virtualbox"
124
+ vm_list = ::Lab::Controllers::VirtualBoxController::dir_list(dir)
125
+ elsif driver_type.downcase == "fog"
126
+ vm_list = ::Lab::Controllers::FogController::dir_list(dir)
127
+ elsif driver_type.downcase == "Dynagen"
128
+ vm_list = ::Lab::Controllers::DynagenController::dir_list(dir)
129
+ elsif driver_type.downcase == "remote_workstation"
130
+ vm_list = ::Lab::Controllers::RemoteWorkstationController::dir_list(dir)
131
+ elsif driver_type.downcase == "remote_esxi"
132
+ vm_list =::Lab::Controllers::RemoteEsxiController::dir_list(dir)
133
+ else
134
+ raise TypeError, "Unsupported VM Type"
135
+ end
136
+
137
+ vm_list.each_index do |index|
138
+ @vms << Vm.new( {'vmid' => "vm_#{index}", 'driver' => driver_type, 'location' => vm_list[index]} )
139
+ end
140
+ end
141
+
142
+ def build_from_running(driver_type=nil, user=nil, host=nil, clear=false)
143
+
144
+ if clear
145
+ @vms = []
146
+ end
147
+
148
+ case driver_type.intern
149
+ when :workstation
150
+ vm_list = ::Lab::Controllers::WorkstationController::running_list
151
+
152
+ vm_list.each do |item|
153
+
154
+ ## Name the VM
155
+ index = @vms.count + 1
156
+
157
+ ## Add it to the vm list
158
+ @vms << Vm.new( {
159
+ 'vmid' => "vm_#{index}",
160
+ 'driver' => driver_type,
161
+ 'location' => item,
162
+ 'user' => user,
163
+ 'host' => host } )
164
+ end
165
+
166
+
167
+ when :virtualbox
168
+ vm_list = ::Lab::Controllers::VirtualBoxController::running_list
169
+ vm_list.each do |item|
170
+ ## Add it to the vm list
171
+ @vms << Vm.new( {
172
+ 'vmid' => "#{item}",
173
+ 'driver' => driver_type,
174
+ 'location' => nil })
175
+ end
176
+ when :fog
177
+ raise "Unsupported" # TODO - figure out a way to allow this
178
+ when :dynagen
179
+ raise "Unsupported"
180
+ when :remote_workstation
181
+ vm_list = ::Lab::Controllers::RemoteWorkstationController::running_list(user, host)
182
+
183
+ vm_list.each do |item|
184
+
185
+ ## Name the VM
186
+ index = @vms.count + 1
187
+
188
+ ## Add it to the vm list
189
+ @vms << Vm.new( {
190
+ 'vmid' => "vm_#{index}",
191
+ 'driver' => driver_type,
192
+ 'location' => item,
193
+ 'user' => user,
194
+ 'host' => host } )
195
+ end
196
+ when :remote_esxi
197
+ vm_list = ::Lab::Controllers::RemoteEsxiController::running_list(user,host)
198
+
199
+ vm_list.each do |item|
200
+ @vms << Vm.new( {
201
+ 'vmid' => "#{item[:id]}",
202
+ 'name' => "#{item[:name]}",
203
+ 'driver' => driver_type,
204
+ 'user' => user,
205
+ 'host' => host } )
206
+ end
207
+
208
+ else
209
+ raise TypeError, "Unsupported VM Type"
210
+ end
211
+
212
+ end
213
+
214
+ def build_from_config(driver_type=nil, user=nil, host=nil, clear=false)
215
+ if clear
216
+ @vms = []
217
+ end
218
+
219
+ case driver_type.intern
220
+ when :virtualbox
221
+ vm_list = ::Lab::Controllers::VirtualBoxController::config_list
222
+
223
+ vm_list.each do |item|
224
+ ## Add it to the vm list
225
+ @vms << Vm.new( {
226
+ 'vmid' => "#{item}",
227
+ 'driver' => driver_type,
228
+ 'location' => nil,
229
+ 'user' => user,
230
+ 'host' => host } )
231
+ end
232
+
233
+ else
234
+ raise TypeError, "Unsupported VM Type"
235
+ end
236
+
237
+ end
238
+
239
+ def running?(vmid)
240
+ if includes_vmid?(vmid)
241
+ return self.find_by_vmid(vmid).running?
242
+ end
243
+ return false
244
+ end
245
+ end
240
246
  end
241
247
  end
data/src/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in lab.gemspec
4
+ gemspec
data/src/README.md ADDED
@@ -0,0 +1,80 @@
1
+ This folder contains the libraries necessary to run the lab plugin, and can also be used in a standalone way to automate virtual machines.
2
+
3
+ CONCEPTS:
4
+ =========
5
+
6
+ The lab provides a clean interface to common vm functions such as start / stop / snapshot / revert and even running system commands or higher-level functions like opening a browser to a specified URL. It's designed so the different VM technologies have a similiar interface, and you can ignore the specifics of the VM tech. The majority of the functionality is implemented in the form of drivers and controllers. Drivers implement the underlying command for each vm software (such as start/stop/revert), and controllers implement the commands which apply to all vms (such as listing all running vms, or cloning a vm).
7
+
8
+ If you're interested in porting a vm software (see below), please take a look at the workstation_driver.rb and the workstation_controller.rb -- This is a simple driver / controller in the lab, and you can simply copy / modify this to implement a new driver & controller for the software.
9
+
10
+ SUPPORTED VM TECHNOLOGIES:
11
+ ==========================
12
+ NOTE: The lab libraries have only been tested with linux as a host, porting to windows is not planned at this time.
13
+
14
+ Implemented:
15
+ - workstation (Tested against 7.x)
16
+ - remote_workstation (Tested against 7.x)
17
+ - virtualbox (Tested against 4.x)
18
+ - remote_esx (VMware ESX Host Agent 4.1.0 build-348481)
19
+
20
+ Partially Implemented:
21
+ - amazon_ec2 (via fog gem)
22
+ - dynagen
23
+
24
+ Need Implementation:
25
+ - qemu
26
+ - qemudo
27
+ - others?
28
+
29
+ PLATFORM SUPPORT:
30
+ =================
31
+ You will need to have this code running on a linux box, Currently this has only been run / tested on Ubuntu 9.04 -> 10.04, though it should run on any linux with an ssh client and the dependencies below. Remote VM Hosts will need to be linux as well, though other platforms may work (untested). If you're interested in porting it to windows, please contact me (jcran).
32
+
33
+ Platform Dependencies:
34
+ - whatever vm software is necessary for the driver you're using (see SUPPORTED VM TECHNOLOGIES above)
35
+ - net/scp - the gem (net-scp). Required to copy files to/from the devices in the case that tools are not installed. Not necessary if tools are installed.
36
+ - fog - require to use the amazon_ec2 driver
37
+
38
+ STANDALONE API:
39
+ ===============
40
+ BACKGROUND:
41
+
42
+ The lab libraries add tons of useful functionality that isn't exposed through the lab plugin, such as the ability to run commands on hosts. This library can serve as an excellent base for more complex operations on a remote host as well.
43
+
44
+ USAGE:
45
+
46
+ You must first create a yaml file which describes your vm. See data/lab/test_targets.yml for an example.
47
+ <pre>
48
+ require 'vm_controller'
49
+ vm_controller = ::Lab::Controllers::VmController.new(YAML.load_file(lab_def))
50
+ vm_controller['vm1'].start
51
+ vm_controller['vm1'].snapshot("clean")
52
+ vm_controller['vm1'].run_command("rm /etc/resolv.conf")
53
+ vm_controller['vm1'].open_uri("http://autopwn:8080")
54
+ vm_controller['vm1'].revert("clean")
55
+ vm_controller['vm1'].revert("clean")
56
+ </pre>
57
+ METASPLOIT MSFCONSOLE LAB PLUGIN:
58
+ =================================
59
+
60
+ BACKGROUND:
61
+
62
+ The lab plugin for msfconsole adds a number of commands which may be useful if you're interested in automating remote hosts with rc scripts, or if you need to control targets / support systems while utilizing the metasploit console. A potential use case is testing an IPS / IDS, and resetting the target after running each exploit.
63
+
64
+ USAGE:
65
+
66
+ Here's some example usage for the lab plugin.
67
+ <pre>
68
+ msf> load lab // Loads the lab plugin
69
+ msf> lab_load <path_to_lab_file> // Loads from a lab configuration file. See data/lab/test_targets.yml for an example
70
+ msf> lab_load_dir workstation /path/to/vmx/files // Loads from a local directory.
71
+ msf> lab_load_running remote_esx root esx_server // Loads all running vms.
72
+ msf> lab_start vm1 // Start a vm which was loaded above
73
+ msf> lab_snapshot vm1 snapshot_1 // Snapshot a vm as 'snapshot_1'
74
+ msf> lab_run_command ("rm -rf /") // oops!
75
+ msf> lab_show // Show all vms that we're aware of
76
+ msf> lab_show_running // Show only running vms
77
+ msf> lab_start vm2 // Start another vm
78
+ msf> lab_suspend vm1 // Suspend a vm
79
+ msf> lab_revert all snapshot_1 // Revert all vms back to 'snapshot_1'
80
+ </pre>