Обходим Application Control через NTVDM

В рамках развития своей пентестерской деятельности заинтересовался такой областью, как защищенность банкоматов. Как все, наверное, знают, в большинстве случаев на сколько-нибудь современных банкоматах, стоят те или иные версии ОС Windows: от XP до 10 (в том числе Embedded/IoT редакции). В ОС запущен некий набор банковских приложений, а также реализованы дополнительные меры защиты, как, например, контроль работы приложений (Application Control). Об одном из способов обхода этой защиты и будет этот пост.

Способов обхода контроля запускаемых приложений существует большое количество и их применимость/не применимость зависит от грамотности произведенной настройки и используемых средств. Прежде тем перечислить основные способы обхода, я перечислю основные признаки, которые используются для контроля легитимности запускаемого приложения:
— полный/частичный путь к файлу приложения или директории;
— контрольная сумма файла (MD5, SHA-1 и т.д.);
— криптографическая подпись файла.

Вышеперечисленные методы используются в комбинации с белыми/черными списками приложений, а также доступных для запуска расширений. Теперь перейдем к способам обхода:
— выполнение в контексте доверенных приложений (cmd, NTVDM и т.д.) / интерпретаторов (Java, PHP и т.д.);
— коллизии хэш-функций;
— DLL hijacking.

Также можно отметить обход черного списка расширений (редкие расширения, про которые не все помнят, вроде .scr, .com) и использование уязвимостей в самих защищающих продуктах (не AppLocker'ом едины) / в установленном ПО. Подробнее о вышеперечисленных вещах можно узнать из тематических докладов со всевозможных конференций или обратиться к yarbabin, как к автору одного из материалов по теме.
Вернемся к сути статьи: рассмотрим подробнее способ обхода через выполнение в контексте доверенного приложения, а конкретнее - NTVDM. В контексте NTVDM в современных x86-версиях Windows (а нештатным образом и в x64 - https://github.com/leecher1337/ntvdmx64) исполняются 16-разрядные приложения.
Если вы думаете, что 16-разрядные приложения - это исключительно прерывания, ассемблер и примитивные операции времен MS-DOS, то это не так. Во времена Windows 3.11 и позднее можно было создавать 16-разрядные приложения с использованием WinAPI, причем из такого приложения никто не мешает загрузить 32-разрядную динамическую библиотеку, которая будет исполнять произвольный код, разработанный в привычной для современного разработчика среде. Такой вот тривиальный и относительно известный способ обхода.
Ниже я приведу пример кода для старой среды разработки Microsoft Visual C 1.52 (последняя версия, которая позволяла собирать 16-разрядные файлы, если верить Wiki) реализуюший вышеописанную задачу.
Итак, нам понадобятся: загрузочная дискета Windows 95, образ Windows 95 и Microsoft Visual C 1.52c. После установки ОС и среды разработки на виртуальную машину, запускаем среду и копируем туда следующий код:

Код довольно примитивен: мы просто вызываем штатные, но не слишком известные модификации методов LoadLibrary и FreeLibrary для 32-разрядных приложений из 16-разрядного, а также используем макрос DECLARE_HANDLE32. Что он из себя представляет? Да в общем-то ничего особенного:

Стандартный легаси-макрос, который знаком только бородатым программистам. Кстати, вы можете спросить, зачем я вызываю FreeLibrary32W в конце кода, хотя казалось бы, после завершения процесса динамическая библиотека и так будет выгружена - отнюдь. В данном случае все работает несколько иначе. После запуска вышеописанного кода, библиотека подгружается в контексте процесса ntvdm.exe, однако, после завершения работы она не выгружается.

Скорее всего это связанно либо с тем, что разработчики не захотели заморачиваться, либо с организацией памяти системы в старых версиях Windows, которая существовала вплоть до Windows NT, аутентичная эмуляция так сказать.
Теперь давайте скомпилируем наше приложение и проверим его работоспособность. Для этого просто выберем из меню среды разработки Options->Project->QuickWin application (.EXE), а также Build Mode - Release.

После этого нажмем Shift+F8 или через меню Project->Build ***. Формат QuickWin application был выбран из-за простоты и отсутствия необходимости создавать проект, хоть и добавляет солидный по тем временам оверхед: результирующий файл получился размером ~ 43 КБ.
Перенесем полученный файл на целевую систему и попробуем его запустить, указав в качестве аргумента имя 32-разрядной динамической библиотеки, расположенной в той же директории, что и запускаемый файл (DLL, которая выводит Hello World, можно взять отсюда или собрать самому).

Ожидаемый результат получен, DLL была подгружена в процесс ntvdm.exe, а процесс с именем нашего исполняемого файла (кстати, файлу можно изменить расширение, например, на .com) технически так и не был создан. Успех.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *