
CVE-2017-8291 CTF avec docker et exemples
Le module PIL (Pillow) permettant de traiter des images en Python est affecté par la vulnérabilité GhostButt (CVE-2017-8291) car il appelle GhostScript en interne, ce qui entraîne une vulnérabilité d'exécution de commande à distance.
PIL détermine en interne le type d'image en fonction de l'en-tête du fichier (Magic Bytes). S'il s'agit d'un fichier EPS (l'en-tête est %!PS), il est transmis à PIL/EpsImagePlugin.py pour traitement.
Dans ce module, PIL appelle la commande système gs, c'est-à-dire GhostScript, pour traiter les fichiers image :
command = ["gs",
"-q", # quiet mode
"-g%dx%d" % size, # set output geometry (pixels)
"-r%fx%f" % res, # set input DPI (dots per inch)
"-dBATCH", # exit after processing
"-dNOPAUSE", # don't pause between pages,
"-dSAFER", # safe mode
"-sDEVICE=ppmraw", # ppm driver
"-sOutputFile=%s" % outfile, # output file
"-c", "%d %d translate" % (-bbox[0], -bbox[1]),
# adjust for image origin
"-f", infile, # input file
]
# Omit the code to determine whether GhostScript is installed
try:
with open(os.devnull, 'w+b') as devnull:
subprocess.check_call(command, stdin=devnull, stdout=devnull)
im = Image.open(outfile)
Bien que -dSAFER, c'est-à-dire le mode sans échec, soit défini, en raison d'une vulnérabilité de contournement du sandbox dans GhostScript (GhostButt CVE-2017-8291), ce mode sans échec est contourné et des commandes arbitraires peuvent être exécutées.
De plus, à l'heure actuelle, la dernière version officielle de GhostScript 9.21 est encore affectée par cette vulnérabilité, on peut donc dire que tant que GhostScript est installé sur le système d'exploitation, notre PIL présente une vulnérabilité d'exécution de commande.
Environnement d'exploitation :
docker-compose up -d
Après exécution, visitez http://your-ip:8000/ pour voir une page de téléversement. La fonction normale consiste à téléverser un fichier PNG ; le backend appelle PIL pour charger l'image et affiche la largeur et la hauteur. Mais nous pouvons modifier l'extension du fichier EPS contenant la commande exécutable en PNG pour le téléverser, car le backend détermine le type d'image en fonction de l'en-tête du fichier, la vérification de l'extension est donc ignorée.
Par exemple, si nous téléversons poc.png, nous pouvons exécuter touch /tmp/youhavebeenpwned. Modifiez la commande dans le POC en une commande de rebond pour obtenir un shell :