dawnscanner 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.ruby-version +1 -1
- data/Changelog.md +85 -9
- data/KnowledgeBase.md +206 -5
- data/README.md +25 -25
- data/Rakefile +19 -5
- data/Roadmap.md +104 -46
- data/VERSION +10 -10
- data/bin/dawn +96 -15
- data/checksum/dawnscanner-1.4.2.gem.sha1 +1 -0
- data/dawnscanner.gemspec +21 -4
- data/doc/dawn_1_5_announcement.md +66 -0
- data/doc/{codesake-dawn.yaml.sample → dawnscanner.yaml.sample} +0 -0
- data/doc/new_knowledge_base_v1.0.md +78 -0
- data/lib/dawn/core.rb +22 -28
- data/lib/dawn/engine.rb +111 -54
- data/lib/dawn/kb/basic_check.rb +3 -0
- data/lib/dawn/kb/cve_2014_3483.rb +1 -0
- data/lib/dawn/kb/cve_2015_1819.rb +34 -0
- data/lib/dawn/kb/cve_2015_4020.rb +34 -0
- data/lib/dawn/kb/gem_check.rb +43 -0
- data/lib/dawn/kb/osvdb_115654.rb +33 -0
- data/lib/dawn/kb/osvdb_116010.rb +30 -0
- data/lib/dawn/kb/osvdb_117903.rb +30 -0
- data/lib/dawn/kb/osvdb_118954.rb +5 -3
- data/lib/dawn/kb/osvdb_119878.rb +3 -3
- data/lib/dawn/kb/osvdb_120415.rb +31 -0
- data/lib/dawn/kb/osvdb_120857.rb +34 -0
- data/lib/dawn/kb/osvdb_121701.rb +30 -0
- data/lib/dawn/kb/owasp_ror_cheatsheet.rb +23 -31
- data/lib/dawn/kb/owasp_ror_cheatsheet/check_for_backup_files.rb +16 -20
- data/lib/dawn/kb/owasp_ror_cheatsheet/check_for_safe_redirect_and_forward.rb +31 -31
- data/lib/dawn/kb/owasp_ror_cheatsheet/command_injection.rb +22 -22
- data/lib/dawn/kb/owasp_ror_cheatsheet/csrf.rb +23 -23
- data/lib/dawn/kb/owasp_ror_cheatsheet/mass_assignment_in_model.rb +25 -25
- data/lib/dawn/kb/owasp_ror_cheatsheet/sensitive_files.rb +21 -21
- data/lib/dawn/kb/owasp_ror_cheatsheet/session_stored_in_database.rb +24 -24
- data/lib/dawn/kb/version_check.rb +4 -0
- data/lib/dawn/knowledge_base.rb +36 -4
- data/lib/dawn/registry.rb +43 -0
- data/lib/dawn/reporter.rb +88 -47
- data/lib/dawn/utils.rb +3 -4
- data/lib/dawn/version.rb +4 -4
- data/lib/dawnscanner.rb +4 -1
- data/spec/lib/dawn/codesake_knowledgebase_spec.rb +40 -0
- data/spec/lib/kb/cve_2014_3483_spec.rb +5 -1
- data/spec/lib/kb/cve_2015_1819_spec.rb +16 -0
- data/spec/lib/kb/cve_2015_4020_spec.rb +24 -0
- data/spec/lib/kb/osvdb_115654_spec.rb +15 -0
- data/spec/lib/kb/osvdb_116010_spec.rb +15 -0
- data/spec/lib/kb/osvdb_117903_spec.rb +23 -0
- data/spec/lib/kb/osvdb_118954_spec.rb +13 -1
- data/spec/lib/kb/osvdb_119878_spec.rb +8 -9
- data/spec/lib/kb/osvdb_120415_spec.rb +16 -0
- data/spec/lib/kb/osvdb_120857_spec.rb +32 -0
- data/spec/lib/kb/osvdb_121701_spec.rb +15 -0
- metadata +153 -12
- metadata.gz.sig +0 -0
- data/BUGS.md +0 -14
@@ -0,0 +1 @@
|
|
1
|
+
3ac33d4e0894c508d68f56ca9e76d60881a6f7ab
|
data/dawnscanner.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.summary = %q{Dawnscanner is a security source code scanner for ruby powered code. It is crafted with love to make your sinatra, padrino and ruby on rails web applications secure.}
|
13
13
|
gem.homepage = "http://dawnscanner.org"
|
14
14
|
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.license = "MIT"
|
15
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
18
|
gem.require_paths = ["lib"]
|
@@ -23,17 +24,33 @@ Gem::Specification.new do |gem|
|
|
23
24
|
|
24
25
|
gem.add_dependency 'cvss'
|
25
26
|
gem.add_dependency 'haml'
|
26
|
-
gem.add_dependency 'parser'
|
27
|
-
gem.add_dependency 'ptools'
|
28
27
|
gem.add_dependency 'ruby_parser'
|
29
28
|
gem.add_dependency 'sys-uname'
|
30
|
-
gem.add_dependency 'grit'
|
31
29
|
gem.add_dependency 'terminal-table'
|
32
30
|
gem.add_dependency 'justify'
|
33
31
|
gem.add_dependency 'logger-colors'
|
32
|
+
gem.add_dependency 'ptools'
|
33
|
+
gem.add_dependency 'sqlite3'
|
34
|
+
gem.add_dependency 'dm-sqlite-adapter'
|
35
|
+
gem.add_dependency 'data_mapper'
|
34
36
|
|
35
|
-
|
37
|
+
# Dependencies for code stats
|
38
|
+
gem.add_dependency 'code_metrics'
|
39
|
+
gem.add_dependency 'metric_fu-Saikuro'
|
40
|
+
gem.add_dependency 'flay'
|
41
|
+
gem.add_dependency 'churn'
|
42
|
+
gem.add_dependency 'flog'
|
43
|
+
gem.add_dependency 'reek'
|
44
|
+
gem.add_dependency 'cane'
|
36
45
|
|
46
|
+
# This gem is used to extract info from a git archives. This feature will be
|
47
|
+
# available in dawnscanner 2.0.0. Disabling the dependency right now.
|
48
|
+
# gem.add_dependency 'grit'
|
49
|
+
|
50
|
+
# Marked to be unused right now
|
51
|
+
# gem.add_dependency 'parser'
|
52
|
+
|
53
|
+
gem.add_development_dependency ('coveralls')
|
37
54
|
gem.add_development_dependency 'rake'
|
38
55
|
gem.add_development_dependency 'rspec'
|
39
56
|
gem.add_development_dependency('tomdoc')
|
@@ -0,0 +1,66 @@
|
|
1
|
+
## Press announcement
|
2
|
+
|
3
|
+
Today, the December 9th 2015, the fifth, and last, minor dawnscanner rubygem
|
4
|
+
version it has been released.
|
5
|
+
|
6
|
+
dawnscanner is a source code scanner designed to review your code for
|
7
|
+
security issues.
|
8
|
+
|
9
|
+
dawnscanner is able to scan your ruby standalone programs but its main usage
|
10
|
+
is to deal with web applications. It supports applications written using majors
|
11
|
+
MVC (Model View Controller) frameworks, like:
|
12
|
+
|
13
|
+
* [Ruby on Rails](http://rubyonrails.org)
|
14
|
+
* [Sinatra](http://www.sinatrarb.com)
|
15
|
+
* [Padrino](http://www.padrinorb.com)
|
16
|
+
|
17
|
+
dawnscanner version 1.5.0 has 209 security checks loaded in its knowledge
|
18
|
+
base. Most of them are CVE bulletins applying to gems or the ruby interpreter
|
19
|
+
itself. There are also some check coming from Owasp Ruby on Rails cheatsheet.
|
20
|
+
|
21
|
+
Writing safe code it's important, but sometimes security issues are introduced
|
22
|
+
by third party code your application relies on. As example, consider a SQL
|
23
|
+
Injection vulnerability introduced by Ruby on Rails framework.
|
24
|
+
|
25
|
+
Despite the effort you spend in sanitizing inputs, your web application
|
26
|
+
inherits the vulnerability suffering as well. An attacker can easily exploit it
|
27
|
+
and break into your database unless you upgrade the offended gem.
|
28
|
+
|
29
|
+
There is a comprehensive set of command line flags you can read more by issuing
|
30
|
+
```dawn --list-knowledge-base``` flag or by reading [project
|
31
|
+
README](https://github.com/codesake/codesake-dawn/raw/master/README.md) file.
|
32
|
+
|
33
|
+
The list of security checks included in version 1.5.0 can be found online at:
|
34
|
+
[http://dawnscanner.org/knowledge-base.html](http://dawnscanner.org/knowledge-base.html).
|
35
|
+
|
36
|
+
You can use [facilities provided by
|
37
|
+
github](https://github.com/thesp0nge/dawnscanner/issues) to submit bug
|
38
|
+
reports, product enhancements, new security checks you want to me to add in
|
39
|
+
future releases and even success stories.
|
40
|
+
|
41
|
+
Now it's time for you to install dawnscanner version 1.5.0 with the
|
42
|
+
following command and start reviewing your code for security issues:
|
43
|
+
|
44
|
+
```
|
45
|
+
$ gem install -P MediumSecurity dawnscanner
|
46
|
+
```
|
47
|
+
|
48
|
+
You can find the announcement on the web here: [http://dawnscanner.org/announce-codesake-dawn-v1-5-0-released.html/](http://dawnscanner.org/announce-codesake-dawn-v1-5-0-released.html/)
|
49
|
+
Enjoy it!
|
50
|
+
Paolo - paolo@dawnscanner.org
|
51
|
+
|
52
|
+
## Twitter announcement
|
53
|
+
|
54
|
+
### version 1.5.0
|
55
|
+
@dawnscanner version 1.5.0 is out. 209 security checks, SQLite3 integration, better reports and tons of bug fixes. Read the announcement here: http://dawnscanner.org/announce-codesake-dawn-v1-5-0-released.html/ #ruby #rails #sinatra #padrino #security #appsec #cyber
|
56
|
+
|
57
|
+
## Linkedin announcement
|
58
|
+
|
59
|
+
### version 1.5.0
|
60
|
+
@dawnscanner version 1.5.0 is out. Read the announcement online. dawnscanner makes security code review fun for ruby developers, it scans 209 CVE and OSVDB bulletins and future release will be able to scan custom ruby code for XSS, SQL Injections and business logic flaws. It supports Sinatra, Padrino and Ruby on Rails MVC frameworks out of the box.
|
61
|
+
|
62
|
+
$ gem install dawnscanner
|
63
|
+
$ have fun
|
64
|
+
|
65
|
+
## HN Link
|
66
|
+
## Reddit
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# The Knowledge Base
|
2
|
+
|
3
|
+
For future releases, the dawnscanner knowledge base must be improved. Now, each
|
4
|
+
new test is included in the whole binary gem, requiring the user to manually
|
5
|
+
upgrade his bundle to reflect the support of newest vulnerabilities.
|
6
|
+
|
7
|
+
This has some major drawbacks:
|
8
|
+
|
9
|
+
* people must manually check if a new dawnscanner gem is available
|
10
|
+
* upgrading a bundle, sometimes must not be possible due to dependencies
|
11
|
+
* new vulnerabilities will require KB to be upgraded very quickly. People must
|
12
|
+
upgrade daily, as their anti virus tool, but dawnscanner core should not be
|
13
|
+
forced to go at the same speed.
|
14
|
+
* upgrade must be automatic on tool startup, to avoid people being exposed to
|
15
|
+
vulnerabilities.
|
16
|
+
|
17
|
+
For such a reason, security checks must be separated from the tool core. They
|
18
|
+
must be a set of independent archives, deployed on the Internet in a digitally
|
19
|
+
encrypted and signed format.
|
20
|
+
|
21
|
+
They must have an information about dawnscanner API version it has been able to
|
22
|
+
consume it. In example, we can introduce a new option in DepedencyCheck in
|
23
|
+
dawnscanner version 1.10. Each check will contain a required version, so to be
|
24
|
+
excluded when old dawnscanner would try consuming those archives.
|
25
|
+
|
26
|
+
## Format
|
27
|
+
|
28
|
+
Now, security checks are standard ruby classes. This could have an impact in
|
29
|
+
terms of memory utilization. At the time, no benchmarks are available.
|
30
|
+
An option can be, translating check's initialize methods in YAML format,
|
31
|
+
letting the generic class DepdencyCheck, PatternMatchingCheck and friends, to
|
32
|
+
answer to the vuln? method (like today).
|
33
|
+
|
34
|
+
This can have the benefit of having 4 classes, reading YAML files, instead of
|
35
|
+
having tons of superclasses instanciating those magic 4. The core rules,
|
36
|
+
understanding if a vulnerability is present, is already in the base API. It's
|
37
|
+
just a matter of translating initialiation in YAML file and creating a method
|
38
|
+
reading the YAML file populating internal data.
|
39
|
+
|
40
|
+
Instead of YAML we can think also to sqlite db or JSON files. Latter option can
|
41
|
+
be a good idea since it's web and API friendly.
|
42
|
+
|
43
|
+
## Archives
|
44
|
+
|
45
|
+
Checks organization will be different upon the format to be chosen. In case of
|
46
|
+
YAML files, a standard directory hierachy is enough:
|
47
|
+
|
48
|
+
vulnerabilities/
|
49
|
+
kb.txt <-- where info about the archive, like version, it must be stored
|
50
|
+
third\_party\_gems/
|
51
|
+
CVE\_2013\_2103.yaml
|
52
|
+
CVE\_2013\_2104.yaml
|
53
|
+
ruby_interpreter/
|
54
|
+
CVE\_1023\_4302.yaml
|
55
|
+
misc/
|
56
|
+
CVE\_9999\_1211.yaml
|
57
|
+
|
58
|
+
In case of JSON, we can gather together vulnerabilities in files:
|
59
|
+
|
60
|
+
vulnerabilities/
|
61
|
+
third\_party\_gems_20151116_01.json
|
62
|
+
ruby\_interpreter_20151116_01.json
|
63
|
+
|
64
|
+
SQL approach would be eventually, really close to JSON one, with tables instead
|
65
|
+
of files.
|
66
|
+
|
67
|
+
## Info
|
68
|
+
|
69
|
+
Using either CVE or OSVDB identifiers as vulnerability keys is a poor choice.
|
70
|
+
This lead of duplicated vulns in knowledge base and a lot of effort in checking
|
71
|
+
if a vuln is present.
|
72
|
+
|
73
|
+
## Benchmark
|
74
|
+
|
75
|
+
Those solutions must be benchmarked
|
76
|
+
|
77
|
+
|
78
|
+
_last update: Mon Nov 16 17:38:45 CET 2015_
|
data/lib/dawn/core.rb
CHANGED
@@ -3,6 +3,16 @@ require "yaml"
|
|
3
3
|
module Dawn
|
4
4
|
class Core
|
5
5
|
|
6
|
+
def self.registry_db_folder
|
7
|
+
"#{File.join(Dir.home, 'dawnscanner', 'db')}"
|
8
|
+
end
|
9
|
+
def self.registry_db_name
|
10
|
+
"#{File.join(registry_db_folder, 'dawnscanner.db')}"
|
11
|
+
end
|
12
|
+
def self.sql_log_name
|
13
|
+
"#{File.join(registry_db_folder, 'dawnscanner-sql.log')}"
|
14
|
+
end
|
15
|
+
|
6
16
|
# TODO.20140326
|
7
17
|
# All those methods must moved from here to Util class and a
|
8
18
|
# Dawn::Core namespace must be created.
|
@@ -14,12 +24,15 @@ module Dawn
|
|
14
24
|
puts "\t$ dawn -C --json a_sinatra_webapp_directory"
|
15
25
|
puts "\t$ dawn --ascii-tabular-report my_rails_blog_ecommerce"
|
16
26
|
puts "\t$ dawn --html -F my_report.html my_rails_blog_ecommerce"
|
17
|
-
printf "\n -r, --rails\t\t\t\t\tforce dawn to consider the target a rails application"
|
18
|
-
printf "\n -s, --sinatra\t\t\t\tforce dawn to consider the target a sinatra application"
|
19
|
-
printf "\n -p, --padrino\t\t\t\tforce dawn to consider the target a padrino application"
|
20
|
-
printf "\n -G, --gem-lock\t\t\t\tforce dawn to scan only for vulnerabilities affecting dependencies in Gemfile.lock"
|
21
|
-
printf "\n -
|
27
|
+
printf "\n -r, --rails\t\t\t\t\tforce dawn to consider the target a rails application (DEPRECATED)"
|
28
|
+
printf "\n -s, --sinatra\t\t\t\tforce dawn to consider the target a sinatra application (DEPRECATED)"
|
29
|
+
printf "\n -p, --padrino\t\t\t\tforce dawn to consider the target a padrino application (DEPRECATED)"
|
30
|
+
printf "\n -G, --gem-lock\t\t\t\tforce dawn to scan only for vulnerabilities affecting dependencies in Gemfile.lock (DEPRECATED)"
|
31
|
+
printf "\n -d, --dependencies\t\t\t\tforce dawn to scan only for vulnerabilities affecting dependencies in Gemfile.lock"
|
32
|
+
printf "\n\nReporting\n"
|
33
|
+
printf "\n -a, --ascii-tabular-report\t\t\tcause dawn to format findings using tables in ascii art (DEPRECATED)"
|
22
34
|
printf "\n -j, --json\t\t\t\t\tcause dawn to format findings using json"
|
35
|
+
printf "\n -K, --console\t\t\t\t\tcause dawn to format findings using plain ascii text"
|
23
36
|
printf "\n -C, --count-only\t\t\t\tdawn will only count vulnerabilities (useful for scripts)"
|
24
37
|
printf "\n -z, --exit-on-warn\t\t\t\tdawn will return number of found vulnerabilities as exit code"
|
25
38
|
printf "\n -F, --file filename\t\t\t\ttells dawn to write output to filename"
|
@@ -35,6 +48,7 @@ module Dawn
|
|
35
48
|
printf "\n --list-knowledge-base\t\t\tlist knowledge-base content"
|
36
49
|
printf "\n --list-known-families\t\t\tlist security check families contained in dawn's knowledge base"
|
37
50
|
printf "\n --list-known-framework\t\t\tlist ruby MVC frameworks supported by dawn"
|
51
|
+
printf "\n --list-scan-registry\t\t\tlist past scan informations stored in scan registry (#{Dawn::Core.registry_db_name})"
|
38
52
|
printf "\n\nService flags\n"
|
39
53
|
printf "\n -D, --debug\t\t\t\t\tenters dawn debug mode"
|
40
54
|
printf "\n -V, --verbose\t\t\t\tthe output will be more verbose"
|
@@ -44,26 +58,6 @@ module Dawn
|
|
44
58
|
true
|
45
59
|
end
|
46
60
|
|
47
|
-
def self.dump_knowledge_base(verbose = false)
|
48
|
-
kb = Dawn::KnowledgeBase.new
|
49
|
-
lines = []
|
50
|
-
lines << "Security checks currently supported:\n"
|
51
|
-
|
52
|
-
kb.all.each do |check|
|
53
|
-
if verbose
|
54
|
-
lines << "Name: #{check.name}\tCVSS: #{check.cvss_score}\tReleased: #{check.release_date}"
|
55
|
-
lines << "Description\n#{check.message}"
|
56
|
-
lines << "Remediation\n#{check.remediation}\n\n"
|
57
|
-
else
|
58
|
-
lines << "#{check.name}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
lines << "-----\nTotal: #{kb.all.count}"
|
62
|
-
|
63
|
-
lines.empty? ? 0 : lines.compact.join("\n")
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
61
|
# guess_mvc is very close to detect_mvc despite it accepts a
|
68
62
|
# filename as input and it tries to guess the mvc framework used from the
|
69
63
|
# gems it founds in Gemfile.lock without creating an engine.
|
@@ -111,7 +105,7 @@ module Dawn
|
|
111
105
|
end
|
112
106
|
|
113
107
|
def self.find_conf(create_if_none = false)
|
114
|
-
conf_name = '
|
108
|
+
conf_name = 'dawnscanner.yaml'
|
115
109
|
path_order = [
|
116
110
|
'./',
|
117
111
|
'~/',
|
@@ -131,7 +125,7 @@ module Dawn
|
|
131
125
|
|
132
126
|
# If create_if_none flag is set to true, than I'll create a config file
|
133
127
|
# on the current directory with the default configuration.
|
134
|
-
conf = {"config"=>{:verbose=>false, :output=>"
|
128
|
+
conf = {"config"=>{:verbose=>false, :output=>"tabular", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}}
|
135
129
|
|
136
130
|
# Calculate the conf file path
|
137
131
|
conf_path = File.expand_path('~') +'/.'+conf_name
|
@@ -145,7 +139,7 @@ module Dawn
|
|
145
139
|
end
|
146
140
|
|
147
141
|
def self.read_conf(file=nil)
|
148
|
-
conf = {:verbose=>false, :output=>"
|
142
|
+
conf = {:verbose=>false, :output=>"tabular", :mvc=>"", :gemfile_scan=>false, :gemfile_name=>"", :filename=>nil, :debug=>false, :exit_on_warn => false, :enabled_checks=> Dawn::Kb::BasicCheck::ALLOWED_FAMILIES}
|
149
143
|
begin
|
150
144
|
return conf if file.nil?
|
151
145
|
file = file.chop if (not file.nil? and file.end_with? '/')
|
data/lib/dawn/engine.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# Statistics stuff
|
2
|
+
require 'code_metrics/statistics'
|
2
3
|
|
3
4
|
module Dawn
|
4
5
|
module Engine
|
@@ -20,6 +21,7 @@ module Dawn
|
|
20
21
|
attr_reader :ruby_version
|
21
22
|
|
22
23
|
attr_reader :engine_error
|
24
|
+
attr_reader :stats
|
23
25
|
|
24
26
|
attr_reader :reflected_xss
|
25
27
|
|
@@ -43,6 +45,8 @@ module Dawn
|
|
43
45
|
attr_reader :applied_checks
|
44
46
|
attr_reader :skipped_checks
|
45
47
|
|
48
|
+
attr_reader :output_dir_name
|
49
|
+
|
46
50
|
def initialize(dir=nil, name="", options={})
|
47
51
|
@name = name
|
48
52
|
@scan_start = Time.now
|
@@ -67,12 +71,17 @@ module Dawn
|
|
67
71
|
@ruby_version = get_ruby_version if dir.nil?
|
68
72
|
@gemfile_lock = options[:gemfile_name] unless options[:gemfile_name].nil?
|
69
73
|
|
70
|
-
@
|
74
|
+
@stats = gather_statistics
|
75
|
+
|
76
|
+
@views = detect_views
|
71
77
|
@controllers = detect_controllers
|
72
78
|
@models = detect_models
|
73
79
|
|
80
|
+
@output_dir_name = output_dir
|
81
|
+
|
74
82
|
if $logger.nil?
|
75
|
-
|
83
|
+
require 'logger'
|
84
|
+
$logger = Logger.new(STDOUT)
|
76
85
|
$logger.helo "dawn-engine", Dawn::VERSION
|
77
86
|
|
78
87
|
end
|
@@ -85,7 +94,7 @@ module Dawn
|
|
85
94
|
# impersonificate the engine for the mvc it was detected
|
86
95
|
debug_me "now I'm switching my name from #{@name} to #{options[:guessed_mvc][:name]}"
|
87
96
|
$logger.err "there are no connected gems... it seems Gemfile.lock parsing failed" if options[:guessed_mvc][:connected_gems].empty?
|
88
|
-
@name = options[:guessed_mvc][:name]
|
97
|
+
@name = options[:guessed_mvc][:name]
|
89
98
|
@mvc_version = options[:guessed_mvc][:version]
|
90
99
|
@connected_gems = options[:guessed_mvc][:connected_gems]
|
91
100
|
@gemfile_lock_sudo = true
|
@@ -205,9 +214,44 @@ module Dawn
|
|
205
214
|
end
|
206
215
|
|
207
216
|
def get_mvc_version
|
208
|
-
"#{@mvc_version}" if is_good_mvc?
|
217
|
+
"#{@mvc_version}" if is_good_mvc?
|
209
218
|
end
|
210
219
|
|
220
|
+
########################################################################
|
221
|
+
## Output stuff - START
|
222
|
+
########################################################################
|
223
|
+
|
224
|
+
# Creates the directory name where dawnscanner results will be saved
|
225
|
+
#
|
226
|
+
# Examples
|
227
|
+
# engine.create_output_dir
|
228
|
+
# # => /Users/thesp0nge/dawnscanner/results/railsgoat/20151123
|
229
|
+
# # => /Users/thesp0nge/dawnscanner/results/railsgoat/20151123_1 (if
|
230
|
+
# previous directory name exists)
|
231
|
+
def output_dir
|
232
|
+
@output_dir_name = File.join(Dir.home, 'dawnscanner', 'results', File.basename(@target), Time.now.strftime('%Y%m%d'))
|
233
|
+
if Dir.exist?(@output_dir_name)
|
234
|
+
i=1
|
235
|
+
while (Dir.exist?(@output_dir_name)) do
|
236
|
+
@output_dir_name = File.join(Dir.home, 'dawnscanner', 'results', File.basename(@target), "#{Time.now.strftime('%Y%m%d')}_#{i}")
|
237
|
+
i+=1
|
238
|
+
end
|
239
|
+
end
|
240
|
+
@output_dir_name
|
241
|
+
end
|
242
|
+
|
243
|
+
# Creates the directory
|
244
|
+
def create_output_dir
|
245
|
+
FileUtils.mkdir_p(@output_dir_name)
|
246
|
+
@output_dir_name
|
247
|
+
end
|
248
|
+
|
249
|
+
########################################################################
|
250
|
+
## Output stuff - END
|
251
|
+
########################################################################
|
252
|
+
|
253
|
+
|
254
|
+
|
211
255
|
## Security stuff applies here
|
212
256
|
#
|
213
257
|
# Public it applies a single security check given by its name
|
@@ -215,8 +259,8 @@ module Dawn
|
|
215
259
|
# name - the security check to be applied
|
216
260
|
#
|
217
261
|
# Examples
|
218
|
-
#
|
219
|
-
# engine.apply("CVE-2013-1800")
|
262
|
+
#
|
263
|
+
# engine.apply("CVE-2013-1800")
|
220
264
|
# # => boolean
|
221
265
|
#
|
222
266
|
# Returns a true value if the security check was successfully applied or false
|
@@ -238,30 +282,7 @@ module Dawn
|
|
238
282
|
return false if @checks.empty?
|
239
283
|
|
240
284
|
@checks.each do |check|
|
241
|
-
if check.name == name
|
242
|
-
unless ((check.kind == Dawn::KnowledgeBase::PATTERN_MATCH_CHECK || check.kind == Dawn::KnowledgeBase::COMBO_CHECK ) && @name == "Gemfile.lock")
|
243
|
-
debug_me "applying check #{check.name}"
|
244
|
-
@applied_checks += 1
|
245
|
-
@applied << { :name=>name }
|
246
|
-
check.ruby_version = @ruby_version[:version]
|
247
|
-
check.detected_ruby = @ruby_version if check.kind == Dawn::KnowledgeBase::RUBY_VERSION_CHECK
|
248
|
-
check.dependencies = self.connected_gems if check.kind == Dawn::KnowledgeBase::DEPENDENCY_CHECK
|
249
|
-
check.root_dir = self.target if check.kind == Dawn::KnowledgeBase::PATTERN_MATCH_CHECK
|
250
|
-
check.options = {:detected_ruby => self.ruby_version, :dependencies => self.connected_gems, :root_dir => self.target } if check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
251
|
-
|
252
|
-
check_vuln = check.vuln?
|
253
|
-
|
254
|
-
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check_vuln && check.kind != Dawn::KnowledgeBase::COMBO_CHECK
|
255
|
-
|
256
|
-
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>check.vulnerable_checks} if check_vuln && check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
257
|
-
|
258
|
-
@mitigated_issues << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check.mitigated?
|
259
|
-
return true
|
260
|
-
else
|
261
|
-
debug_me "skipping check #{check.name}"
|
262
|
-
@skipped_checks += 1
|
263
|
-
end
|
264
|
-
end
|
285
|
+
_do_apply(check) if check.name == name
|
265
286
|
end
|
266
287
|
|
267
288
|
false
|
@@ -270,6 +291,7 @@ module Dawn
|
|
270
291
|
def apply_all
|
271
292
|
@scan_start = Time.now
|
272
293
|
debug_me("SCAN STARTED: #{@scan_start}")
|
294
|
+
|
273
295
|
# FIXME.20140325
|
274
296
|
# Now if no checks are loaded because knowledge base was not previously called, apply and apply_all proudly refuse to run.
|
275
297
|
# Reason is simple, load_knowledge_base now needs enabled check array
|
@@ -290,29 +312,9 @@ module Dawn
|
|
290
312
|
end
|
291
313
|
|
292
314
|
@checks.each do |check|
|
293
|
-
|
294
|
-
|
295
|
-
@applied << { :name => name }
|
296
|
-
debug_me "applying check #{check.name}"
|
297
|
-
@applied_checks += 1
|
298
|
-
|
299
|
-
check.ruby_version = @ruby_version[:version]
|
300
|
-
check.detected_ruby = @ruby_version if check.kind == Dawn::KnowledgeBase::RUBY_VERSION_CHECK
|
301
|
-
check.dependencies = self.connected_gems if check.kind == Dawn::KnowledgeBase::DEPENDENCY_CHECK
|
302
|
-
check.root_dir = self.target if check.kind == Dawn::KnowledgeBase::PATTERN_MATCH_CHECK
|
303
|
-
check.options = {:detected_ruby => self.ruby_version, :dependencies => self.connected_gems, :root_dir => self.target } if check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
304
|
-
check_vuln = check.vuln?
|
305
|
-
|
306
|
-
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check_vuln && check.kind != Dawn::KnowledgeBase::COMBO_CHECK
|
307
|
-
|
308
|
-
@vulnerabilities << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>check.vulnerable_checks} if check_vuln && check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
309
|
-
|
310
|
-
@mitigated_issues << {:name=> check.name, :severity=>check.severity, :priority=>check.priority, :kind=>check.check_family, :message=>check.message, :remediation=>check.remediation, :evidences=>check.evidences, :vulnerable_checks=>nil} if check.mitigated?
|
311
|
-
else
|
312
|
-
debug_me "skipping check #{check.name}"
|
313
|
-
@skipped_checks += 1
|
314
|
-
end
|
315
|
+
_do_apply(check)
|
315
316
|
end
|
317
|
+
|
316
318
|
@scan_stop = Time.now
|
317
319
|
debug_me("SCAN STOPPED: #{@scan_stop}")
|
318
320
|
|
@@ -355,7 +357,7 @@ module Dawn
|
|
355
357
|
end
|
356
358
|
|
357
359
|
def count_vulnerabilities
|
358
|
-
ret = 0
|
360
|
+
ret = 0
|
359
361
|
ret = @vulnerabilities.count unless @vulnerabilities.nil?
|
360
362
|
ret += @reflected_xss.count unless @reflected_xss.nil?
|
361
363
|
|
@@ -373,6 +375,61 @@ module Dawn
|
|
373
375
|
hash = File.read(File.join(@target, '.ruby-version')).split('-')
|
374
376
|
return {:version=>hash[0], :patchlevel=>hash[1]}
|
375
377
|
end
|
378
|
+
def _do_apply(check)
|
379
|
+
unless ((check.kind == Dawn::KnowledgeBase::PATTERN_MATCH_CHECK || check.kind == Dawn::KnowledgeBase::COMBO_CHECK ) && @gemfile_lock_sudo)
|
380
|
+
|
381
|
+
@applied << { :name => name }
|
382
|
+
debug_me "applying check #{check.name}"
|
383
|
+
@applied_checks += 1
|
384
|
+
|
385
|
+
check.ruby_version = @ruby_version[:version]
|
386
|
+
check.detected_ruby = @ruby_version if check.kind == Dawn::KnowledgeBase::RUBY_VERSION_CHECK
|
387
|
+
check.dependencies = self.connected_gems if check.kind == Dawn::KnowledgeBase::DEPENDENCY_CHECK
|
388
|
+
check.root_dir = self.target if check.kind == Dawn::KnowledgeBase::PATTERN_MATCH_CHECK
|
389
|
+
check.options = {:detected_ruby => self.ruby_version,
|
390
|
+
:dependencies => self.connected_gems,
|
391
|
+
:root_dir => self.target } if check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
392
|
+
check_vuln = check.vuln?
|
393
|
+
|
394
|
+
if check_vuln
|
395
|
+
|
396
|
+
vc = nil
|
397
|
+
vc = check.vulnerable_checks if check.kind == Dawn::KnowledgeBase::COMBO_CHECK
|
398
|
+
|
399
|
+
@vulnerabilities << {:name=> check.name,
|
400
|
+
:severity=>check.severity,
|
401
|
+
:priority=>check.priority,
|
402
|
+
:kind=>check.check_family,
|
403
|
+
:message=>check.message,
|
404
|
+
:remediation=>check.remediation,
|
405
|
+
:evidences=>check.evidences,
|
406
|
+
:cve_link=>check.cve_link,
|
407
|
+
:cvss_score=>check.cvss_score,
|
408
|
+
:vulnerable_checks=>vc}
|
376
409
|
|
410
|
+
end
|
411
|
+
|
412
|
+
@mitigated_issues << {:name=> check.name,
|
413
|
+
:severity=>check.severity,
|
414
|
+
:priority=>check.priority,
|
415
|
+
:kind=>check.check_family,
|
416
|
+
:message=>check.message,
|
417
|
+
:remediation=>check.remediation,
|
418
|
+
:evidences=>check.evidences,
|
419
|
+
:vulnerable_checks=>nil} if check.mitigated?
|
420
|
+
else
|
421
|
+
debug_me "skipping check #{check.name}"
|
422
|
+
@skipped_checks += 1
|
423
|
+
end
|
424
|
+
|
425
|
+
true
|
426
|
+
end
|
427
|
+
|
428
|
+
def gather_statistics
|
429
|
+
dirs = CodeMetrics::StatsDirectories.new
|
430
|
+
puts target
|
431
|
+
dirs.add_directories("#{target}/**/*.rb", "#{target}")
|
432
|
+
puts CodeMetrics::Statistics.new(*dirs).to_s
|
433
|
+
end
|
377
434
|
end
|
378
435
|
end
|