[Malware] 악성코드 기본 정적 분석: 해시, 문자열, PE 구조와 Imports
실행 파일을 실행하지 않고 해시, Reputation, 문자열, PE 구조와 Imports를 조사해 악성코드의 행위 가설을 세우는 기본 정적 분석 과정을 정리합니다.
출처를 모르는 실행 파일을 받았을 때는 파일을 실행하기 전에 식별 정보와 내부 구조부터 살펴봅니다. 해시로 기존 분석 기록을 찾고 문자열과 Windows API를 조사하면 어떤 기능이 들어 있을지 가설을 세울 수 있습니다. 이렇게 모은 정보는 악성코드의 특성을 정리하고 Threat Intelligence와 연결하는 출발점으로 활용합니다.
알 수 없는 파일에서 시작하기
PAYMENT FOR INV.exe라는 의심스러운 Windows 실행 파일을 예로 살펴봅니다.
처음에는 악성코드 유형과 행위, 위험 수준을 모두 알 수 없는 상태입니다.
- 먼저 파일의 해시를 계산하고 기존 Reputation 정보를 검색
- 파일 자체를 외부 서비스에 올리기 전에 내부 자료나 민감정보가 포함됐는지 확인
- 정적 분석으로 얻은 단서와 아직 검증하지 못한 가설을 구분
악성코드 의심 파일을 받았다고 해서 바로 VirusTotal 등으로 업로드하지 않는 것이 좋습니다. 파일을 업로드하면 내부 자료가 외부에 공유되거나 재사용될 수 있으며 악성코드가 아닌 경우 문제가 발생할 수 있습니다.
따라서 파일 전체를 보내기 전에 해시로 등록된 분석 결과가 있는지 찾는 것이 좋습니다.
기본 정적 분석은 다음 순서로 진행합니다.
- 악성코드 샘플 확보 및 식별
- 해시 계산
- Reputation 확인
- 문자열 분석
- PE 구조 및 섹션 확인
- DLL과 Imports 조사
- 패킹과 난독화 확인
- 악성코드 프로파일 정리
기본 정적 분석이란
정적 분석(Static Analysis)은 프로그램을 실행하지 않고 코드와 파일 구조를 살펴 기능과 특성을 파악하는 과정입니다.
기본 정적 분석에서는 다음 항목을 확인합니다.
- 파일 형식과 알려진 악성코드 여부
- 파일에 포함된 문자열과 Windows 기능
- 네트워크 통신 기능
- Persistence, 즉 실행 상태나 재실행을 유지하려는 기능
- 다른 프로세스를 실행하거나 조작하는 기능
- Packing 또는 Obfuscation 적용 가능성
정적 분석에서 기능의 단서를 발견했다고 해서 반드시 기능이 실행된다고 단정할 수는 없습니다. 실행 조건과 동작 여부는 추가 분석으로 확인해야 합니다.
- 이후 동적 분석을 통해 자세히 알아보겠습니다.
악성코드 샘플 수집
- MalwareBazaar
- 보안 연구자와 분석가를 위한 악성코드 샘플 공유 플랫폼
- Hash, Malware Family, Tag, File Type 등으로 샘플 검색
- SHA-256, Signature, Tags 등 샘플 식별·분류 정보 확인
- Malware-Traffic-Analysis.net
- 악성코드와 관련된 네트워크 트래픽 분석 자료 제공
- 패킷 파일과 관련 자료로 네트워크 행위를 분석할 때 활용
이메일의 실행 파일 첨부 제한 때문에 ZIP 같은 압축 파일로 전달되는 경우도 있습니다. 압축 파일이라는 이유로 안전하다고 판단해서는 안 됩니다.
악성코드 샘플을 다루는 규칙
- 샘플의 Hash와 사용한 알고리즘 기록
- 격리된 악성코드 분석용 VM 사용
- 분석 전 Snapshot 생성
- Shared Folder와 Clipboard Sharing 비활성화
- 출처를 모르는 샘플을 무작정 실행하지 않기
- 개인 PC나 업무용 PC에서 실행하지 않기
- 이메일이나 메신저에 샘플을 첨부하지 않기
분석 대상의 식별 정보
예시 파일의 기본 정보는 다음과 같습니다.
- 파일명:
PAYMENT FOR INV.exe - 파일 크기:
727,040 bytes - 파일 유형: Windows Executable
- 전달 경로: 이메일 첨부로 가정
- 분석 범위: 파일을 실행하지 않는 기본 정적 분석
파일명은 바뀔 수 있으므로 이름만으로 샘플을 구분하지 않습니다. 파일 크기와 유형을 기록하고 해시를 함께 남깁니다.
해시와 Reputation
해시는 파일의 내용을 입력으로 계산한 값으로, 악성코드 샘플을 식별할 때 널리 사용합니다. 암호화한 데이터를 복호화하는 방식과는 다르며 해시값에서 원래 파일을 되찾는 용도로 쓰지 않습니다.
- MD5, SHA-1, SHA-256 등의 알고리즘 사용
- MD5와 SHA-1은 충돌 문제가 있으므로 새 분석 기록에는 SHA-256 사용 권장(무결성 제외)
- 해시값과 알고리즘을 함께 기록
- 해시값만 보고 사용한 알고리즘을 확정하지 않기
PowerShell에서는 Get-FileHash로 파일의 해시를 계산할 수 있습니다.
파일명에 공백이 있으므로 경로를 따옴표로 감쌉니다.
Get-FileHash -LiteralPath '.\PAYMENT FOR INV.exe' -Algorithm SHA256
MD5 값이 필요한 기존 기록과 비교할 때는 알고리즘을 지정합니다.
Get-FileHash -LiteralPath '.\PAYMENT FOR INV.exe' -Algorithm MD5
Get-FileHash는 알고리즘을 생략하면 SHA-256을 사용합니다.
명령의 옵션과 동작은 Microsoft 공식 문서에서 확인할 수 있습니다.
예시 샘플의 SHA-256은 다음과 같습니다.
9f05a25d30b22c3d4a8da65f3ef034fc24ed35b97ed418f79d3af4def9f7ccdf
계산한 SHA-256을 VirusTotal 같은 Reputation Database에서 검색합니다. VirusTotal은 해시로 기존 파일 보고서를 검색할 수 있습니다.
- 여러 Vendor의 탐지 결과와 분류를 함께 확인
- 탐지명과 분류가 서로 다를 수 있다는 점 고려
- Reputation 결과를 파일 자체의 분석과 연결
VirusTotal의 결과는 판단에 참고할 정보입니다. 탐지 결과만으로 파일의 모든 기능과 행위를 확인했다고 볼 수는 없습니다.
Strings: 파일 안의 문자열
문자열 분석은 실행 파일 내부의 읽을 수 있는 문자들을 조사하는 작업입니다. Reputation 정보에 더해 파일 자체에서 단서를 찾습니다.
- 메시지와 에러 메시지
- URL, IP 주소, 도메인
- 파일 경로와 레지스트리 경로
- 명령어와 User-Agent
- 공격자가 남긴 문자열
패킹이나 난독화가 적용되면 문자열을 그대로 읽기 어려울 수 있습니다. 코드 보호를 위해 문자열을 암호화하는 경우도 있으니 패킹, 난독화 여부로 악성을 판단할 순 없습니다.
예시 샘플에 대한 YARA 결과에는 XorStringsNET 문자열 암호화를 탐지하는 규칙이 표시되어 있습니다.
규칙의 일치는 난독화 가능성을 조사할 단서로 사용하고 문자열이 어떻게 복원되는지는 별도로 확인해야 합니다.
PE 구조와 섹션
PE(Portable Executable)는 Windows의 EXE와 DLL 등에 쓰이는 실행 파일 형식입니다. Object 파일은 관련 형식인 COFF로 구분합니다. PE에는 Windows Loader가 파일을 메모리에 올리고 실행하는 데 필요한 정보가 담겨 있습니다.
PEView 같은 도구로 헤더와 섹션을 살펴볼 수 있습니다.
- DOS Header: PE 헤더의 위치 등 기본 정보
- PE Signature와 COFF File Header: 파일 형식, 대상 아키텍처, 섹션 수 등
- Optional Header: 진입점, 이미지 기준 주소, 메모리 배치 등 실행에 필요한 정보
- Section Table: 각 섹션의 위치, 크기, 속성
- Sections: 코드, 데이터, 리소스 등의 내용
| 섹션 | 일반적인 용도 |
|---|---|
.text / .code |
실행 코드 |
.data |
읽고 쓸 수 있는 초기화된 데이터 |
.rdata |
읽기 전용 데이터 |
.rsrc |
리소스 |
.reloc |
재배치 정보 |
문자열은 데이터 영역 등에서 발견할 수 있지만 섹션 이름만으로 내용이나 행위를 단정하지 않습니다. 헤더와 섹션의 상세 구조는 Microsoft PE Format 문서를 참고할 수 있습니다.
DLL과 Imports
Windows Loader는 Import Table을 보고 필요한 DLL을 로드하고 함수 주소를 연결합니다. 프로그램이 어떤 DLL과 함수를 사용하는지 조사하면 기능을 추정할 수 있습니다.
라이브러리 연결 방식
- Static Linking: 필요한 라이브러리 코드가 실행 파일에 포함
- Dynamic Linking: DLL의 함수를 연결해 사용
- Load-time Linking: 프로그램을 불러올 때 필요한 DLL과 함수를 연결
- Runtime Linking: 프로그램 실행 중 DLL을 불러오고 함수 주소를 구해 사용
Runtime Linking에서는 LoadLibrary, GetProcAddress 등을 사용합니다.
분석 중에는 LdrLoadDll 같은 Native API도 확인 대상이 됩니다.
Microsoft의 Runtime Linking 설명에서는 DLL을 로드한 뒤 함수 주소를 구해 호출하는 흐름을 볼 수 있습니다.
Imports에서 행위 가설 세우기
Dependency Walker 등으로 DLL과 Import Function을 조사합니다. 모르는 Windows API가 나오면 문서에서 기능을 먼저 확인합니다.
CreateProcessA: 다른 프로세스를 생성하는 기능의 단서URLDownloadToFile: URL에서 파일을 내려받는 기능의 단서- 두 기능이 함께 보이면 파일을 내려받아 실행할 가능성을 조사
API가 있다는 것만으로 다운로드와 실행이 이어진다고 단정할 수는 없습니다. 코드의 호출 관계를 살피고 동적 분석에서 파일 생성과 새 프로세스 실행 여부를 확인해야 합니다.
분석은 Static Evidence → Behavioral Hypothesis → Dynamic Verification으로 이어집니다.
- 정적 분석에서 발견한 증거로 행위 가설을 세우고 격리된 환경의 동적 분석으로 검증하는 흐름입니다.
주요 Windows DLL
| DLL | 주요 기능 |
|---|---|
Kernel32.dll |
프로세스, 메모리, 파일 등 기본 시스템 기능 |
Advapi32.dll |
레지스트리와 서비스 관리 |
User32.dll |
GUI와 사용자 인터페이스 |
Gdi32.dll |
그래픽 |
Ntdll.dll |
Windows Native API |
Ws2_32.dll |
네트워크 소켓 |
Wininet.dll |
HTTP·FTP 등 인터넷 기능 |
패킹과 난독화
패킹과 난독화는 코드나 문자열을 읽기 어렵게 만들 수 있습니다. 문자열이 잘 보이지 않거나 Imports만으로 기능을 설명하기 어렵다면 적용 여부를 살펴봅니다.
- 패킹: 실행 파일을 압축하거나 감싸 원래 코드가 바로 드러나지 않게 하는 방식
- 난독화: 코드나 문자열의 표현을 바꿔 분석하기 어렵게 하는 방식
- 분석 보고서에 Unpacked PE가 제공되면 원래 파일과 비교할 자료로 활용
패킹이나 난독화가 있다는 사실만으로 악성코드라고 결론 내리지는 않습니다. 확인한 식별 정보, Reputation, 문자열, PE 구조, Imports와 남은 의문을 모아 악성코드 프로파일을 정리합니다.