Результаты, были получены на Windows XP SP3 x86. Сама уязвимость находится в функциях FindFirstFileExW и FindNextFileExW библиотеки kernel32.dll, которые осуществляют копирование данных, полученных из нативной функции NtQueryDirectoryFile, с помощью memmove. Проблема заключается в том, что в качестве размера буфера-источника для функции копирования передается число, полученное из NtQueryDirectoryFile, хотя возможна ситуация, при которой размер буфера-приемника может быть меньше, чем результат выдачи NtQueryDirectoryFile.
Влияние данной уязвимости распространяется на все приложения, использующие функции семейства FindFirstFile/FindNextFile. Первым таким приложением, которое пришло мне в голову, было explorer.exe. Для эксплуатации злоумышленнику достаточно будет заставить пользователя открыть ссылку на зловредный ресурс, и при удачном исходе он сможет получить возможность исполнить код с правами пользователя, открывшего ссылку. Сценарий удаленной эксплуатации, как подсказывает раздел FAQ бюллетеня Microsoft, возможен через UNC share или через WebDAV-путь. Путь UNC (Universal Naming Convention) может указывать на сетевой ресурс обмена файлами, который работает на основе протокола SMB. Для теста был выбран Linux с сервисом Samba, который позволяет создавать «расшаренные» папки на основе этого протокола. В итоге хотелось смоделировать следующую схему удаленной атаки.
На платформе Linux существует схожее ограничение (только не на длину пути, а на длину имени файла), равное 255 символам. Для того чтобы передать уязвимой Windows-машине листинг каталога с именами файлов, длина которых превышает 255 символов, можно просто поправить исходники Samba-сервера. Одним из мест внедрения вредоносного имени может быть функция smbd_marshall_dir_entry из trans2.c (Samba 3.6.6), которая частично формирует выдачу сервера. Для первого теста имя файлов выдачи расширялось на 0x100 байт и заполнялось константой 0xfeeddead. При попытке зайти на модифицированный сервер с уязвимой машины можно наблюдать следующую картину.
Как видно на скриншоте, explorer.exe попытался прочесть dword по адресу из подконтрольного регистра EDX. Прочитанное значение участвует в формировании адреса, по которому происходит вызов. Если подняться по call-стеку на уровень выше, то можно заметить, что первые два параметра функции RecentDocs_Enum являются подконтрольными, к тому же оба они передаются далее. Перезапись этих значений возможна из-за их расположения в куче (схема представлена ниже).
В функции CFSFolder_CreateEnum выделяется память размера 0x498 под экземпляр класса CFileSysEnum; в данном чанке со смещением 0x224 расположена структура WIN32_FIND_DATA. Указатель на данную структуру передается в уязвимую функцию FindFirstFileEx, которая перезаписывает значения, позволяющие осуществить перехват управления.
Для эксплуатации данной уязвимости нужно провести heap spray. Объектами для заполнения кучи в данном случае будут имена файлов, получаемые компонентом CShellBrowser2. Следовательно, для проведения heap spray необходимо создать большое количество файлов на общем сетевом ресурсе. Схема атаки представлена на рисунке ниже. Примечание: в данной схеме не учтена система Data Execution Prevention (DEP); шеллкод, как можно видеть, находится в куче, которая должна быть неисполняемой.
Одна из проблем проведения атаки — фрагментация ответа сервера на несколько SMB-пакетов. В драйвере mrxsmb.sys, который отвечает за работу протокола SMB, есть функция MrxSmbUnalignedDirEntryCopyTail. Данная функция проверяет длину полученных имен, которые передаются в пользовательский режим, и при превышении границы в 0x200 байт выведет ошибку STATUS_INVALID_NETWORK_RESPONSE (0xC00000C3), а получив ошибку, NtQueryDirectoryFile перестанет выдавать имена для FindNextFile.
Эту проверку можно обойти следующим образом. Сначала следует создать набор файлов, которые осуществят heap spray, а потом удалить из каталога все файлы и создать один файл, имя которого будет являться триггером уязвимости. Сервер Samba в случае изменения в файловой системе при подключенном клиенте отправит пакет с функцией NT_NOTIFY, который заставит клиента повторить запрос FIN_FIRST2 на сервер, — получив только одно вредоносное имя. При этом имена файлов, полученных ранее, останутся в памяти. Кроме того, можно контролировать порядок расположения имен, поскольку они отсортированы по имени. Стоит также заметить, что имена, получаемые с Samba-сервера, должны быть уникальными; это можно обеспечить, выделив на уникальный идентификатор 5 байт из основного поля имени файла.
Стоит заметить, что транспорт имен файлов осуществляет взаимодействие по протоколу SMB в двухбайтовом юникоде.
Это накладывает определенные ограничения на адреса, которые перезаписываются на уязвимом клиенте, но поскольку модификация выдачи Samba-сервера происходит уже после конвертации из однобайтового в двухбайтовые символы, эти ограничения несущественны — хотя и вносят некоторую сложность в процесс работы модифицированного сервера. Посылая большой пакет данных, сервер разбивает его на части, а клиент после получения очередной такой части данных выдает серверу имя, начиная с которого ему необходимо продолжить выдачу (см. рис. ниже).
Поскольку при проведении heap spray выдаются нереальные данные, то и имя, с которого надо продолжить выдачу, тоже будет нереальным, и потому необходимо отображать полученное continue_name в реальное имя на сервере, с которого необходимо продолжить.
В итоге полученная конструкция позволяет выполнять код на уязвимой машине с вероятностью приблизительно 1/7. В заключение можно сказать, что уязвимость вполне может быть проэксплуатирована «в дикой природе», хотя для создания боевого эксплойта придется решить проблему с DEP, а также оптимизировать heap spray (для повышения вероятности успешного выполнения).
ссылка на оригинал статьи http://habrahabr.ru/company/pt/blog/166939/
Добавить комментарий