dockscan 0.1.0

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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +340 -0
  8. data/README.md +52 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/dockscan.gemspec +27 -0
  13. data/docs/dockscan.png +0 -0
  14. data/exe/dockscan +107 -0
  15. data/lib/dockscan/modules/audit/container-filesystem-diff.rb +41 -0
  16. data/lib/dockscan/modules/audit/container-filesystem-shadow.rb +37 -0
  17. data/lib/dockscan/modules/audit/container-number-process.rb +36 -0
  18. data/lib/dockscan/modules/audit/container-sshd-process.rb +33 -0
  19. data/lib/dockscan/modules/audit/docker-experimental-build.rb +27 -0
  20. data/lib/dockscan/modules/audit/docker-insecure-registries.rb +53 -0
  21. data/lib/dockscan/modules/audit/docker-limits.rb +34 -0
  22. data/lib/dockscan/modules/audit/docker-networking-forwarding.rb +27 -0
  23. data/lib/dockscan/modules/audit/docker-registry-mirror.rb +41 -0
  24. data/lib/dockscan/modules/audit/docker-storage-driver-aufs.rb +28 -0
  25. data/lib/dockscan/modules/audit.rb +32 -0
  26. data/lib/dockscan/modules/discover/get-containers.rb +14 -0
  27. data/lib/dockscan/modules/discover/get-docker-info.rb +17 -0
  28. data/lib/dockscan/modules/discover/get-docker-version.rb +14 -0
  29. data/lib/dockscan/modules/discover/get-images.rb +16 -0
  30. data/lib/dockscan/modules/discover/get-run-containers.rb +14 -0
  31. data/lib/dockscan/modules/discover.rb +16 -0
  32. data/lib/dockscan/modules/genmodule.rb +17 -0
  33. data/lib/dockscan/modules/report/html.rb +182 -0
  34. data/lib/dockscan/modules/report/stdout.rb +36 -0
  35. data/lib/dockscan/modules/report/txt.rb +36 -0
  36. data/lib/dockscan/modules/report.rb +75 -0
  37. data/lib/dockscan/scan/issue.rb +18 -0
  38. data/lib/dockscan/scan/manage.rb +172 -0
  39. data/lib/dockscan/scan/plugin.rb +14 -0
  40. data/lib/dockscan/version.rb +3 -0
  41. data/lib/dockscan.rb +7 -0
  42. metadata +141 -0
@@ -0,0 +1,182 @@
1
+ class ReportHTML < Dockscan::Modules::ReportModule
2
+
3
+ def info
4
+ return 'This plugin produces HTML reports'
5
+ end
6
+
7
+ def file_extension
8
+ return ".html"
9
+ end
10
+
11
+ def format
12
+ return "html"
13
+ end
14
+
15
+ def htmlhead
16
+ htmlout = ""
17
+ htmlout << "<HTML><HEAD><TITLE>dockscan Report</TITLE>\n"
18
+ htmlout << '<style>'
19
+ htmlout << '.Vulnerability {
20
+ margin:0px;padding:0px;
21
+ width:100%;
22
+ border:0px solid #000000;
23
+
24
+ -moz-border-radius-bottomleft:0px;
25
+ -webkit-border-bottom-left-radius:0px;
26
+ border-bottom-left-radius:0px;
27
+
28
+ -moz-border-radius-bottomright:0px;
29
+ -webkit-border-bottom-right-radius:0px;
30
+ border-bottom-right-radius:0px;
31
+
32
+ -moz-border-radius-topright:0px;
33
+ -webkit-border-top-right-radius:0px;
34
+ border-top-right-radius:0px;
35
+
36
+ -moz-border-radius-topleft:0px;
37
+ -webkit-border-top-left-radius:0px;
38
+ border-top-left-radius:0px;
39
+ }.Vulnerability table{
40
+ border-collapse: collapse;
41
+ border-spacing: 0;
42
+ width:100%;
43
+ height:100%;
44
+ margin:0px;padding:0px;
45
+ }.Vulnerability tr:last-child td:last-child {
46
+ -moz-border-radius-bottomright:0px;
47
+ -webkit-border-bottom-right-radius:0px;
48
+ border-bottom-right-radius:0px;
49
+ }
50
+ .Vulnerability table tr:first-child td:first-child {
51
+ -moz-border-radius-topleft:0px;
52
+ -webkit-border-top-left-radius:0px;
53
+ border-top-left-radius:0px;
54
+ }
55
+ .Vulnerability table tr:first-child td:last-child {
56
+ -moz-border-radius-topright:0px;
57
+ -webkit-border-top-right-radius:0px;
58
+ border-top-right-radius:0px;
59
+ }.Vulnerability tr:last-child td:first-child{
60
+ -moz-border-radius-bottomleft:0px;
61
+ -webkit-border-bottom-left-radius:0px;
62
+ border-bottom-left-radius:0px;
63
+ }.Vulnerability tr:hover td{
64
+ background-color:#ffffff;
65
+ }
66
+ .Vulnerability td{
67
+ vertical-align:middle;
68
+
69
+ background-color:#ffffff;
70
+
71
+ border:0px solid #000000;
72
+ border-width:0px 1px 1px 0px;
73
+ text-align:left;
74
+ padding:7px;
75
+ font-size:10px;
76
+ font-family:Arial;
77
+ font-weight:normal;
78
+ color:#000000;
79
+ }.Vulnerability tr:last-child td{
80
+ border-width:0px 0px 0px 0px;
81
+ }.Vulnerability tr td:last-child{
82
+ border-width:0px 0px 0px 0px;
83
+ }.Vulnerability tr:last-child td:last-child{
84
+ border-width:0px 0px 0px 0px;
85
+ }
86
+ .Vulnerability tr:first-child td{
87
+ border:0px solid #000000;
88
+ text-align:left;
89
+ border-width:0px 0px 0px 0px;
90
+ font-size:14px;
91
+ font-family:Arial;
92
+ font-weight:bold;
93
+ color:#000000;
94
+ }
95
+ .Vulnerability tr:first-child:hover td{
96
+ }
97
+ .Vulnerability tr:first-child td:first-child{
98
+ border-width:0px 0px 0px 0px;
99
+ }
100
+ .Vulnerability tr:first-child td:last-child{
101
+ border-width:0px 0px 0px 0px;
102
+ }
103
+
104
+ .VulnerabilityBLACK tr:first-child td{
105
+ background-color:#000000;
106
+ color:#FFFFFF;
107
+ }
108
+
109
+ .VulnerabilityRED tr:first-child td{
110
+ background-color:#ff0000;
111
+ color:#ffffff;
112
+ }
113
+
114
+ .VulnerabilityORANGE tr:first-child td{
115
+ background-color:#ff9966;
116
+ color:#000000;
117
+ }
118
+
119
+ .VulnerabilityYELLOW tr:first-child td{
120
+ background-color:#ffff00;
121
+ color:#000000;
122
+ }
123
+
124
+ .VulnerabilityGRAY tr:first-child td{
125
+ background-color:#d0d0d0;
126
+ color:#000000;
127
+ }
128
+ '
129
+ htmlout << '</style>'
130
+ htmlout << "</HEAD>\n"
131
+ htmlout << "<BODY>\n"
132
+ htmlout << '<img width="220" height="169" title="" alt="" src="data:image/png;base64,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" />'
133
+ return htmlout
134
+ end
135
+
136
+ def htmlfoot
137
+ htmlout = ""
138
+ htmlout << "</BODY>\n"
139
+ htmlout << "</HTML>\n"
140
+ return htmlout
141
+ end
142
+
143
+ def report(opts)
144
+ output=""
145
+ output << htmlhead
146
+ output << "<h2>dockscan Report<h2>"
147
+ issues = sortvulns
148
+ 7.downto(3) do |sev|
149
+ if issues.key?(sev)
150
+ output << "<h3>" << sev2word(sev) << " vulnerabilities</h3>\n"
151
+ issues[sev].each do |v|
152
+ if sev >= 7 then
153
+ output << '<TABLE CLASS="Vulnerability VulnerabilityBLACK">'
154
+ elsif sev == 6 then
155
+ output << '<TABLE CLASS="Vulnerability VulnerabilityRED">'
156
+ elsif sev == 5
157
+ output << '<TABLE CLASS="Vulnerability VulnerabilityORANGE">'
158
+ elsif sev == 4
159
+ output << '<TABLE CLASS="Vulnerability VulnerabilityYELLOW">'
160
+ elsif sev == 3
161
+ output << '<TABLE CLASS="Vulnerability VulnerabilityGRAY">'
162
+ else
163
+ output << '<TABLE CLASS="Vulnerability">'
164
+ end
165
+ output << "<TR>\n"
166
+ output << "<TD COLSPAN=2>" << v.vuln.title << "</TD>\n"
167
+ output << "<TD>" << sev2word(v.vuln.severity) << "</TD>\n"
168
+ output << "</TR>\n"
169
+ output << "<TR><TD COLSPAN=3>" << v.vuln.description << "</TD></TR>\n"
170
+ output << "<TR><TD COLSPAN=3><PRE>" << v.output << "</PRE></TD></TR>\n"
171
+ output << "<TR><TD COLSPAN=3>" << v.vuln.solution << "</TD></TR>\n"
172
+ output << "<TR><TD>CVSS: " << getkey(v.vuln.risk,"cvss").to_s << "</TD><TD>State: " << v.state << "</TD><TD></TD></TR>\n"
173
+ output << "</TABLE>\n\n"
174
+ end
175
+ output << "<P></P>\n"
176
+ end
177
+ end
178
+ return output
179
+
180
+ end
181
+ end
182
+
@@ -0,0 +1,36 @@
1
+ class ReportStdout < Dockscan::Modules::ReportModule
2
+
3
+ def info
4
+ return 'This plugin produces brief stdout reports'
5
+ end
6
+
7
+ def format
8
+ return "stdout"
9
+ end
10
+
11
+ def file_extension
12
+ return "-stdout.txt"
13
+ end
14
+
15
+ def report(opts)
16
+ output=""
17
+ output << "Dockscan Report\n\n"
18
+
19
+ issues = sortvulns
20
+ 7.downto(3) do |sev|
21
+ if issues.key?(sev)
22
+ output << sev2word(sev) << "\n"
23
+ issues[sev].each do |v|
24
+ # output << k << ": "
25
+ output << v.vuln.title << ": "
26
+ output << v.vuln.solution
27
+ # output << v.output
28
+ output << "\n"
29
+ end
30
+ output << "\n"
31
+ end
32
+ end
33
+ return output
34
+ end
35
+ end
36
+
@@ -0,0 +1,36 @@
1
+ class ReportText < Dockscan::Modules::ReportModule
2
+
3
+ def info
4
+ return 'This plugin produces text reports'
5
+ end
6
+
7
+ def format
8
+ return "txt"
9
+ end
10
+
11
+ def file_extension
12
+ return ".txt"
13
+ end
14
+
15
+ def report(opts)
16
+ output=""
17
+ output << "Dockscan Report\n\n"
18
+
19
+ issues = sortvulns
20
+ 7.downto(3) do |sev|
21
+ if issues.key?(sev)
22
+ output << "-[ " << sev2word(sev) << " ]-\n"
23
+ issues[sev].each do |v|
24
+ output << "=" << v.vuln.title << "=\n"
25
+ output << "Description:\n" << v.vuln.description << "\n"
26
+ output << "Output:\n" << v.output << "\n"
27
+ output << "Solution:\n" << v.vuln.solution << "\n"
28
+ output << "\n"
29
+ end
30
+ output << "\n"
31
+ end
32
+ end
33
+ return output
34
+ end
35
+ end
36
+
@@ -0,0 +1,75 @@
1
+ module Dockscan
2
+ module Modules
3
+
4
+ class ReportModule < GenericModule
5
+ attr_accessor :scandata
6
+
7
+ def info
8
+ raise "#{self.class.name} doesn't implement `handle_command`!"
9
+ end
10
+
11
+ def desc(item)
12
+ if item.vuln.description
13
+ return item.vuln.description
14
+ else
15
+ return false
16
+ end
17
+ end
18
+
19
+ def sortvulns
20
+ severity_sorted=Hash.new
21
+ scandata.each do |classname,scanissue|
22
+ if scanissue.state == "vulnerable" or scanissue.state=="info" then
23
+ severity_sorted[scanissue.vuln.severity] ||= []
24
+ severity_sorted[scanissue.vuln.severity] << scanissue
25
+ end
26
+ end
27
+ return severity_sorted
28
+ end
29
+
30
+ def format
31
+ return "unknown"
32
+ end
33
+
34
+ def file_extension
35
+ return ".unknown"
36
+ end
37
+
38
+ def getkey(hsh,hkey)
39
+ if hsh.has_key?(hkey) then
40
+ return hsh[hkey]
41
+ else
42
+ return ''
43
+ end
44
+ end
45
+
46
+ def sev2word(sev)
47
+ case sev
48
+ when 7
49
+ return "Critical"
50
+ when 6
51
+ return "High"
52
+ when 5
53
+ return "Medium"
54
+ when 4
55
+ return "Low"
56
+ when 3
57
+ return "Info"
58
+ when 2
59
+ return "Verbose"
60
+ when 1
61
+ return "Inspect"
62
+ when 0
63
+ return "Debug"
64
+ else
65
+ return "DebugMiss"
66
+ end
67
+ end
68
+
69
+ def report(opts)
70
+ raise "#{self.class.name} doesn't implement `handle_command`!"
71
+ end
72
+ end # Class
73
+
74
+ end # Module
75
+ end # Dockscan
@@ -0,0 +1,18 @@
1
+ module Dockscan
2
+ module Scan
3
+ class Issue
4
+ attr_accessor :severity, :description, :solution, :title, :tags, :references, :risk, :reflinks
5
+
6
+ def initialize
7
+ severity=0
8
+ description="Forgot to add description"
9
+ solution="Information only."
10
+ title="Forgot to add title"
11
+ tags=Hash.new
12
+ references=Hash.new
13
+ risk=Hash.new
14
+ reflinks=Hash.new
15
+ end
16
+ end # Issue
17
+ end # Scan
18
+ end # Dockscan
@@ -0,0 +1,172 @@
1
+ require 'docker'
2
+
3
+ require 'dockscan/modules/genmodule'
4
+ require 'dockscan/modules/discover'
5
+ require 'dockscan/modules/audit'
6
+ require 'dockscan/modules/report'
7
+
8
+ require 'dockscan/scan/plugin'
9
+
10
+ require 'pp'
11
+
12
+ module Dockscan
13
+ module Scan
14
+ class Manage
15
+
16
+ attr_accessor :log
17
+
18
+ def initialize
19
+ @auditoutput=Hash.new
20
+ @log=Logger.new MultiDelegator.delegate(:write, :close).to(STDERR)
21
+ end
22
+
23
+ def check_connection
24
+ @log.info("Validating version specified: "+Docker.url)
25
+ begin
26
+ Docker.validate_version!
27
+ rescue
28
+ @log.error("Error connecting or validating Docker version")
29
+ return false
30
+ end
31
+ return true
32
+ end
33
+
34
+ def scan (url, opts, logger)
35
+ failed=Array.new
36
+
37
+ if url != nil then
38
+ Docker.url = url
39
+ end
40
+
41
+ @log=logger
42
+
43
+ if not check_connection then
44
+ return
45
+ end
46
+
47
+ moduledirs=Array.new
48
+ if moduledirs.empty? then
49
+ moduledirs.push File.expand_path("../modules", File.dirname(__FILE__))
50
+ end
51
+
52
+ @log.info("Loading discovery modules...")
53
+ moduledirs.each do |moduledir|
54
+ @log.debug("Loading dir: #{moduledir}")
55
+ Dir["#{moduledir}/discover/*.rb"].each do |f|
56
+ @log.info("Loading discovery module: #{f}")
57
+ begin
58
+ require f
59
+ rescue SyntaxError => se
60
+ @log.info("Error loading audit module: #{f}")
61
+ @log.debug("Error executing audit module: #{se.backtrace}")
62
+ failed << f
63
+ end
64
+ end
65
+ end
66
+
67
+ @log.info("Running discovery modules...")
68
+ Dockscan::Modules::DiscoverModule.modules.each do |modclass|
69
+ @log.info("Running discovery module: #{modclass.name}")
70
+ begin
71
+ mod=modclass.new
72
+ mod.scandata=@auditoutput
73
+ @auditoutput[mod.class.name]=mod.run
74
+ rescue Exception => e
75
+ @log.info("Error executing audit module: #{modclass.name}")
76
+ @log.debug("Error executing audit module: #{e.backtrace}")
77
+ failed << modclass.name
78
+ end
79
+ # pp @auditoutput[mod.class.name]
80
+ end
81
+
82
+
83
+ @log.info("Loading audit modules...")
84
+ moduledirs.each do |moduledir|
85
+ @log.debug("Loading dir: #{moduledir}")
86
+ Dir["#{moduledir}/audit/*.rb"].each do |f|
87
+ @log.info("Loading audit module: #{f}")
88
+ begin
89
+ require f
90
+ rescue SyntaxError => se
91
+ @log.info("Error loading audit module: #{f}")
92
+ @log.debug("Error executing audit module: #{se.backtrace}")
93
+ failed << f
94
+ end
95
+ end
96
+ end
97
+
98
+ @log.info("Running audit modules...")
99
+ Dockscan::Modules::AuditModule.modules.each do |modclass|
100
+ @log.info("Running audit module: #{modclass.name}")
101
+ begin
102
+ mod=modclass.new
103
+ mod.scandata=@auditoutput
104
+ @auditoutput[mod.class.name]=mod.check('test')
105
+ rescue Exception => e
106
+ @log.info("Error executing audit module: #{modclass.name}")
107
+ @log.debug("Error executing audit module: #{e.to_s} #{e.backtrace}")
108
+ failed << modclass.name
109
+ end
110
+ # pp @auditoutput[mod.class.name]
111
+ end
112
+
113
+ @log.info("Loading report modules...")
114
+ moduledirs.each do |moduledir|
115
+ Dir["#{moduledir}/report/*.rb"].each do |f|
116
+ @log.info("Loading report #{f}")
117
+ begin
118
+ require f
119
+ rescue SyntaxError => se
120
+ @log.info("Error loading report module: #{f}")
121
+ @log.debug("Error executing report module: #{se.backtrace}")
122
+ failed << f
123
+ end
124
+ end
125
+ end
126
+
127
+ @log.info("Running report modules...")
128
+ Dockscan::Modules::ReportModule.modules.each do |modclass|
129
+ @log.info("Running report module: #{modclass.name}")
130
+ mod=modclass.new
131
+ if opts.key?("report") then
132
+ formats=opts["report"].split(",")
133
+ else
134
+ formats=['stdout']
135
+ end
136
+ formats.each do |fmt|
137
+ if fmt==mod.format then
138
+ begin
139
+ mod.scandata=@auditoutput
140
+ output=mod.report(nil)
141
+ if opts.key?("output") then
142
+ reportfilename = opts["output"]
143
+ reportfilename << mod.file_extension
144
+ File.open(reportfilename, 'w') { |file| file.write(output) }
145
+ else
146
+ puts output
147
+ end
148
+ rescue Exception => e
149
+ @log.info("Error executing report module: #{modclass.name}")
150
+ @log.debug("Error executing report module: #{e.to_s} #{e.backtrace}")
151
+ failed << modclass.name
152
+ end
153
+ @log.debug(output)
154
+ else
155
+ @log.debug("Skipping report module: #{modclass.name}");
156
+ end
157
+ end
158
+ end
159
+
160
+ if failed.count > 0
161
+ failedstr=""
162
+ failed.each do |f|
163
+ failedstr = f + " "
164
+ end
165
+ @log.warn("Following modules failed: #{failedstr}")
166
+ end
167
+ end
168
+
169
+ end # Class
170
+ end # Scan
171
+ end # Dockscan
172
+
@@ -0,0 +1,14 @@
1
+ require 'dockscan/scan/issue'
2
+
3
+ module Dockscan
4
+ module Scan
5
+ class Plugin
6
+ attr_accessor :state, :output, :obj, :vuln, :cname
7
+
8
+ def initialize
9
+ state="untested"
10
+ vuln = Dockscan::Scan::Issue.new
11
+ end
12
+ end # Plugin
13
+ end # Scan
14
+ end # Dockscan
@@ -0,0 +1,3 @@
1
+ module Dockscan
2
+ VERSION = "0.1.0"
3
+ end
data/lib/dockscan.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "dockscan/version"
2
+
3
+ require "dockscan/scan/manage"
4
+
5
+ module Dockscan
6
+ # Your code goes here...
7
+ end