dorothy2 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG +39 -14
- data/README.md +80 -62
- data/UPDATE +6 -14
- data/bin/dorothy2 +472 -0
- data/dorothy2.gemspec +22 -16
- data/etc/ddl/dorothive.ddl +619 -373
- data/etc/sources.yml.example +27 -2
- data/lib/doroGUI.rb +232 -0
- data/lib/doroParser.rb +34 -78
- data/lib/dorothy2.rb +288 -248
- data/lib/dorothy2/BFM.rb +114 -61
- data/lib/dorothy2/DEM.rb +3 -1
- data/lib/dorothy2/NAM.rb +2 -2
- data/lib/dorothy2/Settings.rb +2 -1
- data/lib/dorothy2/VSM.rb +2 -1
- data/lib/dorothy2/deep_symbolize.rb +2 -7
- data/lib/dorothy2/do-init.rb +286 -19
- data/lib/dorothy2/do-logger.rb +1 -1
- data/lib/dorothy2/do-utils.rb +382 -33
- data/lib/dorothy2/version.rb +1 -1
- data/lib/dorothy2/vtotal.rb +30 -20
- data/lib/mu/xtractr.rb +11 -11
- data/lib/mu/xtractr/stream.rb +1 -1
- data/lib/www/public/reset.css +153 -0
- data/lib/www/public/style.css +65 -0
- data/lib/www/views/analyses.erb +28 -0
- data/lib/www/views/email.erb +63 -0
- data/lib/www/views/flows.erb +30 -0
- data/lib/www/views/layout.erb +27 -0
- data/lib/www/views/profile.erb +49 -0
- data/lib/www/views/queue.erb +28 -0
- data/lib/www/views/resume.erb +135 -0
- data/lib/www/views/resume.erb~ +88 -0
- data/lib/www/views/samples.erb +20 -0
- data/lib/www/views/upload.erb +154 -0
- data/share/img/The_big_picture.pdf +0 -0
- data/test/tc_dorothy_full.rb +3 -0
- metadata +169 -70
- data/TODO +0 -27
- data/bin/dorothy_start +0 -225
- data/bin/dorothy_stop +0 -28
- data/bin/dparser_start +0 -94
- data/bin/dparser_stop +0 -31
- data/etc/dorothy copy.yml.example +0 -39
- data/etc/extensions.yml +0 -41
- data/share/update-dorothive.sql +0 -19
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OGViZGY5NjEyNDVlZmY1MWZlYjhlZGRjZmE5YTQ5ZDI1NmU3MGRlNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjgyMDY3MDBmNDU5N2M0MjI2MzdlN2NmMzBiMzg1MzAwODVkYzIzMA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmI0ODkxZDM4OTAyNzY4YWEyNmFlOTg2MDYwNmI4OGM3YjJlYjA0MThhMzc1
|
10
|
+
MDNkNWQwNDUwNmM1MzRjYjk5Nzc4MjYwZWQwZjcyNmFkYWVkMjVmNDkzN2E0
|
11
|
+
YzM1NGNlNWY1OTA1NGFmMjY4ZjMxNzk3NTc2OTQ4MTY3ZGFkYmI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTkxZWY4OTQzOTExOTk1YWI5NjNiMDcxOGM3MjQyNjg1ZTAzMTcxN2FhNTg4
|
14
|
+
ZGJiYTQwMDkwMTI5ODc4ZmVhZjZhNGIzMDI5MTU0YjI5MDI5M2UzM2I3ODlk
|
15
|
+
YWMwZWI1MTg4MDc3ZjY4ZmY2ZmJiYzI0OTYzYjllMzZlYTdjMGQ=
|
data/CHANGELOG
CHANGED
@@ -1,14 +1,39 @@
|
|
1
|
-
Dorothy
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
#Dorothy 2.0
|
2
|
+
############
|
3
|
+
Dorothive
|
4
|
+
Schema expanded and fixed for sinatra/rails application
|
5
|
+
|
6
|
+
Binaries
|
7
|
+
Remove unnecessary binaries (_start, _stop) now everything can be done with dorothy2.
|
8
|
+
Added more arguments for controlling the modules, see the help -h
|
9
|
+
|
10
|
+
Core
|
11
|
+
Introduction of an analysis queue
|
12
|
+
Samples can be submitted through the WebGUI now
|
13
|
+
Samples can be retrieved from email accounts
|
14
|
+
Modules (analysed, BFM, DEM and WGUI) can now be executed alone
|
15
|
+
Introduced the use of analysis profiles
|
16
|
+
|
17
|
+
|
18
|
+
WGUI
|
19
|
+
Added a dummy sinatra webgui
|
20
|
+
Interactive reporting
|
21
|
+
PCAP data analysis
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
#Dorothy 1.2.0
|
27
|
+
###############
|
28
|
+
dorothy.yml
|
29
|
+
added sandbox’s network (needed by DEM)
|
30
|
+
added GeoIP.ISP
|
31
|
+
|
32
|
+
fix dparser
|
33
|
+
iconv deprecated
|
34
|
+
added GeoIP.ISP
|
35
|
+
removed lot of unused classes in DEM
|
36
|
+
|
37
|
+
dorothive
|
38
|
+
samples.hash -> sample.sha256
|
39
|
+
traffic_dumps.hash -> traffic_dumps.sha256
|
data/README.md
CHANGED
@@ -5,47 +5,71 @@ A malware/botnet analysis framework written in Ruby.
|
|
5
5
|
For a perfect view of this document (images and links), open it through the project's [code repository](https://github.com/m4rco-/dorothy2/blob/master/README.md).
|
6
6
|
|
7
7
|
For any issue, use our [Redmine](https://redmine.honeynet.it/projects/dorothy2)
|
8
|
+
|
9
|
+
A wiki page for dorothy2 is under construction. Please take a look at [it](https://redmine.honeynet.it/projects/dorothy2/wiki).
|
10
|
+
|
8
11
|
##Introduction
|
9
12
|
|
10
|
-
Dorothy2 is a framework created for
|
11
|
-
|
12
|
-
|
13
|
+
Dorothy2 is a framework created for suspicious binary analysis.
|
14
|
+
It’s main strengths are a very flexible modular environment, and an interactive investigation framework with a particular care of the network analysis.
|
15
|
+
Additionally, it is able to recognise new spawned processes by comparing them with a previously created baseline.
|
16
|
+
Static binary analysis and an improved system behaviour analysis will be shortly introduced in the next versions.
|
17
|
+
Dorothy2 analyses binaries by the use of pre-configured _analysis profiles_. An analysis profile is composed by the following elements:
|
18
|
+
|
19
|
+
* A certain sandbox OS type
|
20
|
+
* A certain sandbox OS version
|
21
|
+
* A certain sandbox OS language
|
22
|
+
* A fixed analysis timeout (how long to wait before reverting the VM)
|
23
|
+
* The number of screenshots requested (and the delay between them)
|
24
|
+
* A list of the supported extensions, and how the guest OS should execute them
|
25
|
+
|
26
|
+
The use of profiles gives the researcher the possibility to run analysis on a set of binaries by using different environments. As it is known, some malwares are configured to run only in specific environment. A CSIRT, might use them to test suspicious malwares only against an environment that reflects the one of its customers.
|
27
|
+
Sources can also be configured to be automatically analysed by certain profiles (e.g. use Profile_Windows_30sc for all the binaries retrieved by Kippo_source).
|
28
|
+
|
29
|
+
|
30
|
+
Dorothy2 is a continuation of my Bachelor degree's final project ([Dorothy: inside the Storm](https://www.honeynet.it/wp-content/uploads/Dorothy/The_Dorothy_Project.pdf) ) that I presented on Feb 2009. More information about the whole project can be found on the Italian Honeyproject [website](http://www.honeynet.it).
|
13
31
|
|
14
|
-
Dorothy2 is a continuation of my Bachelor degree's final project ([Dorothy: inside the Storm](https://www.honeynet.it/wp-content/uploads/Dorothy/The_Dorothy_Project.pdf) ) that I presented on Feb 2009.
|
15
|
-
The main framework's structure remained almost the same, and it has been fully detailed in my degree's final project or in this short [paper](http://www.honeynet.it/wp-content/uploads/Dorothy/EC2ND-Dorothy.pdf). More information about the whole project can be found on the Italian Honeyproject [website](http://www.honeynet.it).
|
16
32
|
|
33
|
+
The framework is mainly composed by five modules that can be even executed separately.
|
34
|
+
The following picture gives an overview of the current modules and how they are connected each others.
|
35
|
+
>![dorothy.modules](http://www.honeynet.it/wp-content/uploads/dorothy2-structure.jpg)
|
17
36
|
|
18
|
-
The
|
37
|
+
* The Binary Fetcher Module (BFM)
|
19
38
|
|
20
|
-
|
39
|
+
In charge of retrieving the binaries from the configured sources. Currently a “binary source” can be system folder, an email-box, or a host reachable by ssh. Once the binaries have been retrieved, the BFM will populate the analysis queue.
|
21
40
|
|
22
|
-
|
41
|
+
* The Dorothy analysis engine
|
23
42
|
|
24
|
-
|
43
|
+
In charge of analysing the queue by executing the scheduled binaries into a sandbox, and then storing the generated network traffic and its screenshots into the analysis folder (moreover populating Dorothive with the basic information of the file, and CouchDB with the network pcaps).
|
44
|
+
|
45
|
+
* The (network) Data Extraction Module (old dparser)
|
25
46
|
|
26
47
|
In charge of dissecting the pcaps file, and storing the most relevant information (flows data, GeoIP info, etc) into Dorothive. In addition, it extracts all the files downloaded by the sandbox through HTTP/HTTPS and store them into the binary file's analysis folder.
|
27
48
|
|
28
|
-
* The
|
49
|
+
* The (dummy) Webgui
|
50
|
+
|
51
|
+
A dummy Sinatra application which gives an interactive overview on all the acquired data. WARNING: this module is intended to be executed in an controlled environment. The author strongly discourage to expose it on the Internet.
|
29
52
|
|
30
|
-
(Working in progress) A rails application which allows to have an interactive overview on all the acquired data. For a first glance on Andrea's first PoC take a look [this](http://youtu.be/W4DdMYPp4Ws) video (commented in Italian).
|
31
53
|
|
32
54
|
* The Java Dorothy Drone (Mainly coded by Patrizia Martemucci and Domenico Chiarito, but not part of this gem and not publicly available.)
|
33
55
|
|
34
56
|
Our botnet infiltration module, refers to this [ppt](https://www.honeynet.it/wp-content/uploads/Presentations/JDrone.pptx) presentation for an overview.
|
35
57
|
|
36
|
-
The first
|
58
|
+
The first four modules are publicly released under GPL 3 license as tribute to the the [Honeynet Project Alliance](http://www.honeynet.org).
|
37
59
|
All the information generated by the framework - i.e. binary info, timestamps, dissected network analysis - are stored into a postgres DB (Dorothive) in order to be used for further analysis.
|
38
60
|
A no-SQL database (CouchDB) is also used to mass store all the traffic dumps thanks to the [pcapr/xtractr](https://code.google.com/p/pcapr/wiki/Xtractr) technology.
|
39
61
|
|
40
62
|
I started to code this project in late 2009 while learning Ruby at the same time. Since then, I´ve been changing/improving it as long as my Ruby coding skills were improving. Because of that, you may find some parts of code not-really-tidy :)
|
41
63
|
|
64
|
+
|
65
|
+
|
42
66
|
##Requirements
|
43
67
|
|
44
68
|
>WARNING:
|
45
|
-
The current version of Dorothy only
|
69
|
+
The current version of Dorothy only utilises VMWare ESX5 as its Virtual Sandbox Module (VSM). Thus, the free version of ESXi is not supported due to its limitations in using the
|
46
70
|
vSphere 5 API.
|
47
|
-
However, the overall framework could be easily
|
48
|
-
very [modular](http://www.honeynet.it/wp-content/uploads/The_big_picture.pdf),and any
|
71
|
+
However, the overall framework could be easily customised in order to use another virtualization engine. Dorothy2 is
|
72
|
+
very [modular](http://www.honeynet.it/wp-content/uploads/The_big_picture.pdf),and any customisation or modification is very welcome.
|
49
73
|
|
50
74
|
Dorothy needs the following software (not expressly in the same host) in order to be executed:
|
51
75
|
|
@@ -230,65 +254,58 @@ Finally, check out the file extensions.yml within the /etc folder: it instructs
|
|
230
254
|
|
231
255
|
### Dorothy usage:
|
232
256
|
|
233
|
-
|
257
|
+
Usage:
|
258
|
+
dorothy2 [options]
|
234
259
|
where [options] are:
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
260
|
+
--Version, -V: Print the current version.
|
261
|
+
--verbose, -v: Enable verbose mode
|
262
|
+
--infoflow, -i: Print the analysis flow
|
263
|
+
--baseline, -b <s>: Create a new process baseline
|
264
|
+
--source, -s <s>: Choose a source (from the ones defined in etc/sources.yml)
|
265
|
+
--CreateSource, -C: Create new source file
|
266
|
+
--daemon, -d <s>: (start|stop) Execute/kill the selected module (-W, -B, -A) in backround. If no modules are specified, it will exec/kill all of them.
|
267
|
+
--debug, -e: Add extensive log trails
|
268
|
+
--manual, -m: Start everything, copy the file, and wait for me.
|
269
|
+
--SandboxUpdate, -S: Update Dorothive with the new Sandbox file
|
270
|
+
--DorothiveInit, -D <s>: (RE)Install the Dorothy Database (Dorothive)
|
271
|
+
--queue, -q: Show the analysis queue
|
272
|
+
--Analyser, -A: Execute only the Analyser Module (will analalyse only the current queue)
|
273
|
+
--BFM, -B: Execute only the Binary Fetcher Module (BFM)
|
274
|
+
--DEM, -E: Execute only the network Data Extation Module (DEM) aka doroParser
|
275
|
+
--WebGUI, -W: Execute the WebGUI Module (WGUI)
|
276
|
+
--help, -h: Show this message
|
250
277
|
|
251
|
-
After the execution, if everything went fine, you will find the analysis output (screens/pcap/bin) into the analysis folder that you have configured e.g. dorothy/opt/analyzed/[:digit:]/
|
252
|
-
Other information will be stored into Dorothive.
|
253
|
-
If executed in daemon mode, Dorothy2 will poll the datasources every X seconds (where X is defined by the "dtimeout:" field in the configuration file) looking for new binaries.
|
254
278
|
|
255
|
-
|
279
|
+
>Example
|
256
280
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
281
|
+
> $dorothy2 -v -d start
|
282
|
+
> This will execute all the modules in background
|
283
|
+
|
284
|
+
The first time dorothy2 is executed it will drive the user into configuring the analysis environment, more specifically the user will get through the following configuration steps:
|
285
|
+
|
286
|
+
* Configuring the general env variables ($home/.dorothy.yml)
|
287
|
+
* Configuring the BFM sources ($dorothyhome/etc/sources.yml)
|
288
|
+
* Configuring the sandboxes ($dorothyhome/etc/sandboxes.yml)
|
289
|
+
* Configuring the analysis profiles (auto-filled) ($dorothyhome/etc/profiles.yml)
|
290
|
+
|
291
|
+
Once the configuration step will be performed, the user will be always able to edit the configuration files at anytime.
|
263
292
|
|
264
|
-
>Example
|
265
|
-
>
|
266
|
-
$dparser_start -d start
|
267
|
-
$dparser_stop
|
268
293
|
|
269
294
|
|
270
|
-
After the execution, if everything went fine, doroParser will store all the donwloaded files into the binary's analysis folder e.g. dorothy/opt/analyzed/[:digit:]/downloads
|
271
|
-
Other information -i.e. Network data- will be stored into Dorothive.
|
272
|
-
If executed in daemon mode, DoroParser will poll the database every X seconds (where X is defined by the "dtimeout:" field in the configuration file) looking for new pcaps that has been inserted.
|
273
295
|
|
274
296
|
###6. Debugging problems
|
275
297
|
|
276
|
-
I
|
298
|
+
I do recognise that setting up Dorothy is not the easiest task of the world.
|
277
299
|
By considering that the whole framework consists in the union of several 3rd pats, it is very likely that one of them will fail during the process.
|
278
300
|
Below there are some tips about how understand the root-cause of your crash.
|
279
301
|
|
280
|
-
1.
|
281
|
-
|
282
|
-
>Example
|
283
|
-
|
284
|
-
$cd /opt/local/lib/ruby/gems/1.9.3/gems/dorothy2-0.0.1/test/
|
285
|
-
$ruby tc_dorothy_full.rb
|
302
|
+
1. Set the verbose flag (-v) while executing dorothy, or the —debug flag for additional debugging trails.
|
286
303
|
|
287
|
-
|
304
|
+
> $dorothy_start -v -d -s malwarefolder
|
288
305
|
|
289
|
-
|
306
|
+
2. If any error occours, go to our Redmine and raise a [bug-ticket](https://redmine.honeynet.it/projects/dorothy2/)!
|
290
307
|
|
291
|
-
3.
|
308
|
+
3. Write at dorothy2 at googlegroups.com
|
292
309
|
|
293
310
|
------------------------------------------
|
294
311
|
|
@@ -296,13 +313,12 @@ Below there are some tips about how understand the root-cause of your crash.
|
|
296
313
|
|
297
314
|
Thanks to all the people who have contributed in making the Dorothy2 project up&running:
|
298
315
|
|
299
|
-
* Marco C. (
|
316
|
+
* Marco C. (Research)
|
300
317
|
* Davide C. (Dorothive)
|
301
|
-
*
|
318
|
+
* Federico S. - Calogero L. (Infrastructure)
|
302
319
|
* Domenico C. - Patrizia P. (Dorothive/JDrone)
|
303
320
|
* [All](https://www.honeynet.it/research) the graduating students from [UniMI](http://cdlonline.di.unimi.it/) who have contributed.
|
304
321
|
* Sabrina P. (our students "headhunter" :)
|
305
|
-
* Jorge C. and Nelson M. (betatesting/first release feedbacks)
|
306
322
|
|
307
323
|
## Contributing
|
308
324
|
|
@@ -315,6 +331,8 @@ Thanks to all the people who have contributed in making the Dorothy2 project up&
|
|
315
331
|
Every contribution is more than welcome!
|
316
332
|
For any help, please don't hesitate in contacting us at :
|
317
333
|
info at honeynet.it
|
334
|
+
or through our ML:
|
335
|
+
dorothy2 at googlegroups.com
|
318
336
|
|
319
337
|
## License
|
320
338
|
|
@@ -326,4 +344,4 @@ following GNU General Public License version 3.
|
|
326
344
|
|
327
345
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
328
346
|
Everyone is permitted to copy and distribute verbatim copies
|
329
|
-
of this license document, but changing it is not allowed.
|
347
|
+
of this license document, but changing it is not allowed.
|
data/UPDATE
CHANGED
@@ -1,19 +1,11 @@
|
|
1
1
|
#######################################
|
2
|
-
#Updating from Dorothy 1.
|
2
|
+
#Updating from Dorothy 1.x to >= 2.0.0##
|
3
3
|
#######################################
|
4
4
|
|
5
|
-
Dorothy
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
And recreate it by restarting Dorothy. You will see that the init script will ask you more question than before.
|
11
|
-
|
12
|
-
b) The last version of Dorothy modified the dorothive schema in order to let dorothive compatible with Sinatra and Rails.
|
13
|
-
The columns modified are the following:
|
14
|
-
samples.hash -> sample.sha256
|
15
|
-
traffic_dumps.hash -> traffic_dumps.sha256
|
16
|
-
You can modify them manually if you have already a previous Dorothy version up and running, or drop the database and recreate it (-D) using the updated .ddl .
|
17
|
-
|
5
|
+
Dorothy 2.0.0 introduces several features that improve the overall framework.
|
6
|
+
As it is a major update (since 1.2.0), it is not compatible this previous versions, thus it is highly recommended to redo
|
7
|
+
all the installation procedure. If you have been using Dorothy for a while and you have its DB full of precious data that you
|
8
|
+
like to keep on the newer version, please drop me an email and we'll try to find a solution. Keep in mind that also the
|
9
|
+
Dorothive schema has changed, thus a you should create a new DB for this dorothy version.
|
18
10
|
|
19
11
|
|
data/bin/dorothy2
ADDED
@@ -0,0 +1,472 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Copyright (C) 2010-2013 marco riccardi.
|
4
|
+
# This file is part of Dorothy - http://www.honeynet.it/
|
5
|
+
# See the file 'LICENSE' for copying permission.
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'trollop'
|
9
|
+
require 'dorothy2' #comment for testing/developmnet
|
10
|
+
require 'doroParser'
|
11
|
+
|
12
|
+
#load '../lib/dorothy2.rb' #uncomment for testing/developmnet
|
13
|
+
#load '../lib/doroParser.rb'
|
14
|
+
|
15
|
+
|
16
|
+
include Dorothy
|
17
|
+
include DoroParser
|
18
|
+
|
19
|
+
def start_wgui
|
20
|
+
DoroGUI.run!(
|
21
|
+
:environment => DoroSettings.wgui[:environment],
|
22
|
+
:bind => DoroSettings.wgui[:host],
|
23
|
+
:port => DoroSettings.wgui[:port])
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def doro_forker(dmodule)
|
28
|
+
fork do
|
29
|
+
|
30
|
+
unless Util.check_pid_file(DoroSettings.env[:pidfiles] + "/#{dmodule}.pid")
|
31
|
+
|
32
|
+
puts "[" + "+".red + "] " + "[#{dmodule.upcase}]".yellow + " Going in backround with pid #{Process.pid}"
|
33
|
+
Util.create_pid_file(DoroSettings.env[:pidfiles] + "/#{dmodule}.pid", Process.pid)
|
34
|
+
|
35
|
+
case dmodule
|
36
|
+
when 'webgui'
|
37
|
+
puts "[" + "+".red + "] " + "[#{dmodule.upcase}]".yellow + " Launching Web interface at http://#{DoroSettings.wgui[:host]}:#{DoroSettings.wgui[:port]}"
|
38
|
+
require File.dirname(__FILE__) + '/../lib/doroGUI'
|
39
|
+
puts "[" + "+".red + "] " + "[#{dmodule.upcase}]".yellow + " Logging at #{DoroSettings.wgui[:logfile]}" if DEBUG
|
40
|
+
|
41
|
+
STDOUT.reopen DoroSettings.wgui[:logfile]
|
42
|
+
STDERR.reopen DoroSettings.wgui[:logfile]
|
43
|
+
start_wgui
|
44
|
+
when 'bfm'
|
45
|
+
STDOUT.reopen DoroSettings.env[:logfile]
|
46
|
+
STDERR.reopen DoroSettings.env[:logfile]
|
47
|
+
DorothyFetcher.loader(@selected_sources, true)
|
48
|
+
|
49
|
+
when 'analyser'
|
50
|
+
puts "[" + "+".red + "] " + "[#{dmodule.upcase}]".yellow + " Logging at #{DoroSettings.env[:logfile]}" if DEBUG
|
51
|
+
|
52
|
+
STDOUT.reopen DoroSettings.env[:logfile]
|
53
|
+
STDERR.reopen DoroSettings.env[:logfile]
|
54
|
+
Dorothy.start(true)
|
55
|
+
|
56
|
+
when 'dem'
|
57
|
+
puts "[" + "+".red + "] " + "[#{dmodule.upcase}]".yellow + " Logging at #{DoroSettings.env[:logfile_parser]}" if DEBUG
|
58
|
+
|
59
|
+
STDOUT.reopen DoroSettings.env[:logfile_parser]
|
60
|
+
STDERR.reopen DoroSettings.env[:logfile_parser]
|
61
|
+
DoroParser.start(true)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
opts = Trollop.options do
|
73
|
+
banner <<-EOS
|
74
|
+
|
75
|
+
####################################################
|
76
|
+
## ##
|
77
|
+
## The Dorothy Malware Analysis Framework 2.0 ##
|
78
|
+
## ##
|
79
|
+
####################################################
|
80
|
+
|
81
|
+
marco.riccardi@honeynet.it
|
82
|
+
www.honeynet.it/dorothy
|
83
|
+
|
84
|
+
|
85
|
+
Usage:
|
86
|
+
dorothy2 [options]
|
87
|
+
where [options] are:
|
88
|
+
EOS
|
89
|
+
|
90
|
+
opt :Version, "Print the current version."
|
91
|
+
opt :verbose, "Enable verbose mode"
|
92
|
+
opt :infoflow, "Print the analysis flow"
|
93
|
+
opt :baseline, "Create a new process baseline", :type => :string
|
94
|
+
opt :source, "Choose a source (from the ones defined in etc/sources.yml)", :type => :string
|
95
|
+
opt :CreateSource, "Create new source file"
|
96
|
+
opt :daemon, "(start|stop) Execute/kill the selected module (-W, -B, -A) in backround. If no modules are specified, it will exec/kill all of them.", :type => :string
|
97
|
+
opt :debug, "Add extensive log trails"
|
98
|
+
opt :manual, "Start everything, copy the file, and wait for me."
|
99
|
+
opt :SandboxUpdate, "Update Dorothive with the new Sandbox file"
|
100
|
+
opt :DorothiveInit, "(RE)Install the Dorothy Database (Dorothive)", :type => :string
|
101
|
+
opt :queue, "Show the analysis queue"
|
102
|
+
opt :Analyser, "Execute only the Analyser Module (will analalyse only the current queue)"
|
103
|
+
opt :BFM, "Execute only the Binary Fetcher Module (BFM)"
|
104
|
+
opt :DEM, "Execute only the network Data Extation Module (DEM) aka doroParser"
|
105
|
+
opt :WebGUI, "Execute the WebGUI Module (WGUI)"
|
106
|
+
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
print_proc = "
|
111
|
+
The Dorothy Malware Analysis Framework 2.0
|
112
|
+
---------------Execution Flow-------------
|
113
|
+
#0) Fetch new malwares
|
114
|
+
#1) Start VM
|
115
|
+
#2) Copy File to VM
|
116
|
+
#3) Start Sniffer
|
117
|
+
#4) Execute file into VM
|
118
|
+
#5) Make screenshot
|
119
|
+
#6) Wait X minutes (configure X in the conf file)
|
120
|
+
#7) Save the running processes
|
121
|
+
#8) Stop Sniffer
|
122
|
+
#9) Download Screenshot and trafficdump
|
123
|
+
#10) Compare the aquired process list with the one taken during the baseline run. Find the new spawned processes.
|
124
|
+
#11) Try to retreive malware info from VirusTotal
|
125
|
+
#12) Insert data into Dorothy-DB
|
126
|
+
------------------------------------------
|
127
|
+
"
|
128
|
+
|
129
|
+
if opts[:infoflow]
|
130
|
+
puts print_proc
|
131
|
+
exit(0)
|
132
|
+
end
|
133
|
+
|
134
|
+
if opts[:Version]
|
135
|
+
puts "Dorothy ".yellow + Dorothy::VERSION
|
136
|
+
exit(0)
|
137
|
+
end
|
138
|
+
|
139
|
+
puts "
|
140
|
+
|
141
|
+
####################################################
|
142
|
+
## ##
|
143
|
+
## The Dorothy Malware Analysis Framework 2.0 ##
|
144
|
+
## marco.riccardi@honeynet.it ##
|
145
|
+
####################################################
|
146
|
+
|
147
|
+
"
|
148
|
+
|
149
|
+
#VARS
|
150
|
+
HOME = File.expand_path("..",File.dirname(__FILE__))
|
151
|
+
VERBOSE = (opts[:verbose] ? true : false)
|
152
|
+
MANUAL = (opts[:manual] ? true : false)
|
153
|
+
DEBUG = (opts[:debug] ? true : false)
|
154
|
+
|
155
|
+
|
156
|
+
|
157
|
+
modules2daemonise = []
|
158
|
+
|
159
|
+
|
160
|
+
#DEFAULT CONF FILES
|
161
|
+
#conf = HOME + '/etc/dorothy.yml'
|
162
|
+
|
163
|
+
conf = "#{File.expand_path("~")}/.dorothy.yml"
|
164
|
+
|
165
|
+
|
166
|
+
#LOAD ENV
|
167
|
+
if Util.exists?(conf)
|
168
|
+
DoroSettings.load!(conf)
|
169
|
+
else
|
170
|
+
DoroConfig.create
|
171
|
+
exit(0)
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
home = DoroSettings.env[:home]
|
177
|
+
sfile = home + '/etc/sources.yml'
|
178
|
+
sboxfile = home + '/etc/sandboxes.yml'
|
179
|
+
profiles = home + '/etc/profiles.yml'
|
180
|
+
|
181
|
+
|
182
|
+
case opts[:daemon]
|
183
|
+
when "start" then
|
184
|
+
if MANUAL
|
185
|
+
"[Dorothy]".yellow + " Manual and Deamon modes can't be executed together"
|
186
|
+
exit(1)
|
187
|
+
end
|
188
|
+
|
189
|
+
daemon = true
|
190
|
+
when "stop" then
|
191
|
+
|
192
|
+
#TODO the following two line sure can be avoided somehow...
|
193
|
+
LOGGER = DoroLogger.new(DoroSettings.env[:logfile], DoroSettings.env[:logage])
|
194
|
+
LOGGER.sev_threshold = DoroSettings.env[:loglevel]
|
195
|
+
|
196
|
+
modules2stop = []
|
197
|
+
|
198
|
+
if opts[:BFM]
|
199
|
+
modules2stop.push 'bfm'
|
200
|
+
|
201
|
+
elsif opts[:Analyser]
|
202
|
+
modules2stop.push 'analyser'
|
203
|
+
|
204
|
+
elsif opts[:WebGUI]
|
205
|
+
modules2stop.push 'webgui'
|
206
|
+
|
207
|
+
elsif opts[:DEM]
|
208
|
+
modules2stop.push 'dem'
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
#if not specified, close all of them
|
213
|
+
modules2stop = %w(bfm analyser webgui dem) if modules2stop.empty?
|
214
|
+
|
215
|
+
modules2stop.each do |dmodule|
|
216
|
+
Util.stop_process(dmodule)
|
217
|
+
end
|
218
|
+
|
219
|
+
exit(0)
|
220
|
+
|
221
|
+
else
|
222
|
+
daemon = false
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
#Logging
|
227
|
+
if daemon
|
228
|
+
logout = DoroSettings.env[:logfile]
|
229
|
+
logout2= DoroSettings.env[:logfile_parser]
|
230
|
+
else
|
231
|
+
logout = logout2 = STDOUT
|
232
|
+
end
|
233
|
+
|
234
|
+
LOGGER = DoroLogger.new(logout, DoroSettings.env[:logage])
|
235
|
+
LOGGER_PARSER = DoroLogger.new(logout2, DoroSettings.env[:logage])
|
236
|
+
LOGGER.sev_threshold = LOGGER_PARSER.sev_threshold = DoroSettings.env[:loglevel]
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
#check homefolder
|
241
|
+
unless Util.exists?(home)
|
242
|
+
DoroConfig.init_home(home)
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
if opts[:baseline]
|
247
|
+
profile = Util.load_profile(opts[:baseline])
|
248
|
+
exit(1) unless profile
|
249
|
+
puts "[" + "+".red + "] " + "[Analyser]".yellow + " Creating a new process baseline."
|
250
|
+
Dorothy.run_baseline(profile)
|
251
|
+
puts "[" + "+".red + "] " + "[Analyser]".yellow + " Baseline run finished."
|
252
|
+
exit(0)
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
if opts[:DorothiveInit]
|
258
|
+
Util.init_db(opts[:DorothiveInit])
|
259
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " Database loaded, now you can restart Dorothy!"
|
260
|
+
exit(0)
|
261
|
+
end
|
262
|
+
|
263
|
+
#INIT DB Connector
|
264
|
+
begin
|
265
|
+
db = Insertdb.new
|
266
|
+
rescue => e
|
267
|
+
if e.inspect =~ /exist/
|
268
|
+
puts "[" + "+".red + "] " + "WARNING".yellow + " The database doesn't exist yet. Press Enter to load the ddl into the DB"
|
269
|
+
gets
|
270
|
+
Util.init_db(DoroSettings.dorothive[:ddl])
|
271
|
+
exit(0)
|
272
|
+
else
|
273
|
+
puts "[" + "+".red + "] " + "ERROR".red + " Can't connect to the database"
|
274
|
+
puts e
|
275
|
+
exit(0)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
|
280
|
+
if opts[:SandboxUpdate]
|
281
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " Loading #{sboxfile} into Dorothive"
|
282
|
+
DoroConfig.init_sandbox(sboxfile)
|
283
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " Done."
|
284
|
+
exit(0)
|
285
|
+
end
|
286
|
+
|
287
|
+
if opts[:CreateSource]
|
288
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " Creating a new binary source file"
|
289
|
+
DoroConfig.create_sources(sfile)
|
290
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " Done."
|
291
|
+
exit(0)
|
292
|
+
end
|
293
|
+
|
294
|
+
if opts[:queue]
|
295
|
+
db.analysis_queue_view
|
296
|
+
exit(0)
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
#check if Source file exists
|
301
|
+
unless Util.exists?(sfile)
|
302
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " A source file doesn't exist. Please fill the following info in order to create one now."
|
303
|
+
DoroConfig.create_sources(sfile)
|
304
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " A source file has been created, please restart dorothy!"
|
305
|
+
end
|
306
|
+
|
307
|
+
#check if Sandbox file exists
|
308
|
+
unless Util.exists?(sboxfile)
|
309
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " There is no sandbox configured yet. Please do it now."
|
310
|
+
DoroConfig.create_sandbox(sboxfile)
|
311
|
+
DoroConfig.init_sandbox(sboxfile)
|
312
|
+
end
|
313
|
+
|
314
|
+
#check if Profile file exists
|
315
|
+
unless Util.exists?(profiles)
|
316
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " There is no profiles configured yet. A default one is being created for you."
|
317
|
+
|
318
|
+
#We use the first sandbox as default
|
319
|
+
firts_sandbox = YAML.load_file(sboxfile).first[1]
|
320
|
+
DoroConfig.create_profiles(profiles, firts_sandbox, DoroSettings.virustotal[:vtapikey].empty?)
|
321
|
+
end
|
322
|
+
|
323
|
+
#Check DB sandbox data
|
324
|
+
if db.table_empty?("sandboxes")
|
325
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " No sandbox found in Dorothive, the DB will be filled with " + sboxfile
|
326
|
+
DoroConfig.init_sandbox(sboxfile)
|
327
|
+
end
|
328
|
+
|
329
|
+
#Check if a baseline is present for every profile specified
|
330
|
+
YAML.load_file(profiles).each_key do |profile|
|
331
|
+
profile_vars = Util.load_profile(profile)
|
332
|
+
|
333
|
+
baseline_file = "#{DoroSettings.env[:home]}/etc/#{profile_vars[0]}_baseline_procs.yml"
|
334
|
+
|
335
|
+
unless Util.exists?(baseline_file)
|
336
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " There is no process-baseline file for the #{profile} profile. Dorothy is going to create one now."
|
337
|
+
Dorothy.run_baseline(profile_vars)
|
338
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " Baseline run finished."
|
339
|
+
exit(0)
|
340
|
+
end
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
|
345
|
+
sources = YAML.load_file(sfile)
|
346
|
+
|
347
|
+
#check if Sources dir exist
|
348
|
+
sources.keys.each do |s|
|
349
|
+
unless Util.exists?("#{sources[s]["localdir"]}")
|
350
|
+
LOGGER.warn "INIT", "Warning, the source's localdir #{s} (#{sources[s]["localdir"]}) doesn't exist yet, I'm going to create it right now.."
|
351
|
+
Dir.mkdir("#{sources[s]["localdir"]}")
|
352
|
+
LOGGER.debug "INIT", "Source's localdir #{s} created."
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
#CHECK CONF CHANGES
|
357
|
+
%w(sources.yml sandboxes.yml).each do |f|
|
358
|
+
full_p = DoroSettings.env[:home] + '/etc/' + f
|
359
|
+
c_md5 = Digest::MD5.hexdigest(File.read(full_p))
|
360
|
+
o_md5 = db.find_last_conf_chksum(f)
|
361
|
+
if o_md5.nil?
|
362
|
+
puts "#{f} not presend in the database, adding"
|
363
|
+
db.insert("cfg_chk", ['default', f, c_md5, Util.get_time])
|
364
|
+
db.check_sources_modifications(sources) if f == "sources.yml"
|
365
|
+
elsif c_md5 != o_md5
|
366
|
+
puts "The version of #{f} present into the database has changed, fixing this accordingly"
|
367
|
+
db.insert("cfg_chk", ['default', f, c_md5, Util.get_time])
|
368
|
+
db.check_sources_modifications(sources) if f == "sources.yml"
|
369
|
+
DoroConfig.init_sandbox(sboxfile) if f == "sandboxes.yml"
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
db.close
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
|
378
|
+
if opts[:source]
|
379
|
+
unless sources.key?(opts[:source])
|
380
|
+
puts "[" + "+".red + "] " + "[WARNING]".red + " The selected source is not yet configured. The available sources are: "
|
381
|
+
sources.keys.each do |k|
|
382
|
+
puts "[" + "-".red + "] " + k
|
383
|
+
end
|
384
|
+
exit(0)
|
385
|
+
end
|
386
|
+
@selected_sources = sources.select {|k,v| k == opts[:source]}
|
387
|
+
end
|
388
|
+
|
389
|
+
if opts[:BFM]
|
390
|
+
if daemon
|
391
|
+
modules2daemonise.push('bfm')
|
392
|
+
else
|
393
|
+
@selected_sources ||= sources
|
394
|
+
DorothyFetcher.loader(@selected_sources)
|
395
|
+
exit(0)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
if opts[:WebGUI]
|
400
|
+
if daemon
|
401
|
+
modules2daemonise.push('webgui')
|
402
|
+
else
|
403
|
+
require File.dirname(__FILE__) + '/../lib/doroGUI'
|
404
|
+
puts "[" + "+".red + "] " + "[WGUI]".yellow + "Starting WebGUI at http://#{DoroSettings.wgui[:host]}:#{DoroSettings.wgui[:port]}"
|
405
|
+
start_wgui
|
406
|
+
exit(0)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
|
411
|
+
if opts[:Analyser]
|
412
|
+
if daemon
|
413
|
+
modules2daemonise.push('analyser')
|
414
|
+
else
|
415
|
+
puts "[" + "+".red + "] " + "[Analyser]".yellow + "Starting the analyser."
|
416
|
+
Dorothy.start(daemon)
|
417
|
+
exit(0)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
if opts[:DEM]
|
422
|
+
#check pcapr
|
423
|
+
if DoroSettings.pcapr[:local]=="true"
|
424
|
+
if system "sh -c 'type startpcapr > /dev/null 2>&1'"
|
425
|
+
pcapr_conf = "#{File.expand_path("~")}/.pcapr_local/config"
|
426
|
+
unless Util.exists?(pcapr_conf)
|
427
|
+
puts "[WARNING]".red + " Pcapr conf not found at #{File.expand_path("~")}/.pcapr_local/config "
|
428
|
+
puts "[WARNING]".red + " Although you have configured Dorothy in order to look for a *local* Pcapr instance,it seems that it is not configured yet,so please run \"startpcapr\" and configure it."
|
429
|
+
exit(1)
|
430
|
+
end
|
431
|
+
else
|
432
|
+
puts "[WARNING]".red + " Although you have configured Dorothy in order to look for a *local* Pcapr instance, it seems *NOT INSTALLED* in your system.\n\t Please install it by typing \"sudo gem install pcapr-local\. Then set Pcapr to scan #{DoroSettings.env[:analysis_dir]}"
|
433
|
+
exit(1)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
if daemon
|
438
|
+
modules2daemonise.push('dem')
|
439
|
+
else
|
440
|
+
puts "[" + "+".red + "] " + "[DEM]".yellow + "Starting the network Data Extration Module (DEM)."
|
441
|
+
DoroParser.start(daemon)
|
442
|
+
exit(0)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
begin
|
449
|
+
|
450
|
+
@selected_sources ||= sources
|
451
|
+
|
452
|
+
if daemon
|
453
|
+
modules2daemonise = %w(webgui bfm analyser dem) if modules2daemonise.empty?
|
454
|
+
|
455
|
+
modules2daemonise.each do |dmodule|
|
456
|
+
doro_forker(dmodule)
|
457
|
+
end
|
458
|
+
|
459
|
+
else
|
460
|
+
DorothyFetcher.loader(@selected_sources, daemon)
|
461
|
+
Dorothy.start(daemon)
|
462
|
+
end
|
463
|
+
|
464
|
+
rescue SignalException
|
465
|
+
LOGGER.warn "Analyser", "SIGINT".red + " Catched, exiting gracefully."
|
466
|
+
rescue => e
|
467
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " An error occurred: \n".red + e.inspect
|
468
|
+
puts "[" + "+".red + "] " + "[Dorothy]".yellow + " For more information check the logfile \n" + e.inspect if daemon
|
469
|
+
LOGGER.error "Dorothy", "An error occurred: \n" + e.inspect
|
470
|
+
LOGGER.debug "Dorothy", "#{e.inspect} --BACKTRACE: #{e.backtrace}"
|
471
|
+
LOGGER.info "Dorothy", "Dorothy has been stopped"
|
472
|
+
end
|