
Учебная лаборатория, демонстрирующая CVE-2017-8291 (PIL/GhostScript RCE) через загрузку специально созданного EPS-файла с расширением PNG, включая настройку Docker и выполнение PoC.
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin — обновление до V2sudo apt remove docker docker-engine docker.io containerd runc -ysudo apt updatesudo apt install -y ca-certificates curl gnupg lsb-releasesudo mkdir -p /etc/apt/keyringscurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgecho "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugindocker compose versiongit clone https://github.com/vulhub/vulhub.git
После клонирования перейдите в директорию уязвимости, с которой будете работать
Здесь: /vulhub/python/PIL-CVE-2017-8291
Следуйте yml-файлу для выполнения практики
docker compose up -d : команда для создания контейнера и запуска в фоновом режиме
После этого откройте localhost:8000/ и увидите веб-страницу, позволяющую загружать файлы

Загрузите подделанный файл poc.png, находящийся в той же директории
После загрузки должно появиться следующее:

В нормальном режиме после загрузки png-файла выводятся ширина и высота изображения. Однако сервер определяет тип изображения по заголовку файла, игнорируя расширение. Таким образом, EPS-файл, содержащий выполняемые команды, можно переименовать в расширение .png и загрузить.
Используя это, при загрузке poc.png можно выполнить команду 'touch /tmp/aaaaa', а заменив команду в POC-файле на реверс-шелл, можно получить доступ к оболочке.
После загрузки файла подключитесь к docker, перейдите в /tmp и убедитесь, что по команде был создан файл aaaaa.
command = ["gs",
"-q", # тихий режим (минимум вывода)
"-g%dx%d" % size, # размер выходного изображения (в пикселях)
"-r%fx%f" % res, # разрешение входного изображения (DPI)
"-dBATCH", # автоматическое завершение после выполнения
"-dNOPAUSE", # непрерывное выполнение без пауз между страницами
"-dSAFER", # включение безопасного режима
"-sDEVICE=ppmraw", # установка устройства вывода в ppmraw
"-sOutputFile=%s" % outfile, # путь к выходному файлу
"-c", "%d %d translate" % (-bbox[0], -bbox[1]),
# коррекция начала координат изображения (сдвиг)
"-f", infile, # входной файл
]
try:
with open(os.devnull, 'w+b') as devnull:
subprocess.check_call(command, stdin=devnull, stdout=devnull)
im = Image.open(outfile)

Данная уязвимость произошла в библиотеке Python Imaging Library (PIL) и была проанализирована как CVE-2017-8291. Уязвимость вызвана тем, что PIL определяет тип изображения на основе заголовка файла, а не его расширения. Это позволяет загрузить файл с расширением .png, который на самом деле является EPS-файлом, содержащим произвольные команды. При вызове GhostScript на стороне сервера эти команды выполняются.
В ходе проекта была загружена подделанная poc.png, что привело к созданию файла /tmp/aaaaa внутри сервера. Таким образом, подтверждено, что уязвимость может привести к выполнению команд (RCE, Remote Code Execution). Кроме того, данная уязвимость может быть расширена до более продвинутых атак, таких как реверс-шелл, путём злоупотребления изначально предназначенной функцией обработки изображений.