Следующая новость
Предыдущая новость

Обзор эксплоитов. Критические баги в vBulletin, InfluxDB и Django

19.12.2019 14:42
Обзор эксплоитов. Критические баги в vBulletin, InfluxDB и Django

Содержание статьи

  • RCE через загрузку аватара в vBulletin
  • RCE через виджет в vBulletin
  • Обход аутентификации в InfluxDB
  • SQL-инъекция в Django

Сегодня мы поговорим сразу о нескольких уязвимостях. Одна из них была найдена в популярном форумном движке vBulletin и позволяет атакующему выполнять произвольный код, не имея никаких прав, — от такого безобразия его отделяет лишь один POST-запрос. Также я потреплю старичка Django в поисках SQL-инъекций и покажу, как работает обход авторизации в базе данных InfluxDB.

2019 год подходит к концу, все начинают усиленно готовиться к праздникам. Безопасники добивают свои последние аудиты, которые из года в год наваливаются в эту пору. Неудивительно — ведь фискальный год тоже подходит к концу, а бюджеты еще не до конца потрачены!

После таких плодотворных недель кругом начинается затишье, и это касается в том числе информационной безопасности. Не так много уязвимостей и активностей приходится на конец декабря и начало января. Поэтому сейчас самое время вспомнить баги, которые, возможно, остались незамеченными в течение года.

Они просты по своей сути, однако это не мешает им иметь критический статус. Одни дают возможность выполнить произвольный код, другие — получить доступ к чувствительным данным или вовсе захватить полный доступ к системе. В этом году сильно досталось коммерческому форумному движку vBulletin: сразу несколько опасных багов было найдено в последних его версиях во второй половине года. С них и начнем.

RCE через загрузку аватара в vBulletin

Автор: Эджидио Романо (Egidio Romano aka EgiX)
Дата релиза: 4.10.2019
CVE: CVE-2019-17132
Уязвимые версии: vBulletin <= 5.5.4

Чтобы более предметно разговаривать о найденной проблеме, нужно поднять стенд и посмотреть на нее поближе. Так как vBulletin — коммерческое приложение, я предлагаю тебе самостоятельно решить, каким образом его найти.

В качестве базы данных будем использовать MySQL, а в качестве веб-сервера — докер-контейнер на основе Debian.

docker run -d -e MYSQL_USER="vb" -e MYSQL_PASSWORD="EAQhaTXieg" -e MYSQL_DATABASE="vb" --rm --name=mysql --hostname=mysql mysql/mysql-server:5.7 docker run --rm -ti --link=mysql --name=websrv --hostname=websrv -p80:80 debian /bin/bash 

Устанавливаем стандартный набор из Apache2 и PHP.

apt update && apt install -y apache2 php nano php-mysqli php-xml php-gd 

После этого можно запускать веб-сервер.

service apache2 start 

Теперь устанавливаем vBulletin, я буду использовать версию 5.4.3.

Установка vBulletin версии 5.4.3

По дефолту загруженные файлы хранятся в базе данных, такое поведение совместимо с эксплуатацией уязвимости. Поэтому сначала нужно зайти в настройки и поменять место хранения аватаров.

Обзор эксплоитов. Критические баги в vBulletin, InfluxDB и Django
Меняем место хранения загруженных аватаров пользователей в vBulletin

Загружается аватар через отправку запроса POST на /profile/upload-profilepicture.

POST /profile/upload-profilepicture HTTP/1.1 Host: web.fh Connection: keep-alive Accept: application/json, text/javascript, */*; q=0.01 X-Requested-With: XMLHttpRequest Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2V36WCZNIGxAuYwu Cookie: сессионные_куки_  ---WebKitFormBoundary2V36WCZNIGxAuYwu Content-Disposition: form-data; name="profilePhotoFile"; filename="orange_box.png#26759185" Content-Type: image/png  содержимое_файла ---WebKitFormBoundary2V36WCZNIGxAuYwu Content-Disposition: form-data; name="securitytoken"  CSRF-токен ---WebKitFormBoundary2V36WCZNIGxAuYwu-- 

Если здесь просто попытаться загрузить PHP-файл, то ничего не выйдет. Расширение файла определяется библиотекой, которая работает с картинками. Если переданный документ не будет картинкой, то скрипт просто прекратит свою работу с ошибкой not_an_image.

core/vb/library/user.php
1335:   public function uploadAvatar($filename, $crop = array(), $userid = false, $adminoverride = false) 1336:   { ... 1339:       $isImage = $imageHandler->fileLocationIsImage($filename); 1340:       if ($isImage) 1341:       { ... 1359:           $fileInfo = $imageHandler->fetchImageInfo($filename); ... 1361:       else 1362:       { 1363:           // throw something useful here. 1364:           throw new vB_Exception_Api('not_an_image'); 1365:       } ... 1435:       $ext = strtolower($fileInfo[2]); 1436: 1437:       $dimensions['extension'] = empty($ext) ? $pathinfo['extension'] : $ext; ... 1485:                   'extension' => $dimensions['extension'], ... 1511:       $result = $api->updateAvatar($userid, false, $filearray, true); 

После всех манипуляций вызывается updateAvatar с параметрами аватара в $filearray.

Однако существует возможность напрямую вызвать этот метод API. Чтобы это сделать, нужно отправить запрос на эндпойнт ajax/api/user/updateAvatar.
Если заглянуть в тело метода updateAvatar, то можно обнаружить любопытный участок кода.

core/vb/api/user.php
4111:   public function updateAvatar($userid, $avatarid, $data = array(), $cropped = false) 4112:   { ... 4149:       if ($useavatar) 4150:       { 4151:           if (!$avatarid) 4152:           { ... 4166:               if (empty($data['extension'])) 4167:               { 4168:                   $filebits = explode('.', $data['filename']); 4169:                   $data['extension'] = end($filebits); 4170:               } 4171: 4172:               $userpic->set('extension', $data['extension']); ... 4182:                   $avatarfilename = "avatar{$userid}_{$avatarrevision}.{$data['extension']}"; ... 4186:                   $avatarres = @fopen("$avatarpath/$avatarfilename", 'wb'); ... 4187:                   $userpic->set('filename', $avatarfilename); 4188:                   fwrite($avatarres, $data['filedata']); 4189:                   @fclose($avatarres); 

Здесь расширение берется из массива $data, который можно просто передать в теле запроса. Оно будет иметь следующий вид:

userid=0&avatarid=0&data[extension]=<расширение_файла>&data[filedata]=<содержимое_файла>&securitytoken=<токен> 

Когда userid установлен в ноль, скрипт выбирает текущего авторизованного пользователя, а avatarid, равный нулю, говорит, что нужно загружать аватар, а не удалять.

Вот мы и подобрались к самой сути уязвимости. vBulletin не проверят должным образом параметры data[extension] и data[fildeata], и это позволяет творить чудесные вещи. Например, установим расширение php, а в data[filedata] передадим простой PHP-код.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

1 год

7690 р.

1 месяц

720 р.

Я уже участник «Xakep.ru»

Источник

Последние новости