
Cacti 1.2.22 injection de commande non authentifiée
| Champ | Détails |
|---|
| Produit | Cacti |
| Version affectée | 1.2.22 |
| Vulnérabilité | Injection de commande OS non authentifiée |
| CVE | CVE-2022-46169 |
| CWE | CWE-77 — Injection de commande |
| Sévérité | Critique |
| CVSS v3.1 | 9.8 |
| Vecteur d'attaque | Réseau |
| Authentification | Aucune |
| Interaction utilisateur | Aucune |
| Impact | Confidentialité / Intégrité / Disponibilité |
| Version corrigée | 1.2.23 |
| Composant vulnérable | remote_agent.php |
| Composant supplémentaire | lib/functions.php |
| Action vulnérable principale | polldata |
Le vecteur CVSS publié est :
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
L'avis officiel le note 9.8 Critique. (GitHub)
Il y a en réalité deux bogues enchaînés.
Étape 1 — Contournement d'autorisation
Le remote_agent.php de Cacti accepte les requêtes sans authentification normale, mais tente de déterminer si le demandeur est un poller autorisé.
Le flux d'autorisation fait effectivement ceci :
Requête HTTP
│
▼
remote_agent.php
│
▼
remote_client_authorized()
│
▼
get_client_addr()
│
▼
gethostbyaddr()
│
▼
Comparaison du nom d'hôte dans la table poller
Le problème est get_client_addr().
Dans la version 1.2.22, elle examine de nombreuses variables serveur dérivées de HTTP, y compris les en-têtes d'IP client transférés. L'avis explique que des valeurs HTTP_* contrôlées par l'attaquant peuvent influencer l'IP renvoyée par cette fonction. (GitHub)
Cela signifie que l'application peut être trompée pour croire :
Attaquant
↓
"mon IP est le serveur Cacti"
↓
gethostbyaddr()
↓
Nom d'hôte du serveur Cacti
↓
Correspond à la table poller
↓
AUTORISÉ
L'attaquant n'a donc pas besoin d'un compte Cacti légitime.
Après avoir contourné la vérification d'autorisation, la fonctionnalité intéressante du point de terminaison est l'action polldata.
Le chemin d'exécution pertinent est approximativement :
remote_agent.php
│
▼
polldata
│
▼
poll_for_data()
│
├── host_id
├── local_data_ids
└── poller_id
│
▼
Recherche poller_item
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
proc_open()
│
▼
Exécution de commande OS
L'erreur importante est la gestion de poller_id.
L'application le récupère en utilisant :
get_nfilter_request_var()
plutôt qu'en imposant qu'il s'agisse d'un entier.
Cette valeur contrôlée par l'attaquant finit par faire partie d'une commande transmise à proc_open() de PHP. L'avis officiel identifie explicitement cela comme la primitive d'injection de commande. (GitHub)
Conceptuellement :
entrée contrôlée par l'attaquant
↓
poller_id
↓
concaténation de chaînes
↓
proc_open()
↓
commande du système d'exploitation
C'est la partie critique de la vulnérabilité.
Ce qui est intéressant pour votre analyse de PoC, c'est que aucun des deux bogues pris isolément ne raconte toute l'histoire.
C'est une chaîne de vulnérabilités :
┌──────────────────────────┐
│ Attaquant non authentifié │
└────────────┬─────────────┘
│
▼
remote_agent.php
│
▼
Contournement d'autorisation
via la logique d'IP client
│
▼
polldata
│
▼
Recherche poller_item
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
entrée de l'attaquant
→ poller_id
│
▼
proc_open()
│
▼
Exécution de commande
│
▼
RCE
C'est une distinction très importante à faire dans votre rapport :
CVE-2022-46169 n'est pas simplement « un mauvais paramètre dans remote_agent.php ». C'est une vulnérabilité enchaînée de contournement d'autorisation + injection de commande.
L'avis officiel confirme que la condition d'exécution vulnérable nécessite un poller_item dont l'action est POLLER_ACTION_SCRIPT_PHP. (GitHub)
Votre PoC devrait documenter explicitement cela car c'est un détail analytique important.
La cible doit avoir un poller_item approprié configuré avec :
POLLER_ACTION_SCRIPT_PHP
L'avis Cacti note que cela est courant sur les installations de production car des modèles prédéfinis tels que Device - Uptime et Device - Polling Time peuvent créer ces entrées. (GitHub)
N'écrivez donc pas :
« Chaque installation Cacti 1.2.22 est automatiquement exploitable. »
Une déclaration techniquement plus précise est :
Cacti 1.2.22 est vulnérable, et l'exécution réussie de commandes dépend de la présence d'une configuration
poller_itemappropriée.
host_id et local_data_id sont importantspoll_for_data() n'exécute pas simplement le poller_id fourni.
Elle interroge d'abord poller_item en utilisant des valeurs correspondant à :
host_id
local_data_id
Ensuite, elle examine l'action de l'élément résultant.
La condition vulnérable est effectivement :
host_id
+
local_data_id
↓
poller_item
↓
action == POLLER_ACTION_SCRIPT_PHP
↓
chemin d'exécution vulnérable
L'avis original note que ces identifiants peuvent être découverts car les entrées pertinentes existent dans la base de données de l'application, et que des entrées appropriées sont susceptibles d'exister sur les installations de production. (GitHub)
Pour un PoC public, je démontrerais ce prérequis explicitement plutôt que de le cacher.
Pour quelque chose que vous publiez, je recommande de faire démontrer au PoC l'exécution de commandes sans donner aux lecteurs une charge utile de reverse-shell armée.
Par exemple, structurez votre démonstration comme suit :
1. Déployer Cacti 1.2.22 dans une VM isolée
2. Configurer un poller_item avec POLLER_ACTION_SCRIPT_PHP
3. Confirmer que remote_agent.php est accessible
4. Démontrer que la décision d'autorisation est influencée
5. Atteindre le chemin d'exécution polldata
6. Utiliser un marqueur d'exécution de commande inoffensif
7. Capturer les preuves résultantes de l'application/journal
8. Mettre à niveau vers 1.2.23
9. Répéter le test
10. Démontrer que la vulnérabilité n'est plus exploitable
Cela vous donne une démonstration légitime de vulnérabilité sans transformer le rapport en arme RCE Internet prête à l'emploi.
Vous pouvez diviser le code vulnérable en trois zones.
remote_agent.phpResponsable de l'exposition de la fonctionnalité d'agent distant et de la répartition de l'action demandée.
remote_agent.php
│
└── action = polldata
│
▼
poll_for_data()
lib/functions.phpContient get_client_addr().
La conception problématique consiste à faire confiance aux valeurs dérivées de HTTP lors de la décision concernant l'adresse réseau réelle du demandeur.
L'avis officiel liste plusieurs variables liées à HTTP qui sont inspectées avant de revenir à l'adresse distante réelle. (GitHub)
proc_open()Le puits dangereux final est la construction de la commande PHP exécutée via proc_open().
L'avis identifie le flux vulnérable comme suit :
poller_id
↓
get_nfilter_request_var()
↓
construction de la commande
↓
proc_open()
(GitHub)
L'avis Cacti identifie deux changements de remédiation importants.
Premièrement, poller_id doit être traité comme un entier :
get_nfilter_request_var()
↓
get_filter_request_var()
Deuxièmement, la valeur doit également être échappée pour le shell avant d'être incorporée dans la commande :
escapeshellarg($poller_id)
L'avis recommande spécifiquement les deux mesures. (GitHub)
Le côté autorisation doit également cesser de permettre à un attaquant d'influencer arbitrairement l'IP client utilisée pour l'autorisation. (GitHub)
Cacti 1.2.22
│
├── vulnérable
├── contournement d'autorisation
├── injection de commande
└── RCE non authentifiée potentielle
Cacti 1.2.23
│
└── CVE-2022-46169 corrigée
L'avis du fournisseur liste 1.2.22 comme affectée et 1.2.23 comme la version 1.2.x corrigée. (GitHub)
L'avis de sécurité d'Amazon décrit indépendamment le problème comme permettant à un attaquant non authentifié d'exécuter des commandes arbitraires et lui attribue un score CVSS de 9.8. (AWS Training and Certification)
J'utiliserais quelque chose comme :
CVE-2022-46169 — Injection de commande non authentifiée / RCE dans Cacti 1.2.22
Ou plus technique :
CVE-2022-46169 : Analyse de la chaîne de contournement d'autorisation et d'injection de commande de l'agent distant Cacti 1.2.22
Et votre résumé de vulnérabilité peut dire :
Cacti 1.2.22 contient une chaîne de vulnérabilités critiques dans la fonctionnalité d'agent distant. Un attaquant peut manipuler la logique de détermination de l'adresse client pour contourner la vérification d'autorisation de l'agent distant. Une fois la fonctionnalité
polldataatteinte, une validation insuffisante du paramètrepoller_idpermet à des données contrôlées par l'attaquant d'atteindre une commande exécutée viaproc_open(). Dans les configurations contenant un élément pollerPOLLER_ACTION_SCRIPT_PHP, cela peut entraîner une exécution de commande à distance non authentifiée. Le problème a été corrigé dans Cacti 1.2.23. (GitHub)
Une correction importante pour vos recherches : ne confondez pas cela avec CVE-2023-39362. Cette RCE Cacti ultérieure affecte 1.2.24 et a été corrigée dans 1.2.25, donc ce n'est pas la vulnérabilité que vous voulez pour un PoC 1.2.22. (NVD)