dockscan 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +8 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE +340 -0
- data/README.md +52 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dockscan.gemspec +27 -0
- data/docs/dockscan.png +0 -0
- data/exe/dockscan +107 -0
- data/lib/dockscan/modules/audit/container-filesystem-diff.rb +41 -0
- data/lib/dockscan/modules/audit/container-filesystem-shadow.rb +37 -0
- data/lib/dockscan/modules/audit/container-number-process.rb +36 -0
- data/lib/dockscan/modules/audit/container-sshd-process.rb +33 -0
- data/lib/dockscan/modules/audit/docker-experimental-build.rb +27 -0
- data/lib/dockscan/modules/audit/docker-insecure-registries.rb +53 -0
- data/lib/dockscan/modules/audit/docker-limits.rb +34 -0
- data/lib/dockscan/modules/audit/docker-networking-forwarding.rb +27 -0
- data/lib/dockscan/modules/audit/docker-registry-mirror.rb +41 -0
- data/lib/dockscan/modules/audit/docker-storage-driver-aufs.rb +28 -0
- data/lib/dockscan/modules/audit.rb +32 -0
- data/lib/dockscan/modules/discover/get-containers.rb +14 -0
- data/lib/dockscan/modules/discover/get-docker-info.rb +17 -0
- data/lib/dockscan/modules/discover/get-docker-version.rb +14 -0
- data/lib/dockscan/modules/discover/get-images.rb +16 -0
- data/lib/dockscan/modules/discover/get-run-containers.rb +14 -0
- data/lib/dockscan/modules/discover.rb +16 -0
- data/lib/dockscan/modules/genmodule.rb +17 -0
- data/lib/dockscan/modules/report/html.rb +182 -0
- data/lib/dockscan/modules/report/stdout.rb +36 -0
- data/lib/dockscan/modules/report/txt.rb +36 -0
- data/lib/dockscan/modules/report.rb +75 -0
- data/lib/dockscan/scan/issue.rb +18 -0
- data/lib/dockscan/scan/manage.rb +172 -0
- data/lib/dockscan/scan/plugin.rb +14 -0
- data/lib/dockscan/version.rb +3 -0
- data/lib/dockscan.rb +7 -0
- metadata +141 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
class ContainerFilesystemDiff < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks for filesystem differences'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
|
9
|
+
limit=5
|
10
|
+
sp=Dockscan::Scan::Plugin.new
|
11
|
+
si=Dockscan::Scan::Issue.new
|
12
|
+
si.title="Container have higher number of changed files"
|
13
|
+
si.description="Container have high number of changed files which is not recommended practice.\nThis is not recommended for production as data can be lost. It can also mean successful break in attempt."
|
14
|
+
si.solution="It is recommended to have minimal number of changed files inside container and do not store data inside container. It is recommended to use volumes."
|
15
|
+
si.severity=4 # Low
|
16
|
+
si.risk = { "cvss" => 3.2 }
|
17
|
+
sp.vuln=si
|
18
|
+
sp.output=""
|
19
|
+
if scandata.key?("GetContainers") and not scandata["GetContainers"].obj.empty?
|
20
|
+
sp.state="run"
|
21
|
+
scandata["GetContainers"].obj.each do |container|
|
22
|
+
begin
|
23
|
+
ps=container.changes
|
24
|
+
if ps.count > limit then
|
25
|
+
sp.state="vulnerable"
|
26
|
+
allch = ''
|
27
|
+
ps.each do |change|
|
28
|
+
allch << change["Path"] << "\n"
|
29
|
+
end
|
30
|
+
sp.output << idcontainer(container) << " has more than #{limit} file changes: #{ps.count}\n"
|
31
|
+
sp.output << allch
|
32
|
+
sp.output << "\n"
|
33
|
+
end
|
34
|
+
rescue
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return sp
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class ContainerFileSystemShadow < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks /etc/shadow for problems'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Container have passwordless users in shadow"
|
11
|
+
si.description="Container have vulnerable entries in /etc/shadow.\nIt allows attacker to login or switch to user without password."
|
12
|
+
si.solution="It is recommended to set password for user or to lock user account."
|
13
|
+
si.severity=6 # High
|
14
|
+
si.risk = { "cvss" => 7.5 }
|
15
|
+
sp.vuln=si
|
16
|
+
sp.output=""
|
17
|
+
if scandata.key?("GetContainers") and not scandata["GetContainers"].obj.empty?
|
18
|
+
sp.state="run"
|
19
|
+
scandata["GetContainers"].obj.each do |container|
|
20
|
+
content=''
|
21
|
+
container.copy('/etc/shadow') { |chunk| content=content+chunk }
|
22
|
+
shcontent=''
|
23
|
+
Gem::Package::TarReader.new(StringIO.new(content)) { |t| shcontent=t.first.read }
|
24
|
+
# shcontent.split("\n").each do |line|
|
25
|
+
shcontent.lines.map(&:chomp).each do |line|
|
26
|
+
shfield=line.split(":")
|
27
|
+
if shfield[1].to_s=='' then
|
28
|
+
sp.state="vulnerable"
|
29
|
+
sp.output << idcontainer(container) << " does not have password set for user: #{shfield[0]}\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return sp
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ContainerNumberProcess < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks number of container processes'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
|
9
|
+
limit=1
|
10
|
+
sp=Dockscan::Scan::Plugin.new
|
11
|
+
si=Dockscan::Scan::Issue.new
|
12
|
+
si.title="Container have higher number of processess"
|
13
|
+
si.description="Container have more than allowable number of processes.\nThis is not recommended for production as it does not provide intended isolation."
|
14
|
+
si.solution="It is recommended to have single process inside container. If you have more than one process, it is recommended to split them in separate containers."
|
15
|
+
si.severity=4 # Low
|
16
|
+
si.risk = { "cvss" => 3.2 }
|
17
|
+
sp.vuln=si
|
18
|
+
sp.output=""
|
19
|
+
if scandata.key?("GetContainersRunning") and not scandata["GetContainersRunning"].obj.empty?
|
20
|
+
sp.state="run"
|
21
|
+
scandata["GetContainersRunning"].obj.each do |container|
|
22
|
+
ps=container.top
|
23
|
+
if ps.count > limit then
|
24
|
+
sp.state="vulnerable"
|
25
|
+
sp.output << idcontainer(container) << " has more than #{limit} process(es): #{ps.count}\n"
|
26
|
+
ps.each do |process|
|
27
|
+
sp.output << process["CMD"] << "\n"
|
28
|
+
end
|
29
|
+
sp.output << "\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return sp
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class ContainerSSHProcess < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if SSH is running inside container'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Container have SSH server process"
|
11
|
+
si.description="Docker daemon reports it is running SSH daemon inside container.\nThis is not recommended practice as it provides yet another attack surface for attackers and wastes computer resources."
|
12
|
+
si.solution="It is recommended to remove SSH daemon/client from container. It is recommended to use docker exec command to execute commands inside container."
|
13
|
+
si.severity=4 # Low
|
14
|
+
si.risk = { "cvss" => 3.2 }
|
15
|
+
sp.vuln=si
|
16
|
+
sp.output=""
|
17
|
+
if scandata.key?("GetContainersRunning") and not scandata["GetContainersRunning"].obj.empty?
|
18
|
+
sp.state="run"
|
19
|
+
scandata["GetContainersRunning"].obj.each do |container|
|
20
|
+
ps=container.top
|
21
|
+
ps.each do |process|
|
22
|
+
if process["CMD"].include?("ssh") then
|
23
|
+
sp.output << idcontainer(container) << " has SSH process running: " << process["CMD"] << "\n"
|
24
|
+
sp.state="vulnerable"
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return sp
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class DockerExperimentalBuild < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if docker is running Experimental Build'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Running Experimental version of Docker."
|
11
|
+
si.description="Docker daemon reports it is running ExperimentalBuild.\nThis is not recommended for production as it might have problems and security issues."
|
12
|
+
si.solution="It is recommended to replace Docker version with stable and production ready one."
|
13
|
+
si.severity=6 # High
|
14
|
+
si.risk = { "cvss" => 7.0 }
|
15
|
+
si.reflinks = {"Docker's Experimental Binary" => "https://blog.docker.com/2015/06/experimental-binary/"}
|
16
|
+
sp.vuln=si
|
17
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("ExperimentalBuild")
|
18
|
+
sp.state="run"
|
19
|
+
if scandata["GetDockerInfo"].obj["ExperimentalBuild"] == true then
|
20
|
+
sp.output = "Docker daemon reports it is running ExperimentalBuild."
|
21
|
+
sp.state="vulnerable"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
return sp
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class DockerInsecureRegistries < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if insecure registries in use'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Insecure registries in use"
|
11
|
+
si.description="Docker daemon reports it is running configuration with insecure registries.\nThis is not recommended as attacker is able to deploy malicious images to registries."
|
12
|
+
si.solution="It is recommended to use secure registries and configuration without insecure registries."
|
13
|
+
si.severity=4 # Low
|
14
|
+
si.risk = { "cvss" => 3.2 }
|
15
|
+
si.references = {"CIS" => "2.5 Do not use insecure registries" }
|
16
|
+
sp.vuln=si
|
17
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("RegistryConfig")
|
18
|
+
sp.state="run"
|
19
|
+
vulnerable = false
|
20
|
+
outputregs = ""
|
21
|
+
outputindexs = ""
|
22
|
+
# ["RegistryConfig"]["InsecureRegistryCIDRs"].each do |item| puts item end
|
23
|
+
scandata["GetDockerInfo"].obj["RegistryConfig"]["InsecureRegistryCIDRs"].each do |item|
|
24
|
+
if item != "127.0.0.0/8" then
|
25
|
+
vulnerable=true
|
26
|
+
outputregs = item << "\n"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# Docker.info["RegistryConfig"]["IndexConfigs"].each do |item,value| puts item,value,value["Secure"] end
|
30
|
+
scandata["GetDockerInfo"].obj["RegistryConfig"]["IndexConfigs"].each do |item, value|
|
31
|
+
if value["Secure"] != true
|
32
|
+
vulnerable=true
|
33
|
+
outputindexs = item value["Name"] << "\n"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if vulnerable then
|
38
|
+
sp.state="vulnerable"
|
39
|
+
sp.output = "Docker daemon reports it is using insecure registries. Offending issues below.\n "
|
40
|
+
if outputregs != "" then
|
41
|
+
sp.output << "Insecure CIDRs offending configuration:\n"
|
42
|
+
sp.output << outputregs << "\n"
|
43
|
+
end
|
44
|
+
if outputindexs != "" then
|
45
|
+
sp.output << "Offending registry indexes:\n"
|
46
|
+
sp.output << outputindexs << "\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return sp
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class DockerLimits < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if docker is running with defined limits'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Docker running without defined limits"
|
11
|
+
si.description="Docker daemon reports it is running daemon without defined limits.\nThis is not recommended as offending containers could use up all resources."
|
12
|
+
si.solution="It is recommended to define docker limits."
|
13
|
+
si.severity=5 # Medium
|
14
|
+
si.risk = { "cvss" => 4.4 }
|
15
|
+
si.references = {"CIS" => "2.10 Set default ulimit as appropriate" }
|
16
|
+
sp.output=""
|
17
|
+
sp.vuln=si
|
18
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("MemoryLimit")
|
19
|
+
sp.state="run"
|
20
|
+
if scandata["GetDockerInfo"].obj["MemoryLimit"] == false then
|
21
|
+
sp.output << "Docker daemon reports it is running without memory limit.\n"
|
22
|
+
sp.state="vulnerable"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("SwapLimit")
|
26
|
+
if scandata["GetDockerInfo"].obj["SwapLimit"] == false then
|
27
|
+
sp.output << "Docker daemon reports it is running without swap limit.\n"
|
28
|
+
sp.state="vulnerable"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
return sp
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class DockerIPV4Forwarding < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if docker is running with ipv4 forwarding enabled'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Docker running with IPv4 forwarding enabled"
|
11
|
+
si.description="Docker daemon reports it is running daemon with IPv4 forwarding enabled.\nThis is not recommended for production as it forwards network packets without rules."
|
12
|
+
si.solution="It is recommended to disable IPv4 forwarding by default."
|
13
|
+
si.severity=5 # Medium
|
14
|
+
si.risk = { "cvss" => 5.0 }
|
15
|
+
si.reflinks = {"ip_forward to expose containers to the public internet" => "https://github.com/docker/docker/issues/11508"}
|
16
|
+
sp.vuln=si
|
17
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("IPv4Forwarding")
|
18
|
+
sp.state="run"
|
19
|
+
if scandata["GetDockerInfo"].obj["IPv4Forwarding"] == true then
|
20
|
+
sp.output = "Docker daemon reports it is running with automatic IPv4 forwarding."
|
21
|
+
sp.state="vulnerable"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
return sp
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class DockerRegistryMirror < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if mirror registries are in use'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Docker registries are not mirrored"
|
11
|
+
si.description="Docker daemon reports it is running configuration without registry mirrors.\nIf you set up local mirror, your docker host does not have to go directly to internet if not needed."
|
12
|
+
si.solution="It is recommended to setup mirror registry."
|
13
|
+
si.severity=4 # Low
|
14
|
+
si.risk = { "cvss" => 3.0 }
|
15
|
+
si.references = {"CIS" => "2.6 Setup a local registry mirror" }
|
16
|
+
sp.vuln=si
|
17
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("RegistryConfig")
|
18
|
+
sp.state="run"
|
19
|
+
vulnerable=true
|
20
|
+
outputindexs = ""
|
21
|
+
scandata["GetDockerInfo"].obj["RegistryConfig"]["IndexConfigs"].each do |item, value|
|
22
|
+
if value["Mirrors"] != nil
|
23
|
+
vulnerable = false
|
24
|
+
else
|
25
|
+
outputindexs << value["Name"] << "\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if vulnerable then
|
30
|
+
sp.state="vulnerable"
|
31
|
+
sp.output = "Docker daemon reports it does not have mirror registries.\n"
|
32
|
+
if outputindexs != "" then
|
33
|
+
sp.output << "Offending registry indexes:\n"
|
34
|
+
sp.output << outputindexs << "\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
return sp
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class DockerStorageDriverAufs < Dockscan::Modules::AuditModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'This plugin checks if storage driver is aufs'
|
5
|
+
end
|
6
|
+
|
7
|
+
def check(dockercheck)
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
si=Dockscan::Scan::Issue.new
|
10
|
+
si.title="Running aufs as storage driver"
|
11
|
+
si.description="Docker daemon reports it is running aufs as storage driver.\nThis is not recommended for production as it might have problems and security issues."
|
12
|
+
si.solution="It is recommended to use devicemapper instead of aufs storage driver. Actually, you should use the storage driver that is best supported by your vendor."
|
13
|
+
si.severity=4 # Low
|
14
|
+
si.risk = { "cvss" => 3.2 }
|
15
|
+
si.reflinks = {"Switching Docker from aufs to devicemapper" => "http://muehe.org/posts/switching-docker-from-aufs-to-devicemapper/"}
|
16
|
+
si.references = {"CIS" => "2.7 Do not use the aufs storage driver" }
|
17
|
+
sp.vuln=si
|
18
|
+
if scandata.key?("GetDockerInfo") and scandata["GetDockerInfo"].obj.key?("Driver")
|
19
|
+
sp.state="run"
|
20
|
+
if scandata["GetDockerInfo"].obj["Driver"] == true then
|
21
|
+
sp.output = "Docker daemon reports it is running aufs as storage driver."
|
22
|
+
sp.state="vulnerable"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return sp
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Dockscan
|
2
|
+
module Modules
|
3
|
+
|
4
|
+
class AuditModule < GenericModule
|
5
|
+
attr_accessor :scandata
|
6
|
+
|
7
|
+
def info
|
8
|
+
raise "#{self.class.name} doesn't implement `handle_command`!"
|
9
|
+
end
|
10
|
+
|
11
|
+
def idcontainer(container)
|
12
|
+
str=''
|
13
|
+
str << container.id
|
14
|
+
str << " ("
|
15
|
+
names = ''
|
16
|
+
container.info["Names"].each do |name|
|
17
|
+
names << name << " "
|
18
|
+
end
|
19
|
+
str << names
|
20
|
+
str << ")"
|
21
|
+
str << " with IP: "
|
22
|
+
str << container.json["NetworkSettings"]["IPAddress"]
|
23
|
+
return str
|
24
|
+
end
|
25
|
+
|
26
|
+
def check(dockercheck)
|
27
|
+
raise "#{self.class.name} doesn't implement `handle_command`!"
|
28
|
+
end
|
29
|
+
end # class
|
30
|
+
|
31
|
+
end # Module
|
32
|
+
end # Dockscan
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class GetContainers < Dockscan::Modules::DiscoverModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'Container discovery module'
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
sp.obj = Docker::Container.all(:all => true)
|
10
|
+
sp.output = sp.obj.map{|k,v| "#{k}=#{v}"}.join("\n")
|
11
|
+
return sp
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'docker'
|
2
|
+
|
3
|
+
class GetDockerInfo < Dockscan::Modules::DiscoverModule
|
4
|
+
|
5
|
+
def info
|
6
|
+
return 'Info discovery module'
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
sp=Dockscan::Scan::Plugin.new
|
11
|
+
sp.obj = Docker.info
|
12
|
+
sp.output = sp.obj.map{|k,v| "#{k}=#{v}"}.join("\n")
|
13
|
+
sp.state = "run"
|
14
|
+
return sp
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class GetDockerVersion < Dockscan::Modules::DiscoverModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'Info discovery module'
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
sp.obj = Docker.version
|
10
|
+
sp.output = sp.obj.map{|k,v| "#{k}=#{v}"}.join("\n")
|
11
|
+
return sp
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'docker'
|
2
|
+
|
3
|
+
class GetImages < Dockscan::Modules::DiscoverModule
|
4
|
+
|
5
|
+
def info
|
6
|
+
return 'Image discovery module'
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
sp=Dockscan::Scan::Plugin.new
|
11
|
+
sp.obj = Docker::Image.all
|
12
|
+
sp.output = sp.obj.map{|k,v| "#{k}=#{v}"}.join("\n")
|
13
|
+
return sp
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class GetContainersRunning < Dockscan::Modules::DiscoverModule
|
2
|
+
|
3
|
+
def info
|
4
|
+
return 'Running Container discovery module'
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
sp=Dockscan::Scan::Plugin.new
|
9
|
+
sp.obj = Docker::Container.all
|
10
|
+
sp.output = sp.obj.map{|k,v| "#{k}=#{v}"}.join("\n")
|
11
|
+
return sp
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dockscan
|
2
|
+
module Modules
|
3
|
+
|
4
|
+
class DiscoverModule < GenericModule
|
5
|
+
attr_accessor :scandata
|
6
|
+
def info
|
7
|
+
raise "#{self.class.name} doesn't implement `handle_command`!"
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
raise "#{self.class.name} doesn't implement `handle_command`!"
|
12
|
+
end
|
13
|
+
end # class
|
14
|
+
|
15
|
+
end # Module
|
16
|
+
end # Dockscan
|