Module: Msf::Auxiliary::ManageEngineXnode::Process

Included in:
Msf::Auxiliary::ManageEngineXnode
Defined in:
lib/msf/core/auxiliary/manage_engine_xnode/process.rb

Instance Method Summary collapse

Instance Method Details

#process_dr_search(res, res_code, repo_name, fields = nil, mode = 'standard') ⇒ Array?

Processes the obtained server response from a ManageEngine Xnode data repository search request

Parameters:

  • res (Hash)

    JSON-parsed response from the Xnode server. This should be a Hash.

  • res_code (Integer)

    Response code received during the previous get_response call

  • repo_name (String)

    Name of the data repository that was queried

  • fields (Array) (defaults to: nil)

    names of the data repository fields (columns) that were dumped

  • mode (String) (defaults to: 'standard')

    the type of query that was performed: standard, total_hits, aggr_min or aggr_max

Returns:

  • (Array, nil)

    Array containing the parsed query results if parsing succeeds, nil otherwise

[View source] [View on GitHub]

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/msf/core/auxiliary/manage_engine_xnode/process.rb', line 12

def process_dr_search(res, res_code, repo_name, fields=nil, mode='standard')
  if res_code == 1 || res.nil? || !(res.instance_of?(Hash) && res.keys.include?('response') && res['response'].instance_of?(Hash))
    vprint_error("Received unexpected reply when trying to dump table #{repo_name}: #{res}")
    return nil
  end

  response = res['response']

  unless response.include?('search_result') && response.include?('total_hits')
    if response.include?('error_msg')
      error_msg = response['error_msg']
      if /DataRepository for '#{repo_name}' not found!/ =~ error_msg
        print_status("The data repository #{repo_name} is not available on the target.")
      else
        print_error("Received error message: #{error_msg}")
      end
    else
      print_error("Received unexpected query response: #{response}")
    end

    return nil
  end

  case mode
  when 'total_hits'
    # try to grab the total hits
    total_hits = response['total_hits']
    unless total_hits && total_hits.is_a?(Integer)
      print_error("Received unexpected reply when trying to obtain the number of total hits for table #{repo_name}.")
      print_warning("The target may not be exploitable.")
      return nil
    end

    if total_hits == 0
      print_status("Data repository #{repo_name} is empty.")
      return nil
    end

    return [total_hits]
  when 'aggr_min', 'aggr_max'
    aggr_type = mode.split("_")[1]
    unless response.include?('aggr_result') && response['aggr_result'].is_a?(Hash) && response['aggr_result'].include?(aggr_type)
      print_error("Received unexpected reply when trying to obtain #{aggr_type} aggregate value for the UNIQUE_ID field.")
      return nil
    end

    return [response['aggr_result'][aggr_type]]
  when 'standard'
    search_result = response['search_result']
    unless search_result.is_a? Array
      print_error("Received unexpected query response: #{response}")
      return nil
    end

    if search_result.empty?
      vprint_status("The query returned no records.")
      return nil
    end

    return search_result unless fields.is_a? Array
    
    process_results(search_result, fields)
  else
    print_error('An invalid mode parameter was supplied!')
    return nil
  end
end

#process_results(search_result, fields) ⇒ Array?

Processes the search_result received from the Xnode server. If the fields parameter is provided, received values are mapped to known field (column) names.

Parameters:

  • search_result (Array)

    nested Array containing the data repository rows and their values

  • fields (Array)

    data repository fields (columns) that were dumped, used for mapping the search_result values to field names

Returns:

  • (Array, nil)

    Array containing the query results if the provided parameters are correct, nil otherwise

[View source] [View on GitHub]

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/msf/core/auxiliary/manage_engine_xnode/process.rb', line 85

def process_results(search_result, fields)
  return nil unless fields.is_a? Array
  results = []
  non_empty_val_ct = 0 # used to check the search results contains at least one non_empty value 
  # map the search returned values to the specified fields
  search_result.each do |row|
    row_data = {}
    row.each_with_index do |val, index|
      non_empty_val_ct += 1 unless val.blank?
      column_name = fields[index]
      row_data[column_name] = val
    end 
    results << row_data
  end

  if non_empty_val_ct == 0
    return nil
  end

  results
end