
Cacti 1.2.22 – nicht authentifizierte Befehlsinjektion
| Feld | Details |
|---|
| Produkt | Cacti |
| Betroffene Version | 1.2.22 |
| Schwachstelle | Nicht authentifizierte OS-Befehlsinjektion |
| CVE | CVE-2022-46169 |
| CWE | CWE-77 — Command Injection |
| Schweregrad | Kritisch |
| CVSS v3.1 | 9.8 |
| Angriffsvektor | Netzwerk |
| Authentifizierung | Keine |
| Benutzerinteraktion | Keine |
| Auswirkung | Vertraulichkeit / Integrität / Verfügbarkeit |
| Behobene Version | 1.2.23 |
| Verwundbare Komponente | remote_agent.php |
| Zusätzliche Komponente | lib/functions.php |
| Hauptverwundbare Aktion | polldata |
Der veröffentlichte CVSS-Vektor lautet:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Die offizielle Empfehlung bewertet sie mit 9.8 Kritisch. (GitHub)
Es sind tatsächlich zwei Bugs, die miteinander verkettet sind.
Stufe 1 — Autorisierungsumgehung
Cactis remote_agent.php akzeptiert Anfragen ohne normale Authentifizierung, versucht jedoch zu bestimmen, ob der Anfragende ein autorisierter Poller ist.
Der Autorisierungsablauf funktioniert effektiv so:
HTTP-Anfrage
│
▼
remote_agent.php
│
▼
remote_client_authorized()
│
▼
get_client_addr()
│
▼
gethostbyaddr()
│
▼
Poller-Tabellen-Hostname-Vergleich
Das Problem ist get_client_addr().
In 1.2.22 untersucht es zahlreiche von HTTP abgeleitete Server-Variablen, einschließlich Forwarded-Client-IP-Header. Die Empfehlung erklärt, dass vom Angreifer kontrollierte HTTP_*-Werte die von dieser Funktion zurückgegebene IP beeinflussen können. (GitHub)
Das bedeutet, dass die Anwendung dazu verleitet werden kann zu glauben:
Angreifer
↓
"Meine IP ist der Cacti-Server"
↓
gethostbyaddr()
↓
Cacti-Server-Hostname
↓
stimmt mit Poller-Tabelle überein
↓
AUTORISIERT
Der Angreifer benötigt also kein legitimes Cacti-Konto.
Nach der Umgehung der Autorisierungsprüfung ist die interessante Endpunkt-Funktionalität die polldata-Aktion.
Der relevante Ausführungspfad ist ungefähr:
remote_agent.php
│
▼
polldata
│
▼
poll_for_data()
│
├── host_id
├── local_data_ids
└── poller_id
│
▼
poller_item-Lookup
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
proc_open()
│
▼
OS-Befehlsausführung
Der wichtige Fehler ist die Behandlung von poller_id.
Die Anwendung ruft sie ab mit:
get_nfilter_request_var()
anstatt zu erzwingen, dass es eine Ganzzahl ist.
Dieser vom Angreifer kontrollierte Wert wird schließlich Teil eines Befehls, der an PHP's proc_open() übergeben wird. Die offizielle Empfehlung identifiziert dies ausdrücklich als die Befehlsinjektions-Primitive. (GitHub)
Konzeptionell:
vom Angreifer kontrollierte Eingabe
↓
poller_id
↓
String-Verkettung
↓
proc_open()
↓
Betriebssystem-Befehl
Dies ist der kritische Teil der Schwachstelle.
Das Interessante für deine PoC-Analyse ist, dass keiner der beiden Bugs allein die ganze Geschichte ist.
Es ist eine Schwachstellenkette:
┌──────────────────────────┐
│ Nicht authentifizierter │
│ Angreifer │
└────────────┬─────────────┘
│
▼
remote_agent.php
│
▼
Autorisierungsumgehung
über Client-IP-Logik
│
▼
polldata
│
▼
poller_item-Lookup
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
Angreifer-Eingabe
→ poller_id
│
▼
proc_open()
│
▼
Befehlsausführung
│
▼
RCE
Das ist eine sehr wichtige Unterscheidung für deinen Bericht:
CVE-2022-46169 ist nicht einfach "ein schlechter Parameter in remote_agent.php." Es ist eine verkettete Autorisierungsumgehungs- + Befehlsinjektions-Schwachstelle.
Die offizielle Empfehlung bestätigt, dass die verwundbare Ausführungsbedingung ein poller_item erfordert, dessen Aktion POLLER_ACTION_SCRIPT_PHP ist. (GitHub)
Dein PoC sollte dies ausdrücklich dokumentieren, da es ein wichtiges analytisches Detail ist.
Das Ziel benötigt ein geeignetes poller_item, das konfiguriert ist mit:
POLLER_ACTION_SCRIPT_PHP
Die Cacti-Empfehlung stellt fest, dass dies bei Produktionsinstallationen üblich ist, da vordefinierte Vorlagen wie Device - Uptime und Device - Polling Time diese Einträge erstellen können. (GitHub)
Schreibe also nicht:
"Jede Cacti-1.2.22-Installation ist automatisch ausnutzbar."
Eine technisch genauere Aussage ist:
Cacti 1.2.22 ist verwundbar, und eine erfolgreiche Befehlsausführung hängt vom Vorhandensein einer geeigneten
poller_item-Konfiguration ab.
host_id und local_data_id wichtig sindpoll_for_data() führt nicht einfach die bereitgestellte poller_id aus.
Es fragt zuerst poller_item ab, indem es Werte verwendet, die entsprechen:
host_id
local_data_id
Dann untersucht es die Aktion des resultierenden Eintrags.
Die verwundbare Bedingung ist effektiv:
host_id
+
local_data_id
↓
poller_item
↓
action == POLLER_ACTION_SCRIPT_PHP
↓
verwundbarer Ausführungspfad
Die ursprüngliche Empfehlung stellt fest, dass diese Bezeichner entdeckt werden können, da die relevanten Einträge in der Datenbank der Anwendung existieren, und dass geeignete Einträge wahrscheinlich auf produktiven Installationen vorhanden sind. (GitHub)
Für einen öffentlichen PoC würde ich diese Voraussetzung ausdrücklich demonstrieren, anstatt sie zu verstecken.
Für etwas, das du veröffentlichst, empfehle ich, den PoC so zu gestalten, dass er Befehlsausführung demonstriert, ohne den Lesern eine bewaffnete Reverse-Shell-Payload zu geben.
Gestalte deine Demonstration zum Beispiel so:
1. Cacti 1.2.22 in einer isolierten VM bereitstellen
2. Ein poller_item mit POLLER_ACTION_SCRIPT_PHP konfigurieren
3. Bestätigen, dass remote_agent.php erreichbar ist
4. Demonstrieren, dass die Autorisierungsentscheidung beeinflusst wird
5. Den polldata-Ausführungspfad erreichen
6. Eine harmlose Befehlsausführungs-Markierung verwenden
7. Die resultierenden Anwendungs-/Log-Beweise erfassen
8. Auf 1.2.23 upgraden
9. Den Test wiederholen
10. Demonstrieren, dass die Schwachstelle nicht mehr ausnutzbar ist
Das ergibt eine legitime Schwachstellendemonstration, ohne den Bericht in eine fertige Internet-RCE-Waffe zu verwandeln.
Du kannst den verwundbaren Code in drei Bereiche unterteilen.
remote_agent.phpVerantwortlich für die Bereitstellung der Remote-Agent-Funktionalität und die Weiterleitung der angeforderten Aktion.
remote_agent.php
│
└── action = polldata
│
▼
poll_for_data()
lib/functions.phpEnthält get_client_addr().
Das problematische Design besteht darin, HTTP-abgeleiteten Werten zu vertrauen, wenn die tatsächliche Netzwerkadresse des Anfragenden bestimmt wird.
Die offizielle Empfehlung listet mehrere HTTP-bezogene Variablen auf, die untersucht werden, bevor auf die tatsächliche Remote-Adresse zurückgegriffen wird. (GitHub)
proc_open()Die endgültige gefährliche Senke ist die Konstruktion des PHP-Befehls, der über proc_open() ausgeführt wird.
Die Empfehlung identifiziert den verwundbaren Ablauf als:
poller_id
↓
get_nfilter_request_var()
↓
Befehlskonstruktion
↓
proc_open()
(GitHub)
Die Cacti-Empfehlung identifiziert zwei wichtige Abhilfemaßnahmen.
Erstens sollte poller_id als Ganzzahl behandelt werden:
get_nfilter_request_var()
↓
get_filter_request_var()
Zweitens sollte der Wert zusätzlich Shell-escaped werden, bevor er in den Befehl aufgenommen wird:
escapeshellarg($poller_id)
Die Empfehlung empfiehlt ausdrücklich beide Maßnahmen. (GitHub)
Die Autorisierungsseite muss außerdem aufhören, einem Angreifer zu erlauben, die für die Autorisierung verwendete Client-IP willkürlich zu beeinflussen. (GitHub)
Cacti 1.2.22
│
├── verwundbar
├── Autorisierungsumgehung
├── Befehlsinjektion
└── potenzielle nicht authentifizierte RCE
Cacti 1.2.23
│
└── CVE-2022-46169 gepatcht
Die Hersteller-Empfehlung listet 1.2.22 als betroffen und 1.2.23 als die gepatchte 1.2.x-Version auf. (GitHub)
Die Sicherheitsempfehlung von Amazon beschreibt das Problem unabhängig als die Möglichkeit für einen nicht authentifizierten Angreifer, beliebige Befehle auszuführen, und vergibt einen CVSS-Score von 9.8. (AWS Training and Certification)
Ich würde so etwas verwenden wie:
CVE-2022-46169 — Nicht authentifizierte Befehlsinjektion / RCE in Cacti 1.2.22
Oder technischer:
CVE-2022-46169: Analyse der Cacti-1.2.22-Remote-Agent-Autorisierungsumgehung und Befehlsinjektionskette
Und deine Schwachstellenzusammenfassung kann lauten:
Cacti 1.2.22 enthält eine kritische Schwachstellenkette in der Remote-Agent-Funktionalität. Ein Angreifer kann die Logik zur Bestimmung der Client-Adresse manipulieren, um die Remote-Agent-Autorisierungsprüfung zu umgehen. Sobald die
polldata-Funktionalität erreicht ist, ermöglicht eine unzureichende Validierung despoller_id-Parameters, dass vom Angreifer kontrollierte Daten einen überproc_open()ausgeführten Befehl erreichen. Bei Konfigurationen, die einPOLLER_ACTION_SCRIPT_PHP-Poller-Element enthalten, kann dies zu nicht authentifizierter Remote-Befehlsausführung führen. Das Problem wurde in Cacti 1.2.23 behoben. (GitHub)
Eine wichtige Korrektur für deine Recherche: Verwechsle dies nicht mit CVE-2023-39362. Diese spätere Cacti-RCE betrifft 1.2.24 und wurde in 1.2.25 behoben, ist also nicht die Schwachstelle, die du für einen 1.2.22-PoC möchtest. (NVD)