Module: Msf::Exploit::Remote::HTTP::Nifi::Processor

Includes:
Msf::Exploit::Remote::HttpClient
Included in:
Msf::Exploit::Remote::HTTP::Nifi
Defined in:
lib/msf/core/exploit/remote/http/nifi/processor.rb

Defined Under Namespace

Classes: ProcessorError

Instance Attribute Summary

Attributes included from Msf::Exploit::Remote::HttpClient

#client, #cookie_jar

Instance Method Summary collapse

Methods included from Msf::Exploit::Remote::HttpClient

#basic_auth, #cleanup, #configure_http_login_scanner, #connect, #connect_ws, #deregister_http_client_options, #disconnect, #download, #full_uri, #handler, #http_fingerprint, #initialize, #lookup_http_fingerprints, #normalize_uri, #path_from_uri, #peer, #proxies, #reconfig_redirect_opts!, #request_opts_from_url, #request_url, #rhost, #rport, #send_request_cgi, #send_request_cgi!, #send_request_raw, #service_details, #setup, #ssl, #ssl_version, #strip_tags, #target_uri, #validate_fingerprint, #vhost

Methods included from Auxiliary::LoginScanner

#configure_login_scanner

Methods included from Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Method Details

#create_processor(token, process_group, type = 'org.apache.nifi.processors.standard.ExecuteProcess') ⇒ String

Creates a processor in a process group

Parameters:

  • token (String)

    The bearer token from a valid login, or nil for no Authorization headers

  • process_group (String)

    UUID of a processor group

  • type (String) (defaults to: 'org.apache.nifi.processors.standard.ExecuteProcess')

    What type of processor to create

Returns:

  • (String)

    The UUID of the root process group



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/msf/core/exploit/remote/http/nifi/processor.rb', line 129

def create_processor(token, process_group, type = 'org.apache.nifi.processors.standard.ExecuteProcess')
  vprint_status("Attempting to create of processor in group: #{process_group} of type #{type}")
  body = {
    'component' => { 'type' => type },
    'revision' => { 'version' => 0 }
  }
  opts = {
    'method' => 'POST',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'process-groups', process_group, 'processors'),
    'ctype' => 'application/json',
    'data' => body.to_json
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)
  return nil if res.nil?

  unless res.code == 201
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end
  res.get_json_document['id']
end

#delete_processor(token, processor, version = 0) ⇒ Object

Delete a processor

Parameters:

  • token (String)

    The bearer token from a valid login, or nil for no Authorization headers

  • processor (String)

    UUID of the processes

  • version (Int) (defaults to: 0)

    The version number to delete

Raises:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/msf/core/exploit/remote/http/nifi/processor.rb', line 89

def delete_processor(token, processor, version = 0)
  vprint_status("Attempting to delete version #{version} of Processor: #{processor}")
  opts = {
    'method' => 'DELETE',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'processors', processor),
    'vars_get' => { 'version' => version }
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)
  
  raise ProcessorError if res.nil?

  while res.code == 400 && res.body.include?('is not the most up-to-date revision') && version <= 20
    version += 1
    opts['vars_get'] = { 'version' => version }

    res = send_request_cgi(opts)
    raise ProcessorError if res.nil?

    vprint_status("Found newer revision of #{processor}, attempting to delete version #{version}") if res.code == 400 && res.body.include?('is not the most up-to-date revision')
  end

  if version == 20
    print_bad("Aborting after attempting to delete 20 version of Processor: #{processor}")
    raise ProcessorError
  end

  unless res.code == 200
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end
  print_good('Processor Delete sent successfully')
end

#get_processor_field(token, processor, field = 'id') ⇒ String

Get a processor in a process group

Parameters:

  • token (String)

    The bearer token from a valid login, or nil for no Authorization headers

  • processor (String)

    UUID of a processoror

  • field (String) (defaults to: 'id')

    the key from the JSON blob to return

Returns:

  • (String)

    THe value from the specified field



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/msf/core/exploit/remote/http/nifi/processor.rb', line 158

def get_processor_field(token, processor, field = 'id')
  vprint_status("Attempting to get field #{field} of processor: #{processor}")
  opts = {
    'method' => 'GET',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'processors', processor)
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)

  return nil if res.nil?

  unless res.code == 200
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end

  res.get_json_document[field]
end

#start_processor(token, processor) ⇒ Object

Start processor

Parameters:

  • token (String)

    The bearer token from a valid login, or nil for no Authorization headers

  • processor (String)

    UUID of the processes

Raises:



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
# File 'lib/msf/core/exploit/remote/http/nifi/processor.rb', line 13

def start_processor(token, processor)
  vprint_status("Attempting to start Processor: #{processor}")
  body = {
    'state' => 'RUNNING',
    'disconnectedNodeAcknowledged' => false,
    'revision' => {
      'clientId' => 'x',
      'version' => 0
    }
  }
  opts = {
    'method' => 'PUT',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'processors', processor, 'run-status'),
    'ctype' => 'application/json',
    'data' => body.to_json
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)
  raise ProcessorError if res.nil?

  unless res.code == 200
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end
  print_good('Processor Start sent successfully')
end

#stop_processor(token, processor) ⇒ Object

Stop processor

Parameters:

  • token (String)

    The bearer token from a valid login, or nil for no Authorization headers

  • processor (String)

    UUID of the processes

Raises:



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
79
80
81
82
# File 'lib/msf/core/exploit/remote/http/nifi/processor.rb', line 44

def stop_processor(token, processor)
  vprint_status("Attempting to stop Processor: #{processor}")
  body = {
    'revision' => {
      'clientId' => 'x',
      'version' => 1
    },
    'state' => 'STOPPED'
  }
  opts = {
    'method' => 'PUT',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'processors', processor, 'run-status'),
    'ctype' => 'application/json',
    'data' => body.to_json
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)
  raise ProcessorError if res.nil?

  unless res.code == 200
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end

  # Stop may not have worked (but must be done first). Terminate threads now
  opts = {
    'method' => 'DELETE',
    'uri' => normalize_uri(target_uri.path, 'nifi-api', 'processors', processor, 'threads')
  }
  opts['headers'] = { 'Authorization' => "Bearer #{token}" } if token
  res = send_request_cgi(opts)
  raise ProcessorError if res.nil?

  unless res.code == 200
    print_bad("Unexpected response code: #{res.code}")
    raise ProcessorError
  end
  print_good('Processor Stop sent successfully')
end