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.
- data/README.md +13 -4
- data/TODO +12 -6
- data/UPDATE +21 -0
- data/bin/dorothy_start +51 -7
- data/bin/dparser_start +11 -7
- data/dorothy2.gemspec +3 -1
- data/etc/ddl/dorothive.ddl +26 -0
- data/etc/extensions.yml +34 -0
- data/lib/doroParser.rb +1 -1
- data/lib/dorothy2.rb +211 -103
- data/lib/dorothy2/NAM.rb +2 -2
- data/lib/dorothy2/VSM.rb +60 -19
- data/lib/dorothy2/do-init.rb +48 -29
- data/lib/dorothy2/do-utils.rb +10 -8
- data/lib/dorothy2/version.rb +2 -2
- data/share/update-dorothive.sql +19 -0
- metadata +10 -7
data/lib/dorothy2/NAM.rb
CHANGED
@@ -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
|
-
|
24
|
-
@ssh.exec "nohup sudo tcpdump -i #{interface} -s 1514 -w #{pcaphome}/#{name}.pcap host #{vmaddress} > log.tmp
|
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
|
data/lib/dorothy2/VSM.rb
CHANGED
@@ -7,7 +7,7 @@ module Dorothy
|
|
7
7
|
#Dorothy module-class for managig the virtual sandboxes
|
8
8
|
class Doro_VSM
|
9
9
|
|
10
|
-
#
|
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
|
-
|
36
|
-
|
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,
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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 =
|
80
|
-
|
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
|
data/lib/dorothy2/do-init.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
127
|
-
conf["sandbox"]["
|
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
|
-
|
130
|
-
|
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 [
|
156
|
-
conf["nam"]["pcaphome"] = (t = gets.chop).empty? ? "
|
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 "
|
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
|
-
|
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
|
-
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
data/lib/dorothy2/do-utils.rb
CHANGED
@@ -90,7 +90,9 @@ module Dorothy
|
|
90
90
|
elsif value =~ /currval/
|
91
91
|
value1 = value
|
92
92
|
else
|
93
|
-
|
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.
|
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
|
250
|
-
@extension = File.extname
|
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.
|
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/ ? "
|
272
|
+
@extension = (@type =~ /DLL/ ? "dll" : "exe")
|
271
273
|
when /^MS-DOS/ then
|
272
|
-
@extension = "
|
274
|
+
@extension = "bat"
|
273
275
|
when /^HTML/ then
|
274
|
-
@extension = "
|
276
|
+
@extension = "html"
|
275
277
|
else
|
276
278
|
@extension = nil
|
277
279
|
end
|
data/lib/dorothy2/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module
|
2
|
-
VERSION = "1.0.
|
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:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
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-
|
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:
|