dorothy2 1.0.1 → 1.0.9

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.
@@ -20,8 +20,8 @@ module Dorothy
20
20
 
21
21
  def start_sniffer(vmaddress, interface, name, pcaphome)
22
22
  Net::SSH.start(@server, @user, :password => @pass, :port =>@port) do |@ssh|
23
- # @ssh.exec "nohup sudo tcpdump -i eth0 -s 1514 -w ~/pcaps/#{name}.pcap host #{vmaddress} > blah.log 2>&1 & "
24
- @ssh.exec "nohup sudo tcpdump -i #{interface} -s 1514 -w #{pcaphome}/#{name}.pcap host #{vmaddress} > log.tmp 2>&1 & "
23
+ MANUAL ? not_rdp = "and not port 3389" : not_rdp = ""
24
+ @ssh.exec "nohup sudo tcpdump -i #{interface} -s 1514 -w #{pcaphome}/#{name}.pcap host #{vmaddress} #{not_rdp} 2> log.tmp & "
25
25
  t = @ssh.exec!"ps aux |grep #{vmaddress}|grep -v grep|grep -v bash"
26
26
  pid = t.split(" ")[1]
27
27
  return pid.to_i
@@ -7,7 +7,7 @@ module Dorothy
7
7
  #Dorothy module-class for managig the virtual sandboxes
8
8
  class Doro_VSM
9
9
 
10
- #ESX5 interface
10
+ #ESX vSphere5 interface
11
11
  class ESX
12
12
 
13
13
  #Creates a new instance for communicating with ESX through the vSpere5's API
@@ -32,8 +32,24 @@ module Dorothy
32
32
 
33
33
  #AUTHENTICATION
34
34
  guestauth = {:interactiveSession => false, :username => guestuser, :password => guestpass}
35
- @auth=RbVmomi::VIM::NamePasswordAuthentication(guestauth)
36
- abort if am.ValidateCredentialsInGuest(:vm => @vm, :auth => @auth) != nil
35
+ r = 0
36
+ begin
37
+ @auth=RbVmomi::VIM::NamePasswordAuthentication(guestauth)
38
+ abort if am.ValidateCredentialsInGuest(:vm => @vm, :auth => @auth) != nil
39
+ rescue RbVmomi::Fault => e
40
+ if e.inspect =~ /InvalidPowerState/
41
+ if r <= 5
42
+ r = r+1
43
+ LOGGER.debug "VSM", "VM busy (maybe still revertig, retrying.."
44
+ sleep 2
45
+ retry
46
+ end
47
+ LOGGER.error "VSM", "Error, can't connect to VM #{@vm[:name]}"
48
+ LOGGER.debug "VSM", e
49
+ raise "VSM Error"
50
+ end
51
+ end
52
+
37
53
  end
38
54
 
39
55
  def revert_vm
@@ -55,36 +71,61 @@ module Dorothy
55
71
 
56
72
  end
57
73
 
58
- def exec_file(filename, arguments="")
59
- filepath = "C:\\#{filename}"
60
-
61
- if File.extname(filename) == ".dll"
62
- cmd = { :programPath => "C:\\windows\\system32\\rundll32.exe", :arguments => filepath}
63
- LOGGER.info "VSM", ".:: Executing dll #{filename}"
64
-
65
- else
66
- cmd = { :programPath => filepath, :arguments => arguments }
67
- end
74
+ def exec_file(filename, program)
75
+ program["prog_args"].nil? ? args = "" : args = program["prog_args"]
76
+ args << " #{filename}"
77
+ cmd = { :programPath => program["prog_path"], :arguments => args }
78
+ pid = @pm.StartProgramInGuest(:vm => @vm , :auth => @auth, :spec => cmd )
79
+ pid.to_i
80
+ end
68
81
 
82
+ def exec_file_raw(filename, arguments="")
83
+ filepath = "C:\\#{filename}"
84
+ cmd = { :programPath => filepath, :arguments => arguments }
69
85
  pid = @pm.StartProgramInGuest(:vm => @vm , :auth => @auth, :spec => cmd )
70
86
  pid.to_i
71
87
  end
72
88
 
73
89
  def check_internet
74
- exec_file("windows\\system32\\ping.exe", "-n 1 www.google.com") #make www.google.com customizable, move to doroconf
90
+ exec_file_raw("windows\\system32\\ping.exe", "-n 1 www.google.com") #make www.google.com customizable, move to doroconf
75
91
  end
76
92
 
77
-
78
93
  def get_status(pid)
79
- p = @pm.ListProcessesInGuest(:vm => @vm , :auth => @auth, :pids => Array(pid) ).inspect
80
- status = (p =~ /exitCode=>([0-9])/ ? $1.to_i : nil )
81
- return status
94
+ p = get_running_procs(pid)
95
+ p["exitCode"]
82
96
  end
83
97
 
98
+ def get_running_procs(pid=nil, save_tofile=false, filename="#{DoroSettings.env[:home]}/etc/baseline_processes.yml")
99
+ pid = Array(pid) unless pid.nil?
100
+ @pp2 = Hash.new
101
+ procs = @pm.ListProcessesInGuest(:vm => @vm , :auth => @auth, :pids => pid )
102
+ procs.each {|pp2| @pp2.merge! Hash[pp2.pid, Hash["pname", pp2.name, "owner", pp2.owner, "cmdLine", pp2.cmdLine, "startTime", pp2.startTime, "endTime", pp2.endTime, "exitCode", pp2.exitCode]]}
103
+ if save_tofile
104
+ Util.write(filename, @pp2.to_yaml)
105
+ LOGGER.info "VSM", "Current running processes saved to #{filename}"
106
+ end
107
+ @pp2
108
+ end
109
+
110
+ def get_new_procs(current_procs, original_procs=BASELINE_PROCS)
111
+ @new_procs = Hash.new
112
+ current_procs.each_key {|pid|
113
+ @new_procs.merge!(Hash[pid, current_procs[pid]]) unless original_procs.has_key?(pid)
114
+ }
115
+ @new_procs
116
+ end
117
+
118
+ def get_files(path)
119
+ fm_files = @fm.ListFilesInGuest(:vm => @vm, :auth=> @auth, :filePath=> path).files
120
+ @files = Hash.new
121
+ fm_files.each {|file|
122
+ @files.merge!(Hash[file.path, Hash[:size, file.size, :type, file.type, :attrs, file.attributes]])
123
+ }
124
+ @files
125
+ end
84
126
 
85
127
  def screenshot
86
128
  a = @vm.CreateScreenshot_Task.wait_for_completion.split(" ")
87
- ds = @vm.datastore.find { |ds| ds.name == a[0].delete("[]")}
88
129
  screenpath = "/vmfs/volumes/" + a[0].delete("[]") + "/" + a[1]
89
130
  return screenpath
90
131
  end
@@ -1,6 +1,7 @@
1
1
  # Copyright (C) 2010-2013 marco riccardi.
2
2
  # This file is part of Dorothy - http://www.honeynet.it/
3
3
  # See the file 'LICENSE' for copying permission.
4
+ require 'fileutils'
4
5
 
5
6
  module Dorothy
6
7
 
@@ -9,7 +10,7 @@ module Dorothy
9
10
  extend self
10
11
 
11
12
  def init_home(home)
12
- puts "INIT".yellow + " Creating Directoy structure in #{home}"
13
+ puts "[INIT]".yellow + " Creating Directoy structure in #{home}"
13
14
  Dir.mkdir(home) unless Util.exists?("#{home}")
14
15
  unless Util.exists?("#{home}/opt")
15
16
  Dir.mkdir("#{home}/opt")
@@ -24,14 +25,14 @@ module Dorothy
24
25
  Dir.mkdir("#{home}/var")
25
26
  Dir.mkdir("#{home}/var/log")
26
27
  end
27
- puts "INIT".yellow + " Done"
28
+ puts "[INIT]".yellow + " Done\n\n"
28
29
  end
29
30
 
30
31
  def create
31
32
 
32
33
  puts "
33
34
  [WARNING]".red + " It seems that the Dorothy configuration file is not present,
34
- please answer to the following question in order to create it now.
35
+ please answer to the following question in order to create it now.
35
36
  "
36
37
 
37
38
  correct = false
@@ -53,16 +54,11 @@ module Dorothy
53
54
  ################################################
54
55
 
55
56
  puts "\n######### [" + " Dorothy Environment settings ".red + "] #########"
56
-
57
- puts "Please insert the home folder for dorothy [#{HOME}]"
58
- conf["env"]["home"] = (t = gets.chop).empty? ? HOME : t
57
+ puts "Please insert the home folder for dorothy [#{File.expand_path("~")}/Dorothy]"
58
+ conf["env"]["home"] = (t = gets.chop).empty? ? "#{File.expand_path("~")}/Dorothy" : t
59
59
 
60
60
  home = conf["env"]["home"]
61
61
 
62
- self.init_home(home)
63
-
64
-
65
-
66
62
  puts "The Dorothy home directory is #{home}"
67
63
 
68
64
  conf["env"]["pidfile"] = "#{home}/var/dorothy.pid"
@@ -123,11 +119,16 @@ module Dorothy
123
119
  puts "Insert the time (seconds) that the Sandbox should be run before it's reverted [60]"
124
120
  conf["sandbox"]["sleeptime"] = (t = gets.chop).empty? ? 60 : t
125
121
 
126
- puts "Insert the time (seconds) when Dorothy should take the first screenshot [1]"
127
- conf["sandbox"]["screen1time"] = (t = gets.chop).empty? ? 1 : t
122
+ puts "Insert how many screenshots do you want to take [1]"
123
+ conf["sandbox"]["num_screenshots"] = (t = gets.chop).empty? ? 1 : t.to_i
128
124
 
129
- puts "Insert the time (seconds) when Dorothy should take the second screenshot [15]"
130
- conf["sandbox"]["screen2time"] = (t = gets.chop).empty? ? 15 : t
125
+ if conf["sandbox"]["num_screenshots"] > 1
126
+ puts "Insert the time interval (seconds) between each screenshot [5] "
127
+ conf["sandbox"]["screen2time"] = (t = gets.chop).empty? ? 5 : t
128
+ end
129
+
130
+ puts "After how many seconds do you want to take the first screenshot? [1]"
131
+ conf["sandbox"]["screen1time"] = (t = gets.chop).empty? ? 1 : t
131
132
 
132
133
  ######################################################
133
134
  ###NAM
@@ -152,8 +153,8 @@ module Dorothy
152
153
  puts "SSH Port [22] :"
153
154
  conf["nam"]["port"] = (t = gets.chop).empty? ? 22 : t
154
155
 
155
- puts "Folder where to store PCAP files [~/pcaps]"
156
- conf["nam"]["pcaphome"] = (t = gets.chop).empty? ? "~/pcaps" : t
156
+ puts "Folder where to store PCAP files [/home/#{conf["nam"]["user"]}/pcaps]"
157
+ conf["nam"]["pcaphome"] = (t = gets.chop).empty? ? "/home/#{conf["nam"]["user"]}/pcaps" : t
157
158
 
158
159
  ######################################################
159
160
  ###PCAPR
@@ -161,12 +162,23 @@ module Dorothy
161
162
 
162
163
  puts "\n######### [" + " Pcapr configuration ".red + "] #########"
163
164
 
164
- puts "Host [NAM: #{conf["nam"]["host"]}]:"
165
- conf["pcapr"]["host"] = (t = gets.chop).empty? ? conf["nam"]["host"] : t
165
+ puts "Are you going to use Pcapr on this machine? [yes] WARNING: Pcapr is only compatible with Linux "
166
166
 
167
- puts "Port [8080]:"
167
+ t = gets.chop
168
+ if t.empty? || t == "y" || t == "yes"
169
+ conf["pcapr"]["local"] = true
170
+ puts "[WARNING]".yellow + " Be careful in setting Pcapr to scan #{conf["env"]["analysis_dir"]}"
171
+ conf["pcapr"]["host"] = "localhost"
172
+ else
173
+ conf["pcapr"]["local"] = false
174
+ puts "Pcapr Host [NAM: #{conf["nam"]["host"]}]:"
175
+ conf["pcapr"]["host"] = (t = gets.chop).empty? ? conf["nam"]["host"] : t
176
+ end
177
+
178
+ puts "Pcapr HTTP Port [8080]:"
168
179
  conf["pcapr"]["port"] = (t = gets.chop).empty? ? 8080 : t
169
180
 
181
+
170
182
  ######################################################
171
183
  ###VIRUS TOTAL
172
184
  ######################################################
@@ -179,11 +191,7 @@ module Dorothy
179
191
  puts "Enable test mode? In test mode dorothy will avoid to poll Virustotal [y]"
180
192
 
181
193
  t = gets.chop
182
- if t.empty? || t == "y" || t == "yes"
183
- conf["env"]["testmode"] = true
184
- else
185
- conf["env"]["testmode"] = false
186
- end
194
+ (t.empty? || t == "y" || t == "yes") ? conf["env"]["testmode"] = true : conf["env"]["testmode"] = false
187
195
 
188
196
  ##########CONF FINISHED##################
189
197
 
@@ -192,11 +200,21 @@ module Dorothy
192
200
 
193
201
  t = gets.chop
194
202
  if t.empty? || t == "y" || t == "yes"
195
- File.open("#{File.expand_path("~")}/.dorothy.yml", 'w+') {|f| f.write(conf.to_yaml) }
196
- FileUtils.ln_s("#{File.expand_path("~")}/.dorothy.yml", "#{home}/etc/dorothy.yml")
197
- correct = true
198
- puts "Configuration file has been saved in ~/.dorothy.conf and a symlink has been created in\n#{home}/etc/dorothy.yml for an easier edit. You can either modify such file directly."
199
- puts "\n######### [" + " Now you can restart dorothy, enjoy! ".yellow + "] #########"
203
+ begin
204
+ self.init_home(home)
205
+ File.open("#{File.expand_path("~")}/.dorothy.yml", 'w+') {|f| f.write(conf.to_yaml) }
206
+ FileUtils.ln_s("#{File.expand_path("~")}/.dorothy.yml", "#{home}/etc/dorothy.yml") unless Util.exists?("#{home}/etc/dorothy.yml")
207
+
208
+ #copy the default extension file to the user-defined home
209
+ FileUtils.cp("#{HOME}/etc/extensions.yml", "#{home}/etc/extensions.yml")
210
+ correct = true
211
+ puts "Configuration file has been saved in ~/.dorothy.conf and a symlink has been created in\n#{home}/etc/dorothy.yml for an easier edit."
212
+ puts "\n######### [" + " Now you can restart dorothy, enjoy! ".yellow + "] #########"
213
+ rescue => e
214
+ puts e.inspect
215
+ puts "[ERROR]".red + " Configuration aborted, please redo."
216
+ FileUtils.rm("#{home}/etc/dorothy.yml")
217
+ end
200
218
  else
201
219
  puts "Please reinsert the info"
202
220
  correct = false
@@ -206,6 +224,7 @@ module Dorothy
206
224
 
207
225
  end
208
226
 
227
+ #Creates the sandbox configuration file
209
228
  def create_sandbox(sboxfile)
210
229
 
211
230
  correct = false
@@ -90,7 +90,9 @@ module Dorothy
90
90
  elsif value =~ /currval/
91
91
  value1 = value
92
92
  else
93
- value1 = "'#{value}'"
93
+ #if present, remove ""
94
+ value.gsub! /^"|"$/, '' if values.class.inspect == "String"
95
+ value1 = "E'#{value}'"
94
96
  end
95
97
  if n == values.size
96
98
  @sqlstring << value1
@@ -186,7 +188,7 @@ module Dorothy
186
188
  def find_vm
187
189
  vm = @db.exec("SELECT id, hostname, ipaddress, username, password FROM dorothy.sandboxes where is_available is true").first
188
190
  if vm.nil?
189
- LOGGER.warn "DB","At this time there are no free VM available"
191
+ LOGGER.debug "DB","At this time there are no free VM available" if VERBOSE
190
192
  return false
191
193
  else
192
194
  @db.exec("UPDATE dorothy.sandboxes set is_available = false where id = '#{vm["id"]}'")
@@ -246,8 +248,8 @@ module Dorothy
246
248
  sha = Digest::SHA2.new
247
249
  md5 = Digest::MD5.new
248
250
  @binpath = file
249
- @filename = File.basename file
250
- @extension = File.extname file
251
+ @filename = File.basename(file)
252
+ @extension = File.extname(file)[1..-1]
251
253
 
252
254
  File.open(file, 'rb') do |fh1|
253
255
  while buffer1 = fh1.read(1024)
@@ -264,14 +266,14 @@ module Dorothy
264
266
  @ctime= timetmp.strftime("%m/%d/%y %H:%M:%S")
265
267
  @type = fm.file(file)
266
268
 
267
- if @extension.empty? #no extension, trying to put the right one..
269
+ if @extension.nil? #no extension, trying to put the right one..
268
270
  case @type
269
271
  when /^PE32/ then
270
- @extension = (@type =~ /DLL/ ? ".dll" : ".exe")
272
+ @extension = (@type =~ /DLL/ ? "dll" : "exe")
271
273
  when /^MS-DOS/ then
272
- @extension = ".bat"
274
+ @extension = "bat"
273
275
  when /^HTML/ then
274
- @extension = ".html"
276
+ @extension = "html"
275
277
  else
276
278
  @extension = nil
277
279
  end
@@ -1,3 +1,3 @@
1
- module Dorothy2
2
- VERSION = "1.0.1"
1
+ module Dorothy
2
+ VERSION = "1.0.9"
3
3
  end
@@ -0,0 +1,19 @@
1
+ CREATE TABLE dorothy.sys_procs
2
+ (
3
+ analysis_id integer NOT NULL,
4
+ pid integer NOT NULL,
5
+ "name" character varying,
6
+ "owner" character varying,
7
+ "cmdLine" character varying,
8
+ "startTime" timestamp without time zone,
9
+ "endTime" timestamp without time zone,
10
+ "exitCode" integer,
11
+ CONSTRAINT "procs-pk" PRIMARY KEY (analysis_id, pid),
12
+ CONSTRAINT "anal_id-fk" FOREIGN KEY (analysis_id)
13
+ REFERENCES dorothy.analyses (id) MATCH SIMPLE
14
+ ON UPDATE NO ACTION ON DELETE NO ACTION
15
+ )
16
+ WITH (
17
+ OIDS=FALSE
18
+ );
19
+ ALTER TABLE dorothy.sys_procs OWNER TO postgres;
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dorothy2
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 9
10
+ version: 1.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - marco riccardi
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-07-01 00:00:00 Z
18
+ date: 2013-08-11 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: net-scp
@@ -253,8 +253,8 @@ executables:
253
253
  - dparser_stop
254
254
  extensions: []
255
255
 
256
- extra_rdoc_files: []
257
-
256
+ extra_rdoc_files:
257
+ - README.md
258
258
  files:
259
259
  - .gitignore
260
260
  - Gemfile
@@ -262,6 +262,7 @@ files:
262
262
  - README.md
263
263
  - Rakefile
264
264
  - TODO
265
+ - UPDATE
265
266
  - bin/dorothy_start
266
267
  - bin/dorothy_stop
267
268
  - bin/dparser_start
@@ -269,6 +270,7 @@ files:
269
270
  - dorothy2.gemspec
270
271
  - etc/ddl/dorothive.ddl
271
272
  - etc/dorothy copy.yml.example
273
+ - etc/extensions.yml
272
274
  - etc/sandboxes.yml.example
273
275
  - etc/sources.yml.example
274
276
  - lib/doroParser.rb
@@ -315,12 +317,13 @@ files:
315
317
  - share/img/Dorothy-Basic.pdf
316
318
  - share/img/Setup-Advanced.pdf
317
319
  - share/img/The_big_picture.pdf
320
+ - share/update-dorothive.sql
318
321
  - test/tc_dorothy_full.rb
319
322
  - var/log/parser.log
320
323
  homepage: https://github.com/m4rco-/dorothy2
321
324
  licenses: []
322
325
 
323
- post_install_message:
326
+ post_install_message: If you are upgrating from a previous version, read the UPDATE file!
324
327
  rdoc_options: []
325
328
 
326
329
  require_paths: