Le PoC de CVE-2026-44011 : RCE de Craft CMS avec un utilisateur authentifié.
Pour des tests autorisés uniquement.
L'avis de sécurité Craft CMS liste >=4.0.0, <4.17.12 et >=5.0.0, <5.9.18 comme versions affectées, et crédite precicom-vincent-tl comme découvreur.
python -m pip install -r requirements.txt
python cve-2026-44011.py -b 'https://example.com' -u '<username' -p '<password>' -c '<command>'
Arguments requis :
-b, --base-url : URL de Craft, incluant http:// ou https://.-u, --username : nom d'utilisateur du panneau de contrôle.-p, --password : mot de passe du panneau de contrôle.-c, --command : commande à exécuter et dont la sortie doit être capturée.Arguments optionnels :
-P, --cp-path : chemin du panneau de contrôle (par défaut : /admin).-s, --site-id : ID du site (par défaut : 1).-e, --element-type : type d'élément (par défaut : craft\elements\Category).-f, --csrf-field : nom du champ CSRF de connexion (par défaut : CRAFT_CSRF_TOKEN).-t, --timeout : délai d'attente des requêtes et des callbacks en secondes (par défaut : 15).-F, --force : continuer lorsque la version de Craft est indisponible ou en dehors des plages de l'avis.-H, --callback-host : adresse que la cible peut atteindre (adresse locale déduite par défaut ; à surcharger derrière un pivot).--listen-port : port d'écoute (par défaut : un port libre sélectionné par l'OS ; définir un port fixe pour la redirection).Dans l'action de recherche vulnérable, condition passe du corps POST à la création d'objet sans nettoyage.
$conditionConfig = $this->request->getBodyParam('condition');
$condition = Craft::$app->getConditions()->createCondition($conditionConfig);
ElementCondition::setFieldLayouts() construit une disposition à partir de chaque tableau fourni.
if (is_array($fieldLayout)) {
$fieldLayout['type'] = $this->elementType;
return $fieldsService->createLayout($fieldLayout);
}
La charge utile de l'avis attache l'AttributeTypecastBehavior de Yii avec une clé as et câble un événement avec on *. Le comportement atteint Psy\Readline\Hoa\ConsoleProcessus::execute via le typecast de callable de Yii.
condition.fieldLayouts[]
-> FieldLayout behavior + event
-> AttributeTypecastBehavior::typecastValue()
-> call_user_func()
-> ConsoleProcessus::execute()
Le contrôleur corrigé applique Component::cleanseConfig() à la condition avant la création de l'objet.
ConsoleProcessus::execute() de Psy échappe les métacaractères du shell par défaut. Le PoC sert un script temporaire pour exécuter -c, reçoit sa sortie sur un écouteur HTTP intégré, puis arrête l'écouteur ensuite. Utilisez -H si la cible ne peut pas atteindre l'adresse déduite.sh, curl et mktemp sur la cible.python -m unittest discover -s tests -v.