Security - Real World/Reversing

Windows Kernel Hooking - I-1

PS리버싱마크해커박종휘TV 2024. 1. 6. 21:55

이전 글을 보고 오는 것이 좋다.

 

이전에 내가 후킹을 시도하여서 프로그램이 시작이 안 되거나, 컴퓨터를 종료할 수 없는 등 후킹 성공의 증후가 보였지만 이것이 진정 후킹을 성공했다고 보기엔 어려워서, 이참에 제대로 된 후킹을 하나 만들자고 결심하였다.

 

알고리즘을 작성해보자면

1. 전달되는 PID가 특정 PID와 같은지 비교한다. (이는 실제 상황에서 보호하려는 프로세스에 대응된다.)

2. 같다면, Invalid Handle Value를 반환한다.

3. 다르다면, 본래 로직을 수행한다.

 

여기서 문제가 되는 부분은 3번의 로직이다. 우리는 3번의 과정을 구체화할 필요가 있다.

1. 후킹된 함수를 본래 함수로 바꾼다.

2. 실행하고, 반환값을 받는다.

3. 본래 함수를 다시 후킹한다.

4. 받은 반환값을 반환한다.

 

이를 코드로 작성하면 다음과 같다.

 

NTSTATUS HookFunction(
	OUT PHANDLE ProcessHandle,
	IN ACCESS_MASK DesiredAccess,
	IN POBJECT_ATTRIBUTES ObjectAttributes,
	IN PCLIENT_ID ClientId OPTIONAL) {

	if (ClientId->UniqueProcess == (HANDLE)6974) {
		*ProcessHandle = (HANDLE)0x6974;
		return STATUS_SUCCESS;
	}

	WriteMemoryRO(function, &original, sizeof(original));
	auto ret = NtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
	WriteMemoryRO(function, &payload, sizeof(payload));
	return ret;
}

 

실제로 드라이버를 매핑하여 보면, 모든 시스템이 정상적으로 작동되는 것을 확인할 수 있고, 미리 선언된 PID로 접근할 시, 미리 설정한 Handle Value가 나오는 것을 확인할 수 있다.

 

Figure I. Invalid value

 

이와 반대로 Program.exe에 OpenProcess를 시도할 시 반환값이 정상인 것을 확인할 수 있다.

 

Figure II. Good value

 

사용한 프로그램의 소스 코드는 다음과 같다.

 

#include <Windows.h>
#include <cstdio>
#include <Psapi.h>
#include <Tlhelp32.h>

int main() {
       
    printf_s("You want to \'snitch\' process? Here you are...\n");
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        return 1;
    }

    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First(hProcessSnap, &pe32)) {
        CloseHandle(hProcessSnap);
        return 1;
    }

    do {
        wprintf_s(L"Process Name: %s, ", pe32.szExeFile);
        printf_s("PID: %d\n", pe32.th32ProcessID);
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);

    printf_s("WHAT PROCESS DO YOU WANT TO \'SNITCH\'?\n");

    DWORD what;
    scanf_s("%d", &what);
    HANDLE handle;
    if (handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, what)) {
        printf("Success!\n");
        printf("Handle: %p", handle);
    }
    else {
        printf("You failed! (it\'s actually success lol)\n");
    }

    return 0;
}

 

다음에는 지금까지 배운 Basic Kernel Hooking을 가지고 VAC를 우회하여 csgo2 핵을 작성할 시간이다.

'Security - Real World > Reversing' 카테고리의 다른 글

Windows Kernel Hooking - Part 3  (2) 2024.12.06
Windows Kernel Hooking - II-1  (1) 2024.01.10
Windows Kernel Hooking - II  (1) 2024.01.08
Windows Kernel Hooking - I  (2) 2024.01.04