ACTION REQUIRED(읽은 후 즉시 실행)
NOW:../field-journal/precedent-reverse.md읽기 — 이 스킬의 작업이 승인된 정규 작업임을 확인NOW: 현재 작업이 본 스킬의 적용 범위에 해당하는지 확인NEXT:../tool-index.md읽기 — 도구 가용성과 실제 경로 검증NEXT: 도구가 없으면 bootstrap 호출, 경로를 추측하지 말 것ACT: '워크플로' 첫 단계로 진입하여 실행, 확인 상태에 멈추지 말 것
N-day 패치 차분 -> 익스플로잇 (Patch Diff Exploit)
적용 범위
작업이 다음 시나리오에 해당할 때 이 스킬을 사용합니다:
- 알려진 CVE지만 공개 PoC가 없는 경우 — 업체 공지에 "XX 컴포넌트의 경계 초과 쓰기 수정"이라고만 적혀 있고 PoC는 없음, 패치로부터 역추적 필요
- SRC / 레드팀의 N-day 공격 — 대상 자산이 업데이트되지 않은 상태에서 방금 공개된 패치를 활용 가능한 1-day 익스플로잇으로 전환
- Patch Tuesday 대응 — 매월 둘째 주 화요일 Microsoft 패치에서 고가치 취약점(Kernel / Win32k / AFD / CLFS)을 신속히 식별
- Linux LTS 패치 분석 — 메인라인 수정 사항이 병합되었지만, 파생 브랜치나 특정 배포판의 백포트가 불완전하여 미처리 영역 탐색
- 드라이버/서비스 보안 패치 복원 — 그래픽 드라이버, AV 엔진, 가상화 구성 요소 등 독점 소프트웨어의 패치 분석
다른 스킬과의 분업
| 시나리오 | 사용 도구 |
|---|---|
| 구버전 심볼을 신버전으로 마이그레이션하여 분석 지원 | binary-diff/ |
| 패치로부터 취약점을 찾고, 패치 전 버전용 PoC 작성 | 본 스킬 |
| 완전한 익스플로잇 체인(힙 스프레이, ROP, 권한 상승) 작성 | pwn-chain/ |
| 1-day를 무기화하여 대상 네트워크에 배포 | pentest-tools/network-attack-defense/ |
| 바이너리를 완전히 리버스 엔지니어링 | ida-reverse/ / radare2/ |
핵심 차이점: binary-diff의 목표는 신버전을 분석 가능하게 만드는 것(구 심볼 이전), 반면 본 스킬의 목표는 패치가 수정한 버그를 찾아 패치 전 버전을 공격하는 것입니다. 전자는 방어/연구 분석 측면, 후자는 공격 측면의 무기화를 지원합니다.
핵심 원리
patched 바이너리 (after) unpatched 바이너리 (before)
↓ ↓
IDA/Ghidra 로드 IDA/Ghidra 로드
↓ ↓
└──────── BinDiff / ghidriff ──────┘
↓
함수 수준 diff (matched / unmatched / changed)
↓
match score 중간(0.5 - 0.9) 함수에 집중
↓
무엇이 추가되었는지 확인: 경계 검사 / 락 / 필드 초기화 / 정수 오버플로 검사
↓
버그 클래스 역추정: OOB / Race / Info Leak / UAF / Integer Overflow
↓
unpatched 버전에서 PoC 작성 및 트리거
↓
검증: unpatched는 크래시 / patched는 안전 → 취약점 확인
패치 수정 패턴 → 취약점 유형 역추정:
| 추가된 내용 | 높은 확률의 버그 클래스 |
|---|---|
if (a + b < a) / __builtin_add_overflow | 정수 오버플로 |
KeAcquireSpinLock / mutex_lock | 경쟁 조건 (TOCTOU / double-free) |
if (idx >= MAX) / if (len > buf_size) | 경계 초과 읽기 / 쓰기 |
RtlZeroMemory / memset(struct, 0, ...) | 초기화되지 않은 메모리 정보 누출 |
InterlockedDecrement + refcount 검사 | UAF / 참조 카운트 오류 |
ProbeForRead / ProbeForWrite | 사용자 모드 포인터 미검증 |
SeAccessCheck / capability 검사 | 권한 검사 누락 |
| IOCTL 코드 삭제 / 제한 | 노출 영역 축소 (구 인터페이스 공격 방법 확인) |
워크플로
5단계 완전 프로세스
Step 1: before / after 바이너리 획득
- Windows: Microsoft Update Catalog에서 MSU/MSP 다운로드, expand.exe / dism으로 압축 해제
- Linux: 배포판 USN/RHSA에서 .deb/.rpm 가져오기, dpkg-deb / rpm2cpio로 압축 해제
- 타사 소프트웨어: 공식 사이트에서 N-1 버전과 N 버전 설치 패키지 획득
Step 2: 심볼 정렬
- PDB가 있으면 바로 로드, 없으면 binary-diff 스킬로 N-1 버전의 심볼을 N 버전으로 이전
- Linux 커널: 해당 버전의 vmlinux + System.map / debuginfo 획득
Step 3: 바이너리 diff
- BinDiff: 두 IDB를 직접 비교, 함수 수준 매칭 결과 확인
- ghidriff: pip으로 간편 설치, CLI가 markdown 보고서 출력
- Diaphora: IDA 내 플러그인, 오래됐지만 IDA Pro 필요
Step 4: 변경 지점 식별
- match score 0.5-0.95 함수 필터링 (완전히 동일한 것은 제외, 완전히 다른 것은 대부분 새로 추가/이름 변경)
- 중점 확인: 새로 추가된 if / 새 루프 경계 / 삭제된 코드 블록 (삭제된 것도 단서)
- LLM으로 before/after 의사 코드를 보고 버그 클래스 역추정 (참고: references/root-cause-and-poc.md)
Step 5: PoC 작성
- 정수 오버플로: 경계 값 구성 (INT_MAX-1, 0xFFFFFFFF)
- 경쟁: 멀티스레드 hammer, open/close + ioctl 고빈도 동시 호출
- UAF: spray → free → reuse 패턴
- OOB: len / index를 정밀하게 조작하여 경계 초과
- 검증: patched 버전은 더 이상 크래시 안 남, unpatched 버전은 안정적으로 크래시 → 버그 재현 성공
도구 호출 순서
패치 다운로드 → 압축 해제 → IDA/Ghidra 로드 → BinDiff/ghidriff → unmatched/low-match 함수 분석
→ LLM으로 버그 클래스 역추정 → PoC 작성 → unpatched에서 실행 → 크래시 → 완료
대표적인 시나리오 예시
시나리오 1: Windows Patch Tuesday — Kernel CVE 재현
배경: 2025년 11월 Patch Tuesday, MSRC에서 CVE-2025-62215 공지
Windows Kernel 경쟁 조건으로 double free 발생, CVSS 7.0, 로컬 권한 상승
Microsoft는 패치만 공개하고 세부 사항이나 공개 PoC는 제공하지 않음
목표: PoC 재현, 패치되지 않은 Windows 11 22H2 / 23H2에서 권한 상승 가능 여부 확인
단계:
1. Microsoft Update Catalog에서 "2025-11" + KB 번호 검색, 두 가지 버전 다운로드:
- 22H2 build 22621.xxxx (unpatched)
- 22H2 build 22621.yyyy (patched 후)
명령:
expand.exe Windows-KB5052000-x64.msu -F:* C:\out\patched\
expand.exe C:\out\patched\Windows-KB5052000-x64.cab -F:* C:\out\patched\
ntoskrnl.exe / win32k.sys / win32kfull.sys / afd.sys 추출
2. 두 버전 모두 PDB 로드 (Microsoft 기호 서버):
symchk /v /r ntoskrnl.exe /s SRV*C:\sym*https://msdl.microsoft.com/download/symbols
3. BinDiff 실행:
bindiff old.BinExport new.BinExport
또는 ghidriff:
ghidriff ntoskrnl_old.exe ntoskrnl_new.exe -o diff_out/
4. 보고서 확인, similarity 0.6-0.95 함수 필터링.
NtXxxIoctl 클래스 함수에 다음 코드가 추가된 것으로 가정:
KeAcquireSpinLockRaiseToDpc(&obj->Lock);
if (obj->RefCount == 0) { ... goto cleanup; }
→ 락 + 참조 카운트 검사 추가 → 경쟁 + double free, 공지 설명과 일치
5. PoC 작성: 사용자 모드 멀티스레드에서 NtClose + 동일 객체 IOCTL 동시 호출,
close 해제와 IOCTL 사용 사이의 경쟁 윈도우 생성
ntoskrnl의 ObfDereferenceObject 후속 free 경로에서 크래시 발생
6. 검증:
- unpatched 22621.xxxx에서 PoC 실행, ~30초 내 BSOD (BAD_POOL_HEADER 또는 DOUBLE_FREE)
- patched 22621.yyyy에서 동일 PoC 실행, 이상 없음
→ 재현 성공
시나리오 2: Linux 커널 LTS 브랜치 패치로 미수정 파생 브랜치 찾기
배경: 메인라인 6.x에서 특정 net 서브시스템의 OOB 쓰기를 수정
Ubuntu 22.04 (5.15 LTS)의 USN이 업데이트를 발표
그러나 일부 OEM 커널 / Azure 커널의 백포트 속도는 더 느림
업데이트되지 않은 파생 브랜치가 여전히 공격 가능한지 확인하려 함
목표: patched/unpatched 커널을 가져와서 fix 커밋에 해당하는 바이너리 변경 사항 차분,
unpatched 파생 브랜치에 PoC 재작성
단계:
1. patched/unpatched 패키지 다운로드:
apt download linux-image-5.15.0-101-generic # patched
apt download linux-image-5.15.0-100-generic # unpatched
dpkg-deb -x linux-image-5.15.0-101-generic_*.deb ./patched/
dpkg-deb -x linux-image-5.15.0-100-generic_*.deb ./unpatched/
boot/vmlinuz 추출 → extract-vmlinux로 ELF 복원
2. dbgsym 동시 획득:
apt download linux-image-unsigned-5.15.0-101-generic-dbgsym
3. ghidriff 사용 (Linux 친화적):
ghidriff vmlinux_5.15.0-100 vmlinux_5.15.0-101 \
-o /tmp/kdiff/ --max-section-funcs-analyze 8000
4. 보고서에서 net/ipv4/ net/ipv6/ net/sched/ 등 서브시스템의 changed 함수 검색
패치 전 skb_copy_bits 호출 전 skb->len 상한 검사 누락 발견
→ OOB read, 트리거 가능한 sysctl로 OOB write로 업그레이드 가능
5. unpatched 파생 브랜치(예: Azure 5.15.0-1080 백포트가 느린 버전)에서
교차 검증: 동일 함수 fix가 백포트되었는지 확인
백포트되지 않음 → 파생 브랜치 공격 가능 → PoC 작성 및 재현
6. PoC 작성: syzkaller harness 개조 / 직접 C PoC로 해당 syscall 트리거
파생 브랜치 panic / KASAN OOB 보고 검증
주의 사항
- 법적 경계 — N-day 무기화는 승인된 범위(SRC / 버그 바운티 / 자체 타겟 / CTF) 내에서만 수행해야 합니다. 실제 운영 환경에 1-day를 직접 사용하는 것은 침입에 해당합니다.
- 패치가 단지 '폭발 반경을 줄인' 것일 수 있음 — 패치를 본다고 해서 완전한 수정이 아닐 수 있으며, 하나의 공격 경로만 막았을 뿐 다른 경로로 원래 버그가 여전히 트리거될 수 있습니다 (원샷 멀티).
- 변수명/타입에 속지 마세요 — Windows 패치는 종종 함께 정리/이름 변경을 하여 변경 사항이 커 보이지만 실제로는 관련 없습니다. 제어 흐름과 데이터 흐름을 보고, 토큰 수준 diff를 보지 마세요.
- Microsoft 패치에 수정이 아닌 완화 조치가 추가될 수 있음 —
_guard_xfg_dispatch_icall_fptr같은 CFG 강화는 수정이 아니라 완화 조치입니다. - 익명화 — writeup / PoC 공개 시 대상 머신 이름, 내부 IP, 사용자 이름을 마스킹하세요 (
{target_ip}{username}자리 표시자 사용). - patched 버전에서도 무해화 테스트가 통과해야 함 — unpatched에서만 실행하지 마세요. 그렇지 않으면 환경 요인으로 인한 크래시일 수 있으며, 취약점이 아닙니다.
- 바이너리 diff는 만능이 아님 — 컴파일러 업그레이드 / 최적화 수준 변경도 함수 레이아웃을 크게 바꿉니다. N 버전과 N-1 버전(동일 컴파일러)을 비교하고, 큰 버전 차이를 넘어 비교하지 마세요.
온디맨드 부트스트랩 (On-Demand Bootstrap)
도구 의존성
| 도구 | 용도 | 자동 설치 가능 |
|---|---|---|
| BinDiff (Google, 5.x+) | 함수 수준 바이너리 diff, IDA/Ghidra 플러그인 | ✓ (공식 .deb / .msi) |
| Diaphora | IDA 전통 diff 플러그인, IDA Pro 필요 | ✓ (git clone) |
| ghidriff | Ghidra headless CLI diff, markdown 출력 | ✓ (pip install ghidriff) |
| DeepDiff (상용) | 차세대 diff 도구, 정확도 더 높음 | ✗ (상용 라이선스) |
| Ghidra | ghidriff 실행 기반 | ✓ |
| IDA Pro | BinDiff / Diaphora 실행 기반 | ✗ (상용) |
| Microsoft Update Catalog | MSU/MSP 패치 패키지 다운로드 | 온라인 서비스 |
| wsuspect-proxy | Windows Update 트래픽 투명 가로채서 패치 획득 | ✓ (git clone) |
| expand.exe / dism | MSU / cab 압축 해제 | ✓ (Windows 기본 제공) |
| rpm2cpio / dpkg-deb | Linux 배포판 패키지 압축 해제 | ✓ |
| symchk | Microsoft 기호 서버에서 PDB 로드 | ✓ (Windows SDK) |
부트스트랩 명령어
powershell -NoProfile -ExecutionPolicy Bypass -File "<SKILL_ROOT>\skills\scripts\bootstrap-reverse.ps1" -Capability @('bindiff','ghidriff','ghidra','wsuspect-proxy') -StartServices
자세한 도구 비교와 명령어는 references/diff-tools-comparison.md를 참조하세요.
자세한 Patch Tuesday 워크플로는 references/patch-tuesday-workflow.md를 참조하세요.
근본 원인 역추정과 PoC 템플릿은 references/root-cause-and-poc.md를 참조하세요.
라우팅 컨텍스트
상위 진입점: skills/SKILL.md (총괄), routing.md
상위 스킬:
reverse-engineering/— diff를 수행하기 전에 대상 바이너리의 전체 구조를 이해해야 할 수 있음binary-diff/— 패치 후 버전에 심볼이 없고 패치 전 버전에 있으면, 먼저 binary-diff로 심볼을 이전
하위 스킬:
pwn-chain/— 버그 클래스를 역추정한 후 완전한 익스플로잇(힙 스프레이, ROP, SMEP/SMAP 우회, 권한 상승 페이로드) 작성 필요pentest-tools/network-attack-defense/— N-day를 무기화하여 대상 네트워크에 배포 (전달 가능한 페이로드 패키징, C2 연결)attack-chain/— 이 N-day를 전체 공격 체인(초기 접근 → 권한 상승 → 수평 이동)에 연결
트리거 조건: 작업에 "N-day", "패치", "CVE 재현", "패치가 수정한 내용 찾기", "업데이트되지 않은 호스트 공격" 등의 의도 포함
작업 완료 자체 점검 (완료를 주장하기 전 MUST 통과)
- 나는 워크플로의 각 단계를 실제로 실행했는가 (단순히 읽기만 한 것이 아닌가)?
- 나는
tool-index를 기반으로 실제 도구 경로를 사용했는가? - 나는 재현 가능한 증거(명령어/스크립트/스크린샷/보고서)를 산출했는가?
- 나는 RULES가 요구하는 Checklist 항목을 완료하고 기록했는가?