| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- AWS 침해 사고 사례 분석
- AWS 보안 아키텍처 분석
- dreamhack
- 드림핵
- python
- network
- Amazon S3
- 파일 시스템
- AWS
- crackme
- 악성코드분석
- reversing.kr
- AWS 3 Tier Architecture
- 프로그래머스
- 리버싱
- C
- AWS 사고 사례 분석
- sql
- 악성코드 분석
- AWS 침해사고 사례 분석
- 버퍼 오버플로우
- terraform
- programmers
- Database
- 네트워크
- reversing
- 운영체제
- TryHackMe
- CrackMe 문제
- operating system
- Today
- Total
lhywk 님의 블로그
[악성코드 분석] 프로세스/코드 인젝션 본문
DLL 인젝션
강제 로드: 사용자가 만든 임의의 DLL 파일을 현재 실행 중인 다른 프로세스(Target Process)의 메모리 영역에 강제로 불러오게 만드는 기술이다.
기생(Parasite): 마치 기생충이 숙주에 들어가듯, 악성 코드가 정상 프로그램의 메모리 공간 안에 자리를 잡는 것이다.
메모리 보호 정책과 그 우회
기본 원칙 (보호): 현대 운영체제(Windows 등)는 프로세스 간의 독립성을 보장하기 위해, A 프로세스가 B 프로세스의 메모리에 함부로 접근하는 것을 차단한다.
우회 (Injection): DLL 인젝션은 이러한 보호 장벽을 우회하는 기법이다. 일단 DLL이 해당 프로세스 내부에 로드되면, 그 프로세스의 내부 구성원으로 취급받기 때문에 메모리 접근 권한을 획득하게 된다.

정당한 접근 권한 획득의 메커니즘
- 외부인에서 내부자로: 프로세스 밖에서 접근하려 하면 운영체제가 차단하지만, 일단 DLL 인젝션을 통해 프로세스 메모리 내부로 들어오면 해당 프로세스의 '구성원'으로 인정받는다.
- 메모리 공유: My.dll이 기존의 .text(코드), .data(데이터) 영역 및 kernel32.dll과 같은 공간에 공존하게 된다.
- 권한: 같은 메모리 공간을 쓰기 때문에, My.dll은 별도의 제약 없이 타겟 프로세스의 전역 변수(.data)를 읽거나 함수 코드(.text)를 변조할 수 있는 정당한 접근 권한(Access Right)을 갖게 된다.
공격의 목적
다른 프로세스의 메모리 영역에 접근할 수 있게 되면 다음과 같은 작업이 가능하다.
- 데이터 수정: 게임 내 돈이나 생명력을 조작하거나(Game Hack), 인증 과정을 무력화한다.
- 기능 변조: 프로그램의 원래 동작을 가로채거나(Hooking) 변경한다.
핵심 기술 - LoadLibrary()
공격자는 타겟 프로세스에게 "이 DLL을 로드해라"라고 명령을 내리는데, 이때 타겟 프로세스 내부에서 LoadLibrary() 함수가 호출되도록 유도한다.
DLL 인젝션 5단계 (실제 API 호출 순서)


1. 대상 프로세스 핸들 구하기 - OpenProcess
- 운영체제에게 "저 프로세스(dwPID) 좀 건드리고 싶으니 권한(Handle)을 달라"고 요청
- PROCESS_ALL_ACCESS: 읽기, 쓰기, 종료 등 모든 권한을 요청
- 결과: hProcess라는 핸들(열쇠)을 획득. 이후 모든 조작은 이 핸들을 통해 이루어진다.
2. 메모리 공간 할당 - VirtualAllocEx
- VirtualAllocEx를 호출하여 타겟 프로세스(hProcess)에 dwBufSize만큼의 공간을 빌리고, 그 시작 주소를 pRemoteBuf에 저장한다.
- 중요한 것은 단순히 공간만 만드는 게 아니라, 코드가 실행될 수 있도록 실행 권한 옵션을 함께 설정해야 한다는 점이다 (직접 코드 인젝션의 경우. DLL 경로 문자열만 쓸 때는 쓰기 권한이면 충분).
3. 데이터 쓰기 - WriteProcessMemory
- 어디에? hProcess의 pRemoteBuf 위치에.
- 무엇을? 내 프로세스에 있는 szDllName(DLL 경로 문자열)을.
- 얼마나? dwBufSize 크기만큼.
4. 로드 함수 주소 찾기 - GetProcAddress
- LoadLibrary를 직접 타겟 프로세스 안에서 실행시키려면, 타겟 프로세스 메모리 안에서 그 함수가 정확히 어디 있는지 알아야 한다.
- 그런데 윈도우 운영체제 구조상, 핵심 시스템 DLL인 kernel32.dll은 모든 프로세스에서 동일한 메모리 주소에 로딩된다.
- 따라서 공격자는 자기 자신의 프로세스에서 GetProcAddress를 호출하여 LoadLibrary의 주소를 구하고, 이 주소를 타겟 프로세스에서도 그대로 사용할 수 있다.
5. 원격 스레드 실행 - CreateRemoteThread
- 타겟 프로세스(hProcess) 내부에 새로운 스레드를 생성하여 실행시킨다.
- lpStartAddress(실행할 함수): 4에서 구한 LoadLibraryW의 주소(pThread)
- lpParameter(함수의 인자): 3에서 경로를 써둔 메모리 공간의 주소(pRemoteBuf)
- 결과: 타겟 프로세스가 스스로 LoadLibrary("악성DLL")를 호출하게 되며, 악성 DLL이 메모리에 로드된다.

API 후킹
DLL을 인젝션하는 것만으로는 아직 "조용히 들어와 앉아있는" 상태일 뿐이다. 본격적인 감시/조작을 하려면 API 후킹이 필요하다.
후킹의 전제 조건: 다른 프로세스의 API 호출을 가로채려면(Hooking), 내 코드가 그 프로세스 안에 있어야 한다. 따라서 코드 인젝션(DLL 인젝션)은 API 후킹을 수행하기 위한 사전 단계 역할을 한다. DLL을 주입한 후 SetWindowsHookEx 등의 함수를 실행하여 본격적인 후킹을 건다.
후킹의 정상적 활용
- 기능 개선 및 패치: 소스 코드가 없거나 재컴파일이 불가능한 오래된 프로그램에 코드 인젝션으로 직접 오류를 수정(Hot Patching)하거나 새 기능을 덧붙인다.
- 시스템 관리 및 감시: 기업이나 PC방 등에서 사용자를 관리하거나 특정 프로그램의 오작동을 모니터링하는 감시 코드를 추가한다.
후킹의 악의적 활용 - 키보드/마우스 후킹 (키로깅)
가장 대표적인 예가 키보드/마우스 입력을 가로채는 키로거다.
DLL 인젝션과 코드 인젝션의 관계
코드 인젝션(Code Injection): 실행 가능한 기계어 코드(Opcode)나 함수를 현재 실행 중인 다른 프로세스의 메모리 영역에 강제로 삽입하여 실행시키는 더 넓은 의미의 기법이다.
포함 관계: 코드 인젝션은 넓은 의미의 기술 용어이고, DLL 인젝션은 코드 인젝션을 구현하는 가장 대표적이고 일반적인 방법 중 하나다.
| 구분 | DLL 인젝션 | 쓰레드(직접 코드) 인젝션 |
| 실행할 코드의 형태 | 완성된 .dll 파일 (디스크에 존재) | 어셈블리어 코드 조각(Shellcode), 파일로 존재하지 않음 |
| 구현 난이도 | 비교적 쉬움 | 높음 |
| 탐지 가능성 | 백신이 디스크의 악성 DLL 파일을 스캔하여 쉽게 잡아낼 수 있음 | 디스크에 흔적을 남기지 않아 탐지가 훨씬 어려움 (Fileless) |
| 보안 위협 관점 | 전통적인 파일 기반 진단으로 탐지 가능 | EDR 등 메모리 행위 기반(Memory Forensics) 탐지가 필요 |
프로세스 인젝션
프로세스 할로잉을 이해하기 전에, 그 상위 개념인 프로세스 인젝션을 먼저 짚어야 한다.
정의: 대상 프로세스에 외부의 코드 자체를 삽입하고, 해당 코드를 강제로 실행시키는 기법이다.
동작 방식: 단순히 DLL을 로드하거나 스레드를 생성하는 형태(5-1장의 DLL 인젝션)가 아니다. 메인 프로세스 영역에 코드를 직접 추가하거나 기존 코드를 변조하여 실행 흐름을 바꾼다.
실행 조건: 프로세스의 구조를 변경해야 하므로, 해당 프로세스가 중지(Suspended) 상태에서만 작업이 가능하다.
프로세스 인젝션의 주요 기법 두 가지
- 프로세스 할로잉 (Process Hollowing): 정상 프로세스를 중지 상태로 생성한 뒤, 메모리의 정상 코드를 비워내고(Hollow) 그 자리에 악성 코드를 채워 넣는 기법
- 프로세스 도플갱잉 (Process Doppelgänging): NTFS 트랜잭션 기능을 악용하여 악성 코드를 정상 파일처럼 보이게 한 뒤 로드하는 기법
프로세스 할로잉
정상 프로세스를 실행시킨 후, 그 내부의 원래 코드와 데이터를 파내어(Hollow) 없애고 그 자리에 악성 코드를 채워 넣는 기법이다.
위장 및 은닉: 정상 프로그램을 실행할 때 원본 코드와 데이터를 악성 코드로 바꿔치기하는 방식으로 주로 이용된다.
탐지 회피: 실행 중인 상황에서는 작업 관리자나 보안 도구에 정상 프로그램(예: 윈도우 시스템 프로세스인 svchost.exe)으로 보이기 때문에, 보안 탐지를 우회하기 위해 악성코드가 매우 빈번하게 사용한다.
상세 공격 과정

- CreateProcess() API로 타겟이 되는 정상 프로그램을 일시 중지 상태로 프로세스를 생성한다.
- GetThreadContext() API로 생성된 프로세스 메모리의 시작 위치를 파악하고 ReadProcessMemory() API로 Image Base 정보를 읽어온다.
- NtUnmapViewOfSection() API로 이미지 베이스 영역에 존재하는 원래의 정상 코드와 데이터를 메모리에서 해제한다.
- VirtualAllocEx() API로 메모리 영역에 새로운 메모리 공간을 다시 할당한다.
- WriteProcessMemory() API로 공격자가 준비한 악성 코드를 기록한다.
- SetThreadContext() API로 EIP의 값을 삽입된 악성 코드의 시작 지점으로 변경한다. 그 후 ResumeThread() API로 Suspend 상태를 풀고 프로세스를 다시 재실행한다.
프로세스 도플갱잉

- 정상 파일을 대상으로 트랜잭션을 생성해 핸들을 얻는다.
- 트랜잭션 내부에서 해당 파일의 내용을 악성 코드로 덮어쓴다.
- 트랜잭션 파일 핸들을 이용하여 메모리에 섹션 객체를 생성한다.
- 섹션 생성이 끝나면 즉시 트랜잭션을 롤백한다.
- 섹션 객체를 이용하여 새로운 프로세스를 생성한다.
- 프로세스의 매개변수와 PEB를 설정한다.
- 메인스레드를 생성하고 실행을 시작한다.
'Malware Analysis' 카테고리의 다른 글
| [실습] crackme2_find_number (0) | 2026.07.09 |
|---|---|
| [악성코드 분석] Procmon 동적분석 (0) | 2026.07.08 |
| [악성코드 분석] 메모리 공격 기법 (0) | 2026.06.24 |
| [악성코드 분석] 악성코드의 방어 기법 (0) | 2026.06.24 |
| [악성코드 분석] PE 파일 구조 (0) | 2026.06.24 |