📦 무결성 검사 없는 코드 다운로드 KISA A-2 · 무결성 검사 없는 코드 다운로드
자동 업데이터가 HTTP로 다음 버전을 받아 도착한 바이트를 그대로 실행합니다 — 서명도 해시도 없습니다. 중간자가 페이로드를 바꾸면 클라이언트는 악성코드를 실행합니다. 서명/SHA-256 검증(그리고 웹 스크립트엔 HTTPS/SRI)이 이를 막습니다.
0 · 업데이트 채널
벤더가 업데이트 v2.0을 배포합니다. MITM을 켜면 경로상의 공격자가 다운로드를 바꿉니다. 공격자가 주입할 내용을 고르세요.
① 취약한 업데이터: 다운로드 후 즉시 실행 VULNERABLE
이 클라이언트는 HTTP로 update.bin을 받아 곧바로 실행합니다. 서명이나 해시를 전혀 확인하지 않으므로 정상 페이로드와 공격자 것을 구분할 수 없습니다.
🏢 벤더
v2.0
v2.0
──▶
🕵️ MITM
──▶
💻 클라이언트
② 안전한 업데이터: 서명 / SHA-256 검증 SECURE
벤더는 릴리스에 서명하고 기대 SHA-256을 신뢰 채널로 게시합니다. 클라이언트는 다운로드 후 해시를 재계산하고, 핀된 공개키로 서명을 검증한 뒤에만 실행합니다. 변조된 페이로드는 검사를 통과하지 못합니다.
③ 취약 vs 안전 코드
VULNERABLE
# Python — 받은 코드를 그대로 실행
import urllib.request, os
def update():
data = urllib.request.urlopen(
"http://updates.app/v2/update.bin").read()
open("update.bin","wb").write(data)
os.system("./update.bin") # 무결성 검사 0 → MITM이면 악성코드 실행
SECURE
# Python — 해시+서명 검증 후 실행
import hashlib, urllib.request
EXPECTED = "9f86d0818..." # 신뢰 채널로 받은 SHA-256
PUBKEY = load_vendor_pubkey() # 핀된 공개키
def update():
data = urllib.request.urlopen(
"https://updates.app/v2/update.bin").read() # HTTPS
if hashlib.sha256(data).hexdigest() != EXPECTED:
raise SystemExit("hash mismatch - aborting")
if not verify_sig(data, sig, PUBKEY):
raise SystemExit("bad signature - aborting")
run(data) # 검증된 코드만 실행
<!-- 웹 스크립트는 SRI 로 무결성 고정 -->
<script src="https://cdn/app.js"
integrity="sha384-oqVuAfXR..." crossorigin></script>
방어 핵심: 다운로드한 코드는 실행 전 항상 암호 서명 검증(또는 신뢰 채널로 핀된 SHA-256 확인) · HTTPS로 받기 · 벤더 공개키 핀닝 · 웹 자원은 crossorigin과 함께 SRI 사용 · 불일치 시 fail-closed, 미검증 바이트 자동 실행 금지.
⚠️ 교육용 시뮬레이션입니다. 다운로드·MITM·해시·서명 검증은 페이지 내부 mock이며 실제 네트워크·파일·코드 실행은 일어나지 않습니다.