Prefetch 파일 분석을 통한 실행 이력 분석은(는) 무엇을 하나요?
사용 시점
- Windows 시스템에서 어떤 프로그램이 언제 실행되었는지 확인해야 할 때
- 맬웨어 조사 중 의심스러운 바이너리의 실행을 확인할 때
- 침해 사고 중 애플리케이션 사용 타임라인을 구축할 때
- 프로그램 실행을 다른 포렌식 아티팩트와 연관지을 때
- 실행된 안티-포렌식 도구 또는 허가되지 않은 소프트웨어를 식별할 때
사전 요구 사항
- 포렌식 이미지의 Windows Prefetch 디렉토리 접근 권한 (C:\Windows\Prefetch)
- PECmd (Eric Zimmerman), WinPrefetchView, 또는 python-prefetch 파서
- Prefetch 파일 형식 이해 (버전 17, 23, 26, 30)
- Prefetch가 활성화된 Windows 시스템 (클라이언트 OS에서는 기본값, 서버에서는 비활성화)
- Prefetch 파일명 명명 규칙 이해 (APPNAME-HASH.pf)
작업 흐름
1단계: 포렌식 이미지에서 Prefetch 파일 추출
# 포렌식 이미지 마운트
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/evidence.dd /mnt/evidence
# 모든 prefetch 파일 복사
mkdir -p /cases/case-2024-001/prefetch/
cp /mnt/evidence/Windows/Prefetch/*.pf /cases/case-2024-001/prefetch/
# prefetch 파일 개수 확인 및 목록 출력
ls -la /cases/case-2024-001/prefetch/ | wc -l
ls -la /cases/case-2024-001/prefetch/ | head -30
# 무결성 검증을 위한 해시 생성
sha256sum /cases/case-2024-001/prefetch/*.pf > /cases/case-2024-001/prefetch/pf_hashes.txt
# 참고: Prefetch 파일명 형식은 EXECUTABLE_NAME-XXXXXXXX.pf
# 해시(XXXXXXXX)는 실행 파일 경로를 기반으로 생성됨
# 동일한 실행 파일이라도 다른 경로에서 실행되면 다른 prefetch 파일이 생성됨
2단계: PECmd로 Prefetch 파일 파싱
# Eric Zimmerman의 PECmd 사용 (Windows 또는 Linux에서 Mono/Wine을 통해)
# 다운로드: https://ericzimmerman.github.io/
# 단일 prefetch 파일 파싱
PECmd.exe -f "C:\cases\prefetch\POWERSHELL.EXE-A]B2C3D4.pf"
# 모든 prefetch 파일을 파싱하고 CSV로 출력
PECmd.exe -d "C:\cases\prefetch\" --csv "C:\cases\analysis\" --csvf prefetch_results.csv
# JSON 출력으로 파싱
PECmd.exe -d "C:\cases\prefetch\" --json "C:\cases\analysis\" --jsonf prefetch_results.json
# 각 파일에 대해 다음 정보 출력:
# - 실행 파일 이름 및 경로
# - 실행 횟수
# - 마지막 실행 시간 (Windows 10에서는 최대 8개 타임스탬프)
# - 실행 중 참조된 파일 및 디렉토리
# - 볼륨 정보 (시리얼 번호, 생성 날짜)
# - Prefetch 파일 생성 시간
3단계: Linux 기반 분석을 위한 Python 파싱
pip install prefetch
python3 << 'PYEOF'
import os
import json
from datetime import datetime
# Python을 사용하여 prefetch 파일 파싱
import struct
def parse_prefetch(filepath):
"""Windows Prefetch 파일을 파싱합니다."""
with open(filepath, 'rb') as f:
data = f.read()
# MAM 압축 형식 확인 (Windows 10)
if data[:4] == b'MAM\x04':
import lznt1 # 또는 DecompressBuffer 사용
# Windows 10 prefetch 파일은 압축되어 있음
print(f" [압축된 Win10 형식 - 전체 파싱을 위해 PECmd 사용]")
return None
# 버전 17 (XP), 23 (Vista/7), 26 (8.1), 30 (10)
version = struct.unpack('<I', data[0:4])[0]
signature = data[4:8]
if signature != b'SCCA':
print(f" 잘못된 Prefetch 시그니처")
return None
file_size = struct.unpack('<I', data[8:12])[0]
exec_name = data[16:76].decode('utf-16-le').strip('\x00')
run_count = struct.unpack('<I', data[208:212])[0] if version >= 23 else struct.unpack('<I', data[144:148])[0]
result = {
'version': version,
'executable': exec_name,
'file_size': file_size,
'run_count': run_count,
}
# 마지막 실행 타임스탬프 추출
if version == 23: # Vista/7 - 1개 타임스탬프
ts = struct.unpack('<Q', data[128:136])[0]
result['last_run'] = filetime_to_datetime(ts)
elif version >= 26: # Win8+ - 최대 8개 타임스탬프
timestamps = []
for i in range(8):
ts = struct.unpack('<Q', data[128+i*8:136+i*8])[0]
if ts > 0:
timestamps.append(filetime_to_datetime(ts))
result['last_run_times'] = timestamps
return result
def filetime_to_datetime(ft):
"""Windows FILETIME을 datetime 문자열로 변환합니다."""
if ft == 0:
return None
timestamp = (ft - 116444736000000000) / 10000000
try:
return datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S UTC')
except (OSError, ValueError):
return None
# 모든 prefetch 파일 처리
prefetch_dir = '/cases/case-2024-001/prefetch/'
results = []
for filename in sorted(os.listdir(prefetch_dir)):
if filename.lower().endswith('.pf'):
filepath = os.path.join(prefetch_dir, filename)
print(f"\n=== {filename} ===")
result = parse_prefetch(filepath)
if result:
print(f" 실행 파일: {result['executable']}")
print(f" 실행 횟수: {result['run_count']}")
if 'last_run' in result:
print(f" 마지막 실행: {result['last_run']}")
elif 'last_run_times' in result:
for i, ts in enumerate(result['last_run_times']):
print(f" 실행 시간 {i+1}: {ts}")
results.append(result)
# 결과 저장
with open('/cases/case-2024-001/analysis/prefetch_analysis.json', 'w') as f:
json.dump(results, f, indent=2)
PYEOF
4단계: 의심스러운 실행 증거 식별
# 알려진 악성 도구 이름 검색
ls /cases/case-2024-001/prefetch/ | grep -iE \
'(MIMIKATZ|PSEXEC|WMIC|COBALT|BEACON|PWDUMP|PROCDUMP|LAZAGNE|RUBEUS|BLOODHOUND|SHARPHOUND|CERTUTIL|BITSADMIN)'
# 스크립트 인터프리터 검색 (잠재적 악성 실행)
ls /cases/case-2024-001/prefetch/ | grep -iE \
'(POWERSHELL|CMD\.EXE|WSCRIPT|CSCRIPT|MSHTA|REGSVR32|RUNDLL32|MSIEXEC)'
# 원격 접속 도구 검색
ls /cases/case-2024-001/prefetch/ | grep -iE \
'(TEAMVIEWER|ANYDESK|LOGMEIN|VNC|SPLASHTOP|SCREENCONNECT|AMMYY)'
# 데이터 유출 도구 검색
ls /cases/case-2024-001/prefetch/ | grep -iE \
'(RAR|7Z|ZIP|RCLONE|MEGA|DROPBOX|ONEDRIVE|GDRIVE|FTP|CURL|WGET)'
# 최근에 생성된 prefetch 파일 찾기 (가장 최근에 실행된 실행 파일)
ls -lt /cases/case-2024-001/prefetch/ | head -20
# 확인을 위해 Shimcache 및 Amcache와 상호 참조
# Prefetch 존재 = 프로그램이 최소 한 번은 실행됨
5단계: 실행 타임라인 구축
# prefetch 데이터에서 타임라인 생성
python3 << 'PYEOF'
import json
import csv
with open('/cases/case-2024-001/analysis/prefetch_analysis.json') as f:
data = json.load(f)
timeline = []
for entry in data:
if 'last_run_times' in entry:
for ts in entry['last_run_times']:
if ts:
timeline.append({
'timestamp': ts,
'executable': entry['executable'],
'run_count': entry['run_count'],
'source': 'Prefetch'
})
elif 'last_run' in entry and entry['last_run']:
timeline.append({
'timestamp': entry['last_run'],
'executable': entry['executable'],
'run_count': entry['run_count'],
'source': 'Prefetch'
})
# 시간순 정렬
timeline.sort(key=lambda x: x['timestamp'])
# 타임라인 CSV 작성
with open('/cases/case-2024-001/analysis/execution_timeline.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['timestamp', 'executable', 'run_count', 'source'])
writer.writeheader()
writer.writerows(timeline)
# 의심스러운 시간대 출력
for entry in timeline:
if '2024-01-15' in entry['timestamp'] or '2024-01-16' in entry['timestamp']:
print(f" {entry['timestamp']} | {entry['executable']} (x{entry['run_count']})")
PYEOF
주요 개념
| 개념 | 설명 |
|---|---|
| Prefetch | Windows 성능 최적화 기능으로, 애플리케이션 데이터를 사전 로드하고 실행을 추적합니다. |
| SCCA 시그니처 | 유효한 Prefetch 파일을 식별하는 매직 바이트입니다. |
| 경로 해시 | 실행 파일 경로의 CRC 기반 해시로, .pf 파일명의 일부를 구성합니다. |
| 실행 횟수 | 실행 파일이 실행된 횟수입니다 (래핑될 수 있음). |
| 마지막 실행 타임스탬프 | Windows 8+에서는 최대 8개의 최근 실행 타임스탬프를 저장합니다. |
| 참조된 파일 | 실행 첫 10초 동안 접근된 파일 및 디렉토리 목록입니다. |
| 볼륨 정보 | 원본 볼륨을 식별하는 드라이브 시리얼 번호와 생성 날짜입니다. |
| MAM 압축 | Windows 10 Prefetch 파일은 MAM4 압축을 사용하며, 파싱 전에 압축 해제가 필요합니다. |
도구 및 시스템
| 도구 | 용도 |
|---|---|
| PECmd | Eric Zimmerman의 Prefetch 파서로, CSV/JSON 출력을 지원합니다. |
| WinPrefetchView | NirSoft의 GUI 도구로, Prefetch 파일을 볼 수 있습니다. |
| python-prefetch | Prefetch 파일 파싱을 위한 Python 라이브러리입니다. |
| Prefetch Hash Calculator | 실행 파일 경로에서 예상 해시를 계산하는 도구입니다. |
| KAPE | Prefetch를 포함한 자동화된 아티팩트 수집 도구입니다. |
| Autopsy | Prefetch 분석 모듈이 포함된 포렌식 플랫폼입니다. |
| Plaso/log2timeline | Prefetch 파서를 포함한 슈퍼 타임라인 도구입니다. |
| Velociraptor | Prefetch 수집 및 분석 아티팩트를 제공하는 엔드포인트 에이전트입니다. |
일반적인 시나리오
시나리오 1: 맬웨어 실행 확인 Prefetch 디렉토리에서 맬웨어 실행 파일 이름을 검색하고, Prefetch 존재를 통해 실행을 확인합니다. 실행 횟수와 마지막 실행 시간을 추출하고, 참조된 DLL을 식별하여 맬웨어 동작을 이해한 후, 레지스트리 자동 실행 항목과 상호 참조합니다.
시나리오 2: 공격자 도구 사용 타임라인 PsExec, Mimikatz, BloodHound 및 기타 공격자 도구의 Prefetch 파일을 식별하고, 도구 실행의 시간순 타임라인을 구축합니다. 공격 순서(정찰, 자격 증명 도난, 측면 이동)를 결정하고, 타임스탬프를 네트워크 연결 로그와 일치시킵니다.
시나리오 3: 데이터 스테이징 및 유출 압축 도구(7z, WinRAR, zip)의 Prefetch 항목을 찾고, 파일 전송 유틸리티(rclone, FTP 클라이언트)의 실행을 식별하며, 클라우드 스토리지 클라이언트 실행을 확인합니다. 데이터 스테이징 및 전송이 발생한 시점의 타임라인을 만듭니다.
시나리오 4: 안티-포렌식 탐지 알려진 안티-포렌식 도구(CCleaner, Eraser, SDelete)의 실행을 확인하고, Prefetch 디렉토리가 최근에 비워졌는지 확인합니다 (활성 시스템에서 예상보다 적은 파일 수). 다른 증거와 관련하여 안티-포렌식 도구 실행 타임스탬프를 기록합니다.
출력 형식
Prefetch 분석 요약:
시스템: Windows 10 Pro (Build 19041)
Prefetch 파일: 234
분석 기간: 사용 가능한 전체 실행 이력
실행 통계:
고유 실행 파일 총계: 234
최초 실행: 2023-06-15 (시스템 설치)
최신 실행: 2024-01-18 23:45 UTC
의심스러운 실행:
MIMIKATZ.EXE-5F2A3B1C.pf
실행 횟수: 3 | 마지막 실행: 2024-01-16 02:30:15 UTC
PSEXEC.EXE-AD70946C.pf
실행 횟수: 7 | 마지막 실행: 2024-01-16 02:45:30 UTC
RCLONE.EXE-1F3E5A2B.pf
실행 횟수: 2 | 마지막 실행: 2024-01-17 03:15:00 UTC
POWERSHELL.EXE-022A1004.pf
실행 횟수: 145 | 마지막 실행: 2024-01-18 14:00:00 UTC
공격 타임라인 (Prefetch 기준):
2024-01-15 14:32 - POWERSHELL.EXE (초기 접근)
2024-01-16 02:30 - MIMIKATZ.EXE (자격 증명 도난)
2024-01-16 02:45 - PSEXEC.EXE (측면 이동)
2024-01-17 03:15 - RCLONE.EXE (데이터 유출)
보고서: /cases/case-2024-001/analysis/execution_timeline.csv