06.05.2013

»нжект DLL в современных Metro-приложени€х

image

»жект DLL Ц одна из самых старых техник, используема€ дл€ выполнени€ своего кода в приложени€х в ќ— Windows. ќбычно этот метод используетс€ дл€ изменени€ стандартного поведени€ приложени€ или добавлени€ нового функционала.

јвтор: Mauro Leggieri

»жект DLL – одна из самых старых техник, используема€ дл€ выполнени€ своего кода в приложени€х в ќ— Windows. ќбычно этот метод используетс€ дл€ изменени€ стандартного поведени€ приложени€ или добавлени€ нового функционала.

»нжект DLL в процесс Ц относительно проста€ задача: необходимо создать удаленный поток, где будет вызыватьс€ LoadLibrary, использу€ метод CreateRemoteThread или NtCreateThreadEx. ƒл€ получени€ доступа к инжектируемому процессу вам необходимы некоторые привилегии, однако их получение выходит за рамки этой статьи.

 огда вы попытаетесь инжектировать библиотеку в Metro-приложение в Windows 8, то обнаружите, что хот€ инжектируемый код и работает корректно, ваша DLL Ќ≈ загрузитс€. ћетод LoadLibrary возвратит FALSE, и метод GetLastError возвратит ERROR_ACCESS_DENIED.

Ќу, подумаете вы… —овременные UI-приложени€ имеют ограниченные доступ к ресурсам системы и запускаютс€ в «песочнице», так что подобные проблемы ожидаемы.

¬о врем€ исследовани€ методов по добавлению нового функционала в приложение Windows Mail, поставл€емое вместе Windows 8, и перехвату функций в современных UI-приложени€х посредством Deviare, нам нужно вы€снить, почему LoadLibrary возвращает FALSE.

Ќа сцену выходит реверс-инжиниринг

ћы начнем с анализа метода LoadLibrary. ќн вызывает LoadLibraryEx с dwFlags=0 и выполн€ет некоторые проверки. ѕерва€ остановка.

≈сли вы хотите загрузить упакованный объект (package), то должны использовать LoadPackagedLibrary API. ≈сли вы хотите загрузить обычную DLL, то должны использовать LoadLibrary[Ex]. ¬ документации на LoadPackagedLibrary говоритс€ о том, что путь не может быть абсолютным или содержать Ђ..ї, однако эти проверки в основном делаютс€ в методе LoadLibraryEx. ≈динственное отличие между LoadLibrary и LoadPackagedLibrary - в параметре dwFlags, который равен 4 или 0.

 роме того, LoadLibraryEx будет формировать поисковый путь дл€ обнаружени€ DLL, а затем вызовет недокументированный метод LdrLoadDll. ѕоскольку мы хотим напр€мую указать путь к библиотеке, то, соответственно, сразу будем вызывать метод LdrLoadDll.

¬тора€ попытка:

’от€ LdrLoadDll корректно нашел DLL, при использовании SpyStudio дл€ проверки ошибок, мы обнаружили, что при вызове метода NtOpenFile возникла ошибка STATUS_ACCESS_DENIED. ћы установили, что это проблема имеет отношение к безопасности.

»спользу€ утилиту icacls.exe, мы установили дополнительные привилегии на DLL-файл, чтобы позволить чтение и запуск в процессах с низким уровнем достоверности (low integrity processes). “акже мы добавили нового пользовател€ в Windows 8 с именем ЂALL APPLICATION PACKAGESї в список пользователей с правами на чтение и запуск DLL-кода.

“реть€ попытка:

NtOpenFile выполнил начальные проверки безопасности, однако DLL все равно не загружена.

ѕродолжа€ исследовать LdrLoadDll, мы перешли в режим €дра из NtCreateSection API и вы€снили, что функци€ CiValidateImageHeader библиотеки ci.dll возвращает ошибку STATUS_INVALID_IMAGE_HASH, после чего мы добавили цифровую подпись к файлу. ƒл€ предупреждени€ будущих проблем, вместо самоподписанного сертификата, мы использовали насто€щий.

“еперь с функцией CiValidateImageHeader все ок, но далее функци€ CiValidateImageData возвращает ту же самую ошибку. ƒалее мы добавили параметр /ph при использовании утилиты SignTool.exe дл€ включени€ страниц хэшей в подписываемый процесс.

„етверта€ попытка:

Ќу, подумали мы: теперь DLL подписана, с привилеги€ми все ок. ѕопробуем еще раз.

» вновь ошибка.

Ќа этот раз камнем преткновени€ стала функци€ SeGetImageRequiredSigningLevel, котора€ находитс€ в ntoskrnl.exe. SeGetImageRequiredSigningLevel провер€ет минимальные требовани€ к сертификату при загрузке DLL внутри WinRT-приложени€.

ћы решили, что нужно подписать нашу DLL кросс-сертификатом, который используетс€ дл€ подписи драйверов режима €дра.

¬ывод:

»сследовани€ были остановлены, поскольку на данный момент у нас нет кросс-сертификата, однако мы обнаружили, что один из параметров €дра определ€ет, какой тип сертификата провер€етс€ функцией SeGetImageRequiredSigningLevel.

¬ этом посте объ€сн€етс€ метод ручного обхода посредством WinDbg защитных проверок и запуска недостоверных приложений в устройстве Surface. —леду€ схожей процедуре, мы можем обойти защитные проверки и корректно смапировать и заинжектить DLL в WinRT-приложени€х в версии Windows дл€ настольных ѕ .

ѕеред началом нашего исследовани€, у нас уже был рабочий метод по инжекту DLL в WinRT-приложени€х: нужно скопировать DLL-файл в папку System32. ’от€ дл€ этого и нужны права администратора, но в этом случае вы можете использовать метод LoadLibrary без указани€ пути к библиотеке, поскольку System32 €вл€етс€ папкой, где по умолчанию происходит поиск библиотек.   тому же, поскольку вы используете относительный путь, некоторые проверки безопасности отмен€ютс€. ≈ще один плюс Ц вам не нужно подписывать файл!

ќднако мы, как и множество компаний, хотим избежать разрастани€ папки System32 и храним файлы в той же директории, где находитс€ приложени€. »менно поэтому мы и начали наше исследование.†

или введите им€

CAPTCHA