Содержание статьи
Исторический экскурс
Все началось еще в 2010 году, когда в паблике всплыл эксплоит для Windows версий 7 и ниже. Эксплоит позволял атакующему выполнить произвольный код в системе, причем пользователю достаточно было всего лишь перейти по ссылке.
Этот эксплоит использовался как один из вариантов распространения небезызвестного червя Stuxnet. Когда кто-то вставлял флешку в компьютер, червь заражал ее, копируя вредоносный DLL, и создавал специальный ярлык. Если на машине, в которую потом вставляли носитель, была включена функция автозапуска, вредоносный код из библиотеки выполнялся.
Импакт при этом не ограничивался одной только флешкой: код также срабатывал, если пользователь посещал вредоносный URL, который указывал на сетевую или локальную папку с эксплоитом.
Взглянув на весь этот ужас, в Microsoft выпустили апдейт MS10-046, который исправляет эту уязвимость. Вот только получилась заплатка не то чтобы удачной.
В начале января 2015 года немецкий исследователь Михель Герклоц (Michael Heerklotz) детально изучил этот патч и нашел способ его обойти. Результатом работы Герклоца стал отчет на конференции Zero Day Initiative (ZDI), проводимой компанией HP. После исправления патча в марте того же 2015 года исследование было опубликовано. Имеется даже видеодемонстрация работы эксплоита.
После этого в Microsoft выкатили следующий патч — с порядковым номером MS15-018, однако и он не смог полностью закрыть уязвимость. Совсем недавно, в июне 2017 года, был обнаружен очередной способ его обхода. Импакт при этом остался тем же — выполнение произвольного кода на целевой системе.
Уязвимость откликается на CVE-2017-8464, а PoC-эксплоит создали Йорик Костер (Yorick Koster) и nixawk. Йорик также написал модуль для Metasploit. MSF я не использую по религиозным соображениям и поэтому в обзоре буду опираться на первоначальный сплоит. Найти его ты сможешь, заглянув в репозиторий к nixawk.
Если же хочешь просто потриггерить уязвимость, то здесь есть готовые LNK-файлы и DLL, которая запускает калькулятор. Тебе остается лишь скинуть их на флешку.
WARNING
Материал адpесован специалистам по безопасности и тем, кто собираeтся ими стать. Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Стенд
В качестве подопытного кролика для теста уязвимости я буду использовать виртуалку с Windows 10 х64.
При работе с бинарщиной нам, конечно же, пригодится дизассемблер. Не будем оригинальничать и возьмем IDA.
Также нам понадобится какой-нибудь дебаггер. Я решил использовать WinDbg в режиме отладчика ядра. Вот один из способов настроить удаленный дебаггинг виртуалки.
-
Запустить WinDbg. Затем File → Kernel Debug. Там во вкладке NET нужно указать порт. Его будет слушать программа в ожидании подключения от отлаживаемой системы. Еще можно указать ключ для шифрования передаваемых данных во время соединения.
-
Включить режим отладки на гостевой машине. В этом нам поможет консольная утилита
bcdedit
.bcdedit /debug on bcdedit /dbgsettings net hostip:127.0.0.1 port:50000 key:time.to.debug.1337
где hostip
— IP хостовой ОС, port
и key
— порт и ключ, которые ты указал в настройках WinDbg. После перезагрузки виртуалки она подключится к отладчику.
Особенности линкования
Чтобы понимать уязвимость и успешно ее проэксплуатировать, нужно сначала разобраться непосредственно с самим форматом LNK-файлов. К счастью, нам не придется продираться через дебри бинарщины вслепую, потому что ребята из Microsoft позаботились и написали подробную техническую спецификацию под названием Shell Link (.LNK) Binary File Format. Будем заглядывать туда периодически.
Еще нам понадобится утилита для просмотра детальной информации по файлам LNK. Так как моя основная ОС — это Windows 10, то я воспользуюсь приложением LNKParser. Если ты ищешь что-то платформонезависимое, то попробуй модуль pylnk (pip install pylnk
) для Python.
Shell Link Binary File Format состоит из последовательности структур, которые регулируются правилами ABNF (Augmented Backus-Naur Form). Правила же описаны в спецификации RFC5234.
SHELL_LINK = SHELL_LINK_HEADER [LINKTARGET_IDLIST] [LINKINFO] [STRING_DATA] *EXTRA_DATA
Совокупность этих структур и называется shell link, а в простонародье — «ярлык».
В нем содержится не только ссылка на местоположение объекта, как можно было ожидать, но и множество других параметров.
Рассмотрим все это на живом примере. Для этого создадим ярлык на любой файл (я создал для explorer.exe) и натравим на него LNKParser.
lnk_parser_cmd "explorer.exe - Shortcut.lnk"
Здесь я рассмотрю только нужные для создания эксплоита структуры, ты же можешь покопаться в тонкостях строения .LNK в свое удовольствие.
За загрузку, анализ и парсинг данных из файла ярлыка отвечает функция CShellLink::_LoadFromStream
из библиотеки windows.storage.dll
.
Первый обязательный блок, который должен присутствовать в каждом уважающем себя LNK-файле, — это SHELL_LINK_HEADER
. По большому счету это единственная обязательная структура в ярлыке. Она содержит идентификационную информацию, временные метки и флаги, которые определяют наличие или отсутствие дополнительных блоков с информацией, включая LinkTargetIDList
, LinkInfo
и StringData
.
Пройдемся по остальным структурам.
HeaderSize
(4 байта) — размер блока Header, он фиксированный —0x0000004C
.LinkCLSID
(16 байт) — уникальный идентификатор класса (CLSID). Структура CLSID — это оболочка для идентификатора COM-класса. Также имеет фиксированное значение —00021401-0000-0000C000-000000000046
.LinkFlags
(4 байта) — флаги, которые отвечают за опции ярлыка. Некоторые флаги означают наличие дополнительных структур в файле.FileAttributes
(4 байта) — атрибуты файла, на который ссылается ярлык.CreationTime
(8 байт),AccessTime
(8 байт),WriteTime
(8 байт) — время создания файла, последнего доступа к нему и его изменения.FileSize
(4 байта) — размер файла. Формат — 32-битное беззнаковое целое.IconIndex
(4 байта) — индекс иконки файла в указанном хранилище. Формат — 32-битное беззнаковое целое.ShowCommand
(4 байта) — вид окна приложения, запущенного через ярлык. Формат — 32-битное беззнаковое целое. Он может быть трех видов: нормальный (SW_SHOWNORMAL
,0x00000001
), развернутый на весь экран (SW_SHOWMAXIMIZED
,0x00000003
), свернутый (SW_SHOWMINNOACTIVE
,0x00000007
).HotKey
(2 байта) — структураHotKeyFlags
отвечает за назначенные ярлыку горячие клавиши. В настройках линка ты можешь указать требуемое сочетание клавиш, и если сам LNK лежит на рабочем столе или в меню, то при их нажатии он будет срабатывать.Reserved1
(2 байта),Reserved2
(4 байта),Reserved3
(4 байта) — зарезервированные значения. Должны быть нулевыми.
Из всего этого многообразия нас интересует только LinkFlags
. Секция состоит из 32 бит, каждый из которых отвечает за разные опции ярлыка.
Нужные нам биты — это 0 (HasLinkTargetIDList
) и 7 (IsUnicode
).
С IsUnicode
, думаю, все ясно из названия, а вот нулевой бит рассмотрим подробнее.
Флаг HasLinkTargetIDList
указывает, что следующим блоком, идущим за хидером, будет структура IDList
.
Функция CShellLink::_LoadIDList
сначала читает первые два байта данных из блока (это размер структуры) и выделяет требуемое количество памяти для его загрузки.
Затем начинается чтение данных из LINKTARGET_IDLIST
. Каждый элемент этой структуры — это часть пути до объекта, на который ссылается ярлык. Система проходит по каждому такому элементу ItemID
и читает его данные.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»