Step 342. 새 분야 착수 — Level 0의 자세로, 검증된 방법론을 들고
Level 4 — 전문가 | 난이도 ★★★☆☆ | 예상 소요 시간 2일 (입문 경로 확정 + 환경 구축 + 기초 실습 1단위)
전제: Step 341에서 다음 도전 분야 1개를 선정하고 선정서를 작성했다. 이 챕터의 실습 예시는 IoT/임베디드(펌웨어 카빙) 축으로 진행합니다 — 다른 축을 골랐다면 같은 절차를 그 축의 맛보기에 적용하세요.
- 준비물: Step 341의 선정서, 리눅스 환경(WSL이면 충분), 파이썬 3, 학습 노트 저장소. 이 챕터의 펌웨어 생성·카빙 스크립트와 출력은 이 책의 랩(WSL, Ubuntu 24.04, 파이썬 3.12)에서 실측한 것입니다.
- 주의: 오늘의 실습은 표준 입문 경로의 "목차 신뢰"가 핵심입니다 — 아는 것과 새 것이 섞여 혼란이 와도 2주는 목차 순서대로 갑니다.
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 펌웨어·취약 앱·클라우드 랩 전부 공식 배포물과 내 계정에서만 다룹니다.
새 분야의 첫걸음은 항상 겸손해야 합니다. 이 커리큘럼을 완주한 지금도 새 분야에서는 초보입니다. 그런데 이번에는 다릅니다 — 여러분은 "초보에서 전문가까지 가는 법"을 몸으로 아는 사람이고, 처음 PowerShell을 열든 날의 자세에 검증된 학습 방법론(기초 → 실습 → 정리 → 공유)을 얹고 입문합니다.
오늘은 그 첫 실습일입니다. 선정한 영역의 입문 경로를 확정하고, 환경을 구축하고, 기초 실습 한 단위를 완료합니다. 예시로 다루는 IoT 펌웨어 카빙은 이 책의 파일 포맷 지식이 그대로 통하는 영역이라, 첫날부터 "연결 고리"를 손으로 확인할 수 있습니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- 선정 영역의 표준 입문 경로(공식 문서·입문 랩·커뮤니티 커리큘럼)를 찾아 목차를 확정한다
- 영역별 실습 환경을 "내 랩/연습용 자산" 원칙으로 구축한다
- 펌웨어 블롭에서 매직 바이트 스캔으로 내장 파일을 카빙(carving)한다
- 카빙 도구의 오탐(가짜 시그니처)을 판별한다
- Level 0~2의 기록 습관 그대로 새 분야의 학습 노트를 시작한다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | 파이썬 3(표준 라이브러리만: zlib, zipfile, io), 리눅스 셸(WSL) |
| 오늘의 명령 | python3 make_fw.py · python3 carve.py router_fw.bin · ls -la · cat carved_* |
| 필요한 개념 | 펌웨어 블롭, 매직 바이트(파일 시그니처), 카빙, 오탐(false positive) |
| 오늘의 산출물 | 입문 경로 목차 + 실습 환경 + 카빙 실습 기록 + 학습 노트 첫 문서 |
2-1. 새 분야의 입문 구조 — 목차를 신뢰하라
새 분야에서 첫 혼란은 "아는 것과 새 것이 섞이는" 지점에서 옵니다. 펌웨어 분석을 열었는데 절반은 아는 파일 포맷 이야기, 절반은 처음 보는 부트로더 이야기 — 어디까지 공부해야 하는지 감이 안 잡힙니다.
처방은 분명합니다 — 입문 경로의 목차를 신뢰하세요. 표준 입문 경로(THM/HTB 트랙, 공식 가이드, 커뮤니티 커리큘럼)의 목차는 수많은 입문자의 시행착오로 다듬어진 순서입니다. 순서대로 2주만 따라가면 분야의 지도가 머리에 생깁니다. 목차를 뛰어넘는 탐구는 지도가 생긴 뒤의 일입니다.
2-2. 환경 구축의 원칙 — 새 분야도 "내 랩/연습용 자산"에서만
영역별 환경 구축의 형태는 다르지만 원칙은 하나입니다 — 새 분야도 실습은 내 랩과 연습용 자산에서만 수행합니다.
| 영역 | 환경의 형태 | 주의 |
|---|---|---|
| 클라우드 | AWS Free Tier + 격리된 실습 계정 | 요금 경보 설정 필수, 루트 계정 잠금, 실습 전용 IAM 사용자 |
| 모바일 | 안드로이드 에뮬레이터 + 취약 연습 앱(DIVA 등) | 실기기 대신 에뮬레이터, 연습 앱 외 분석 금지 |
| IoT | 공개 펌웨어 이미지 + 분석 도구 | 제조사가 공식 배포하는 펌웨어만 |
| AI | 로컬 플레이그라운드 + OWASP 자료 | 외부 LLM 서비스에 공격성 프롬프트를 보내지 않는다 |
클라우드의 "요금 경보"는 보안이 아니라 지갑의 문제로 입문자가 가장 많이 당하는 함정입니다 — 계정을 만들자마자 결제 알림부터 켜세요.
2-3. 펌웨어와 카빙 — 오늘 실습의 개념
펌웨어(firmware) 는 장치에 박히는 소프트웨어 패키지입니다. 라우터의 펌웨어 하나를 풀면 부트로더, 커널, 루트 파일시스템이 나오고 — 그 안에서 설정 파일, 하드코딩된 자격증명, 개인 키가 발견되는 것이 IoT 보안의 고전입니다.
그런데 펌웨어는 흔히 여러 조각이 하나의 파일에 이어 붙은 블롭(blob) 입니다. 헤더 다음에 압축 커널, 그 다음에 파일시스템 이미지 — 경계 표시가 없는 경우가 많습니다. 이때 쓰는 기법이 카빙(carving) 입니다 — 각 파일 형식의 매직 바이트(시그니처)를 바이너리 전체에서 찾아, 그 지점부터 끄집어내는 것입니다.
| 형식 | 매직 바이트 | 단서 |
|---|---|---|
| gzip | 1f 8b 08 |
커널·설정 압축에 흔함 |
| zip | 50 4b 03 04 ("PK") |
APK·일부 업데이트 패키지 |
| ELF | 7f 45 4c 46 |
실행 파일 |
| SquashFS | 68 73 71 73 ("hsqs") |
라우터 루트 파일시스템의 대표 |
전문 도구로는 binwalk가 표준입니다. 다만 오늘은 도구 없이 파이썬 표준 라이브러리만으로 카빙을 직접 구현합니다 — 도구가 하는 일을 손으로 한 번 해 보는 것이 입문 첫날의 몫이고, 그래야 나중에 binwalk 출력을 읽을 수 있습니다.
2-4. 오탐 — 시그니처는 우연히도 나타난다
카빙의 첫 함정은 오탐(false positive) 입니다. 매직 바이트는 몇 바이트짜리 패턴일 뿐이라, 압축 데이터 안에 우연히 같은 바이트 열이 나타날 수 있습니다. zip의 PK가 압축물 내부에도 등장하는 것이 대표적입니다.
그래서 카빙 도구의 출력은 "발견"이 아니라 "후보"입니다 — 실제로 그 오프셋에서 파일이 열리는지(디컴프레스되는지)까지 확인해야 진짜입니다. 3-3의 실측에서 이 오탐이 실제로 발생하니, 출력을 주의 깊게 읽어 보세요.
3. 따라 하기
3-1. 입문 경로 확정 — 목차를 노트 첫 장에
선정 영역의 표준 입문 경로를 찾아 목차를 통째로 학습 노트에 옮깁니다. IoT 축의 예시입니다.
입문 경로 목차 (화면 예시 — IoT/펌웨어 축):
1. 펌웨어의 구조 — 부트로더, 커널, 루트 파일시스템
2. 펌웨어 획득과 추출 — 카빙, binwalk 계열 도구 <- 오늘 여기
3. 루트 파일시스템 분석 — 설정·자격증명·키 사냥
4. 정적 분석 — 추출한 바이너리의 리버싱 입문
5. 에뮬레이션과 동적 분석 — QEMU로 펌웨어 돌려 보기
6. (선택) 하드웨어 인터페이스 — UART/JTAG
목차를 옮길 때 각 항목에 "내 기존 지식과의 연결"을 한 줄씩 달아 두세요 — 4번은 이 책의 리버싱 챕터들과, 5번은 WSL 경험과 연결됩니다. 이 한 줄들이 2주 후의 이해도를 결정합니다.
3-2. 훈련용 펌웨어 만들기 — 실측
실제 라우터 펌웨어 대신, 구조가 같은 훈련용 블롭을 직접 만듭니다 — 헤더 + gzip 조각 + zip 조각 + 난수 꼬리. make_fw.py로 저장하세요.
# make_fw.py — 훈련용 가짜 펌웨어 블롭 생성
import gzip, zipfile, io, os, random
random.seed(42)
hdr = b"LABFW" + bytes(random.randrange(256) for _ in range(59)) # 64바이트 헤더
payload = gzip.compress(b"labhostnssh-rsa AAAA... lab-keyn")
zipbuf = io.BytesIO()
with zipfile.ZipFile(zipbuf, "w") as z:
z.writestr("init/start.sh", "#!/bin/shn# lab init scriptn")
z.writestr("etc/passwd", "root:x:0:0:root:/root:/bin/shn")
tail = bytes(random.randrange(256) for _ in range(128))
open("router_fw.bin","wb").write(hdr + payload + zipbuf.getvalue() + tail)
print("생성: router_fw.bin", os.path.getsize("router_fw.bin"), "bytes")
실행한 실측 출력입니다:
생성: router_fw.bin 520 bytes
520바이트짜리 블롭이 생겼습니다. 실제 펌웨어는 수 MB~수백 MB지만, 구조는 같습니다 — 경계 없이 이어 붙은 조각들. 직접 만들었기에 정답을 알고 있습니다: gzip 조각에 호스트명과 키 조각, zip 조각에 init/start.sh와 etc/passwd. 이제 정답을 모른 척하고 카빙으로 되찾아 봅시다.
3-3. 카빙 — 매직 바이트로 끄집어내기
카빙 도구를 직접 구현합니다. carve.py로 저장하세요.
# carve.py — 매직 바이트 스캔으로 펌웨어에서 파일 끄집어내기
import sys, zlib, zipfile, io
MAGICS = {
b"x1fx8bx08": "gzip",
b"PKx03x04": "zip",
b"x7fELF": "elf",
b"hsqs": "squashfs",
b"ustar": "tar(대략)",
}
data = open(sys.argv[1], "rb").read()
print(f"대상: {sys.argv[1]} ({len(data)} bytes)")
found = []
for magic, name in MAGICS.items():
off = 0
while True:
i = data.find(magic, off)
if i < 0:
break
found.append((i, name))
off = i + 1
for off, name in sorted(found):
print(f" 오프셋 {off:>6}: {name} 시그니처")
# 추출 시도 — 시그니처는 후보일 뿐, 열리는지 확인해야 진짜
for off, name in sorted(found):
if name == "gzip":
try:
d = zlib.decompressobj(16 + zlib.MAX_WBITS)
out = d.decompress(data[off:])
open(f"carved_{off}.bin", "wb").write(out)
print(f"[+] gzip @ {off} 추출 성공 -> carved_{off}.bin ({len(out)} bytes)")
except Exception as e:
print(f"[-] gzip @ {off} 실패: {e}")
if name == "zip":
try:
z = zipfile.ZipFile(io.BytesIO(data[off:]))
for n in z.namelist():
open("carved_" + n.replace("/", "_"), "wb").write(z.read(n))
print(f"[+] zip @ {off} 추출 성공 -> {z.namelist()}")
except Exception as e:
print(f"[-] zip @ {off} 실패: {e}")
실행한 실측 출력입니다:
대상: router_fw.bin (520 bytes)
오프셋 64: gzip 시그니처
오프셋 114: zip 시그니처
오프셋 185: zip 시그니처
[+] gzip @ 64 추출 성공 -> carved_64.bin (32 bytes)
[+] zip @ 114 추출 성공 -> ['init/start.sh', 'etc/passwd']
[-] zip @ 185 실패: negative seek value -71
읽는 법: 세 가지를 봅니다. ① 오프셋 64의 gzip — 헤더가 정확히 64바이트였으니 정답과 일치합니다. ② 오프셋 185의 두 번째 zip 시그니처와 실패 — 이것이 2-4의 오탐입니다. zip 파일 내부의 중앙 디렉터리에도 PK 패턴이 들어 있어서 스캐너가 "후보"로 잡았지만, 실제로 열어 보니 negative seek value -71이라는 에러로 실패합니다. 시그니처 스캔은 후보를 주고, 열어 보는 것이 확정입니다. ③ 추출 성공은 [+], 실패는 [-] — 도구 출력의 이 관례는 binwalk도 같습니다.
3-4. 추출물 확인 — 펌웨어 분석의 첫 수확
끄집어낸 파일들을 확인합니다.
ls -la
cat carved_64.bin
cat carved_etc_passwd
실측 출력입니다:
-rw-r--r-- 1 student student 1406 Sep 9 22:06 carve.py
-rw-r--r-- 1 student student 32 Sep 9 22:06 carved_64.bin
-rw-r--r-- 1 student student 30 Sep 9 22:06 carved_etc_passwd
-rw-r--r-- 1 student student 688 Sep 9 22:06 make_fw.py
-rw-r--r-- 1 student student 520 Sep 9 22:06 router_fw.bin
labhost
ssh-rsa AAAA... lab-key
root:x:0:0:root:/root:/bin/sh
(위 ls 출력은 실측 중 관련 행만 추린 것이고, 실제 랩에는 추출 과정의 산출물이 더 있을 수 있습니다.)
읽는 법: 지금 여러분은 "펌웨어 분석의 고전적 수확"을 방금 손에 넣었습니다. gzip 조각에서 호스트명과 SSH 키 조각이, zip 조각에서 passwd 파일이 나왔습니다. 실제 라우터 펌웨어 분석도 정확히 이 그림입니다 — 카빙으로 루트 파일시스템을 풀고, 그 안에서 자격증명·키·설정을 사냥합니다. 오늘의 520바이트가 수 MB짜리 실제 펌웨어로 바뀔 뿐, 절차는 동일합니다.
3-5. 학습 노트 시작 — Level 0의 습관 그대로
실습이 끝나면 바로 기록합니다. Level 0~2에서 하든 것과 같은 양식입니다.
학습 노트 첫 문서 (화면 예시 — IoT 축 Day 1):
- 배운 개념: 펌웨어 블롭, 매직 바이트, 카빙, 오탐
- 손으로 한 것: make_fw.py로 블롭 생성, carve.py로 3개 파일 추출
- 막힌 지점: 오프셋 185의 zip 오탐 — negative seek 에러의 정체를 처음엔 몰랐다
- 해결 과정: zip 내부 구조(중앙 디렉터리)를 다시 읽어 오탐의 원리를 확인
- 다음 할 일: 목차 3번 — 실제 공개 펌웨어 1개에 같은 절차 적용
마지막으로, 완료 기준을 스스로 정하세요 — 이 책 전체의 일관된 규칙입니다. 예: "목차 2번 항목을 실제 펌웨어로 재현하고, 노트에 3편 이상 기록한다". 새 분야에서도 완료 기준이 있는 학습만이 끝나는 학습입니다.
4. 미션과 연습문제
미션 — 선택 영역 기초 실습의 완료
- Step 341에서 선정한 영역의 표준 입문 경로를 찾아 목차를 학습 노트 첫 장에 옮기고, 각 항목에 "기존 지식과의 연결"을 한 줄씩 답니다.
- 2-2의 원칙표에 따라 실습 환경을 구축합니다 (클라우드면 격리 계정+요금 경보, 모바일이면 에뮬레이터+취약 연습 앱, IoT면 공개 펌웨어와 분석 디렉터리).
- 입문 실습 한 단위를 수행합니다 — IoT 축이라면 3-2~3-4의 카빙 실습을 재현하고, 이어서 실제 공개 펌웨어 1개에 같은 절차를 적용합니다. 다른 축이라면: 클라우드는 IAM 사용자·정책 실습 + CloudGoat 시나리오 1개, 모바일은 DIVA 취약점 3개 분석.
- 3-5 양식의 학습 노트를 시작하고, 막힌 지점과 해결 과정을 빠짐없이 기록합니다.
- 기초 실습의 완료 기준을 스스로 정해 문서화하고, 달성을 확인합니다.
연습문제
문제 1. 새 분야 입문에서 "목차를 신뢰하라"는 처방이 필요한 이유를, "아는 것과 새 것이 섞이는" 혼란의 구조로 설명해 보세요.
문제 2. 카빙에서 매직 바이트 스캔이 "발견"이 아니라 "후보"인 이유를, 3-3 실측의 오프셋 185 사례로 설명해 보세요.
문제 3. 클라우드 환경 구축에서 "요금 경보 설정"이 보안 수칙이 아니라 입문 수칙의 첫 항목인 이유를 설명해 보세요.
문제 4. 도구(binwalk)가 있는데도 첫 카빙을 파이썬으로 직접 구현해 보는 이유를, "도구 출력을 읽는 능력"의 관점에서 설명해 보세요.
5. 모범 답안과 완료 기준
미션 모범 답안
검증 기준으로 확인하세요.
- 목차의 충실성: 입문 경로 목차가 통째로 옮겨졌고, 각 항목에 기존 지식과의 연결이 구체적으로 달렸는가.
- 환경의 합법성: 실습 환경이 2-2 원칙표대로 내 랩/연습용 자산에 국한됐는가 — 클라우드라면 요금 경보의 설정 증거가 있는가.
- 실습의 재현성: 카빙 실습이라면 스크립트와 출력이 노트에 남아 타인(또는 미래의 나)이 재현 가능한가.
- 오탐의 이해: 실습 기록에 오탐 사례와 그 판별 과정이 서술됐는가.
- 완료 기준의 자기 정의: 완료 기준이 측정 가능한 문장으로 정해졌고 달성 여부가 체크됐는가.
연습문제 해답
문제 1 해답. 새 분야의 자료는 기존 지식과 새 개념이 섞여 있습니다 — 펌웨어 분석의 파일 포맷 부분은 이미 아는 내용이고, 부트로더 부분은 처음입니다. 이때 학습자는 두 극단으로 기웁니다 — 아는 부분에서 "이건 안다"며 건너뛰다가 새 부분에서 좌절하거나, 반대로 아는 부분까지 전부 다시 공부하며 진도가 멈추거나. 표준 입문 경로의 목차는 수많은 입문자의 시행착오로 다듬어진 순서라, 이 섞임을 전제로 설계돼 있습니다. 목차를 신뢰한다는 것은 순서의 판단을 전문가들의 축적에 위임한다는 뜻이고, 그 덕에 학습자는 "뭘 공부할까"의 판단 비용 없이 "지금 이 항목"에만 집중할 수 있습니다. 2주가 지나 분야의 지도가 머리에 생기면, 그때부터는 자기 판단으로 목차를 재편해도 됩니다 — 위임은 입문 구간의 전략이지 영구 규칙이 아닙니다.
문제 2 해답. 매직 바이트는 몇 바이트짜리 패턴일 뿐이라, 실제 파일의 시작이 아닌 곳에도 우연히 나타납니다. 실측에서 오프셋 185는 PK 시그니처가 잡혔지만 추출이 negative seek value -71로 실패했습니다 — zip 파일 내부의 중앙 디렉터리 영역에도 PK로 시작하는 레코드가 있어서 스캐너가 "후보"로 보고한 것입니다. 시그니처는 "여기에 무언가 있을지도 모른다"는 힌트이고, 그 오프셋에서 실제로 파일이 열리는지(디컴프레스·파싱이 성공하는지) 확인해야 "발견"이 됩니다. 전문 도구인 binwalk의 출력에도 엔트로피 그래프와 함께 후보 목록이 나오는 이유가 이것이고, 분석가의 일은 후보 중 진짜를 가려내는 것입니다.
문제 3 해답. 클라우드는 사용량이 곧 요금이라, 실습 환경의 방치가 곧바로 청구서로 옵니다. 입문자의 전형 사고는 이렇습니다 — 실습용 인스턴스나 스토리지를 만들고 지우는 것을 잊어, 몇 주 뒤 예상 밖의 요금을 맞는 것. 이 사고는 보안 사고보다 훨씬 흔하고, 입문 의욕을 꺾는 효과는 큽니다. 그래서 클라우드 입문의 첫 실습은 어떤 보안 기법보다 먼저 결제 알림·예산 경보의 설정입니다. 더불어 이 습관은 보안으로도 이어집니다 — 비용 이상 징후는 내가 모르는 자산의 동작(침해의 신호)을 잡는 가장 간단한 센서이기도 하니까요.
문제 4 해답. 도구를 바로 쓰면 출력을 "읽는 능력" 없이 "믿는 습관"이 생깁니다. binwalk의 출력은 후보 목록이고, 그중 진짜와 오탐을 가리는 일은 사용자의 몫입니다. 직접 구현해 보면 도구가 하는 일의 전부를 알게 됩니다 — 매직 바이트를 스캔하고, 각 오프셋에서 파싱을 시도하고, 성공과 실패를 표시한다는 것. 그래서 도구의 [+]/[-] 표시가 왜 있는지, 오탐 행이 왜 뜨는지, 도구가 조용히 놓친 것은 없는지를 판단할 수 있게 됩니다. "도구가 하는 일을 손으로 한 번 해 보는 것"은 이 책 전체의 반복 원리(패킷을 직접 만들어 보고, 익스플로잇을 직접 써 보는 것처럼)이고, 새 분야에서도 그 원리는 그대로입니다.
완료 기준 체크리스트
- [ ] 선정 영역의 표준 입문 경로 목차를 노트에 옮기고 연결 고리를 달았다
- [ ] 2-2 원칙표대로 실습 환경을 구축했다 (클라우드면 요금 경보 포함)
- [ ] 카빙 실습(또는 해당 축의 입문 실습)을 재현하고 출력을 노트에 남겼다
- [ ] 오탐 사례를 직접 만나고 판별 과정을 기록했다
- [ ] 막힌 지점과 해결 과정이 학습 노트에 있다
- [ ] 기초 실습의 완료 기준을 스스로 정하고 달성을 확인했다
6. 흔한 실수와 해결
벽 1. python3 carve.py 실행 시 파일을 못 찾아요
증상: 이런 에러가 뜹니다.
FileNotFoundError: [Errno 2] No such file or directory: 'router_fw.bin'
원인: carve.py를 실행한 디렉터리와 router_fw.bin을 만든 디렉터리가 다릅니다 — 스크립트는 인자로 받은 경로를 현재 디렉터리 기준으로 찾습니다.
해결: 두 파일을 같은 디렉터리에 두고 그 디렉터리에서 실행하세요 — cd ~/lab342 후 python3 make_fw.py && python3 carve.py router_fw.bin. 습관으로 만들어 두면 좋은 것 — 실습은 항상 전용 디렉터리에서. 산출물(carved_*)이 흩어지는 것도 막아 줍니다.
벽 2. 추출은 성공인데 내용이 깨져 보여요
증상: carved_64.bin을 에디터로 열었더니 앞부분이 이상한 문자입니다.
원인: 두 가지를 구분하세요. ① 진짜 깨짐 — 추출 시작점이 틀린 경우. ② 정상인데 바이너리인 경우 — 펌웨어에서 끄집어낸 것은 대부분 텍스트가 아니라 커널 이미지·파일시스템 같은 바이너리입니다.
해결: 먼저 file carved_64.bin으로 형식을 확인하고, xxd carved_64.bin | head로 헥스를 보세요. 텍스트가 기대되는 조각(설정 파일류)인데 깨졌다면 오프셋이 틀린 것이니 스캔 결과의 다른 후보를 시도합니다. 3-4의 실측처럼 cat에서 바로 읽히는 것은 텍스트 조각뿐입니다 — "안 읽히는 추출물"은 실패가 아니라 다음 분석 단계(file, strings, 리버싱)의 입력입니다.
벽 3. 입문 경로를 찾았는데 너무 오래된 자료예요
증상: 커뮤니티 추천 커리큘럼이 3년 전 자료고, 나오는 도구 버전이 지금과 다릅니다.
원인: 분야마다 자료의 수명이 다릅니다 — Step 341에서 AI 보안 자료의 수명이 짧다고 한 것과 같은 문제입니다.
해결: 세 겹으로 확인하세요. ① 개념의 유효성 — 카빙·매직 바이트 같은 개념은 십 년이 지나도 유효합니다. ② 도구의 현재성 — 도구 이름보다 "그 도구가 하는 일"을 따라가세요. ③ 공식 문서 우선 — 커뮤니티 자료는 지도로 쓰고, 명령·옵션은 반드시 공식 문서로 확인합니다. 오래된 자료가 위험한 것은 개념이 아니라 명령행입니다.
벽 4. 실제 펌웨어를 구했는데 암호화돼 있어요
증상: 제조사에서 받은 펌웨어를 카빙했더니 시그니처가 아무것도 안 잡힙니다.
원인: 최신 펌웨어는 암호화·난독화된 채 배포되는 경우가 늘고 있습니다 — 시그니처 스캔이 안 통하는 것이 정상입니다.
해결: 입문 단계에서는 우회가 목표가 아닙니다 — 카빙이 통하는 공개 펌웨어로 갈아타세요. 구형 라우터 펌웨어, 오픈소스 펌웨어(OpenWrt 류) 이미지가 좋은 연습 재료입니다. 암호화된 펌웨어의 대응(장치에서 덤프, 업데이트 과정 가로채기 등)은 목차의 뒷부분 주제입니다 — 목차를 신뢰하세요, 오늘의 항목이 아닙니다.
벽 5. "아는 것"이 나올 때마다 건너뛰고 싶어져요
증상: 입문 자료의 절반이 복습이라 뛰어넘다가, 어느 지점부터 갑자기 이해가 끊깁니다.
원인: 아는 내용 사이에 새 용어가 숨어 있습니다 — "파일시스템"은 아는데 그 분야의 호칭(루트fs, 스쿼시FS 이미지)은 새것인 식입니다.
해결: 건너뛰기의 규칙을 바꾸세요 — 절을 통째로 건너뛰지 말고, 속독하되 용어 표만 새로 만듭니다. 아는 내용을 읽는 시간은 낭비가 아니라 그 분야의 어휘를 내 지식에 매핑하는 시간입니다. 2-1의 지도가 생기는 과정이 정확히 이것입니다. 그리고 이 책에서 배운 기록 습관이 여기서도 답입니다 — 노트에 "복습 구간: O, 새 용어: 루트fs(=루트 파일시스템 이미지)" 식의 한 줄이면 충분합니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 목차 신뢰 | 입문 구간의 순서 판단은 표준 경로에 위임 — 지도가 생기면 재편 |
| 내 랩 원칙 | 새 분야도 실습은 내 랩·연습용 자산에서만 — 클라우드는 요금 경보부터 |
| 펌웨어 블롭 | 헤더+압축 조각+파일시스템이 경계 없이 이어 붙은 패키지 |
| 매직 바이트 | 형식을 알리는 시그니처 — gzip 1f 8b 08, zip PK, ELF, squashfs |
| 카빙 | 시그니처 오프셋부터 파일을 끄집어내는 기법 |
| 오탐 | 시그니처는 우연히도 나타난다 — 열어 봐야 확정 |
| 학습 노트 | Level 0의 습관 그대로 — 개념·막힘·해결·다음 할 일 |
오늘의 도구·명령어
| 도구·명령 | 하는 일 |
|---|---|
python3 make_fw.py |
훈련용 펌웨어 블롭 생성 (헤더+gzip+zip+꼬리) |
python3 carve.py <파일> |
매직 바이트 스캔 + 추출 시도 + 성공/실패 표시 |
ls -la / cat carved_* |
추출물 목록과 텍스트 조각 확인 |
file / xxd |
추출물의 형식 판별 (안 읽히는 것의 다음 단계) |
| 학습 노트 양식 | 개념·실습·막힘·해결·다음 할 일의 다섯 줄 |
명령어보다 중요한 감각
Step 1의 여러분은 PowerShell의 프롬프트 하나도 낯설어했고, 오늘의 여러분은 낯선 분야의 블롭에서 파일을 끄집어냅니다. 새 분야에서의 어색함은 같지만, 어색함을 다루는 절차는 이미 손에 있습니다 — 기초를 확인하고, 손으로 해보고, 막힘을 기록하고, 정리합니다.
카빙 한 번에 펌웨어 분석가가 되는 것은 아닙니다. 그러나 "520바이트의 블롭에서 키와 passwd를 끄집어낸 사람"과 "펌웨어 분석을 읽기만 한 사람"의 차이는, 이 책 전체가 반복해 온 그 차이입니다. 첫 단위를 손으로 완료한 오늘, 새 분야는 더 이상 낯선 땅이 아니라 진행 중인 지도입니다.
전부 체크되면 Step 342 완료입니다.