미친해커

[Reversing] Code Injection Step 1 본문

Reversing/Code Injection

[Reversing] Code Injection Step 1

미친해커 2022. 4. 5. 17:44
반응형

Code Injection 기법은 사실상 ShellCode Injection 이라고 불러도 될 만큼 동작 방식이 매우 비슷하다. 하지만 우리는 주입할 코드를 ShellCode가 아닌 C언어 함수로 작성해 주입할 것이다.

1. 주입할 함수 작성

/*
주입되는 코드는 CreateRemoteThread API를 통해 실행되기 때문에
아래와 같은 형식을 반드시 지켜줘야 한다. (함수명은 관계 없음)
*/
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    // 계산기를 실행
    WinExec("calc.exe", SW_SHOW);
}

2. 코드 인젝션 함수 작성

BOOL CodeInjection(DWORD PID)
{
    // 타겟 프로세스의 핸들 획득 
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

    if (hProcess == NULL)
    {
        printf("OpenProcess Failed!\n");
        return FALSE;
    }

    // 주입할 함수의 사이즈를 계산
    SIZE_T ThreadProcSize = (ULONGLONG)AtherFunc - (ULONGLONG)ThreadProc;

    // 타겟 프로세스에 공간 할당
    PVOID ThreadProcAddress = VirtualAllocEx(hProcess, NULL, ThreadProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    // 할당된 공간에 ThreadProc 함수 작성
    if (WriteProcessMemory(hProcess, ThreadProcAddress, (LPCVOID)ThreadProc, ThreadProcSize, NULL) == FALSE)
    {
        printf("WriteProcessMemory Failed!\n");
        return -1;
    }

    // 쓰레드 생성 및 실행
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcAddress, NULL, 0, NULL);

    if (hThread == NULL)
    {
        printf("CreateRemoteThread Failed\n");
        return FALSE;
    }

    printf("Code Injection Success!\n");
    return TRUE;
}

완성된 코드

#include <stdio.h>
#include <windows.h>

/*
주입되는 코드는 CreateRemoteThread API를 통해 실행되기 때문에
아래와 같은 형식을 반드시 지켜줘야 한다. (함수명은 관계 없음)
*/
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    // 계산기를 실행
    WinExec("calc.exe", SW_SHOW);
}
int AtherFunc() {} // ThreadProc 함수의 사이즈를 구하기 위해 아무런 기능을 하지 않는 함수를 정의

BOOL CodeInjection(DWORD PID)
{
    // 타겟 프로세스의 핸들 획득 
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

    if (hProcess == NULL)
    {
        printf("OpenProcess Failed!\n");
        return FALSE;
    }

    // 주입할 함수의 사이즈를 계산
    SIZE_T ThreadProcSize = (ULONGLONG)AtherFunc - (ULONGLONG)ThreadProc;

    // 타겟 프로세스에 공간 할당
    PVOID ThreadProcAddress = VirtualAllocEx(hProcess, NULL, ThreadProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    // 할당된 공간에 ThreadProc 함수 작성
    if (WriteProcessMemory(hProcess, ThreadProcAddress, (LPCVOID)ThreadProc, ThreadProcSize, NULL) == FALSE)
    {
        printf("WriteProcessMemory Failed!\n");
        return -1;
    }

    // 쓰레드 생성 및 실행
    HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcAddress, NULL, 0, NULL);

    if (hThread == NULL)
    {
        printf("CreateRemoteThread Failed\n");
        return FALSE;
    }

    printf("Code Injection Success!\n");
    return TRUE;
}

int main(int argc, char *argv[])
{
    DWORD PID = 0;
    printf("PID : ");
    scanf("%d", &PID);

    CodeInjection(PID);
}

 

위 코드를 빌드하기 전 다음과 같은 설정을 해준다.

  • 빌드 최적화 옵션 해제
  • Release 모드로 빌드

빌드 후에 프로그램을 실행해 타겟 프로세스의 PID를 입력한다. 그럼 계산기가 뜨지 않고 타겟 프로세스가 오류를 띄우며 종료된다. 그게 정상이다.

타겟 프로세스로 삼은 메모장이 EXCEPTION_ACCESS_VIOLATION 에러를 띄우며 디버거를 띄운 모습

왜 이런 현상이 발생할까? 그 이유는 다음 포스팅에서 알아보자

반응형

'Reversing > Code Injection' 카테고리의 다른 글

[Reversing] Code Injection Step 2  (0) 2022.04.07
[Reversing] Code Injection Step 0  (0) 2022.04.04
Comments