Step 238. ★ 중간 점검: 보통 난이도 Crypto 5문제 독립 해결 — Write-up 금지 구간

Step 238. ★ 중간 점검: 보통 난이도 Crypto 5문제 독립 해결 — Write-up 금지 구간

Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★★☆ | 예상 소요 시간 15시간 이상(며칠에 나눠 진행)

전제: Step 227~237의 Crypto 트랙 전체. 분류 루틴과 RSA 공격 체크리스트가 손에 익어 있다.

⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 오늘의 무대인 드림핵·picoCTF는 운영자가 공식 개방한 합법 학습 플랫폼입니다.

  • 준비물: 안 풀어 본 보통 난이도 Crypto 문제에 접근할 계정(드림핵 난이도 2~3 권장), 파이썬, 기록용 문서, 타이머.
  • 주의: 새로 배우는 기법이 없는 점검 챕터입니다. 서버 화면은 출력 예시로 표기합니다.

Crypto 트랙의 졸업 시험입니다. 규칙은 하나 — 보통 난이도 문제 5개를 풀이 없이 독립 해결하는 것. 수학을 "아는 것"과 "공격 코드로 쓰는 것"은 다릅니다. 지금까지 10개 챕터에서 배운 모든 무기를, 아무도 알려 주지 않는 문제 앞에서 스스로 꺼내는가 — 그것을 측정하는 자리입니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • 공정한 점검이 되도록 문제를 선정하는 기준(랜덤, 사전 노출 차단)을 적용한다
  • 문제당 3시간 상한과 분류 우선 루틴으로 독립 해결을 진행한다
  • 분류 단서, 시도한 공격, 실패 이유, 돌파 지점을 포함한 과정 기록을 남긴다
  • 구현 버그와 공격 실패를 구분하는 자기 검증법을 적용한다
  • 자주 쓴 공격 코드를 crypto 유틸 모듈로 정리한다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 파이썬 + 지금까지 만든 공격 코드 전부 (역원 계산기, XOR 도구, RSA 공격, 토이 해시, ECC 연산)
오늘의 절차 랜덤 선정 → 3시간 상한 → 분류 기록 → 5문제 판정 → 풀이 문서 + 유틸 모듈
필요한 개념 독립 해결의 정의, 구현 버그 vs 공격 실패, 자기 출제 검증법
오늘의 산출물 5문제 기록표 + 풀이 문서 5편 + crypto 유틸 모듈 v1

2-1. 왜 5문제인가 — 그리고 왜 "연속"이 아닌가

Step 202(웹 점검)와 다른 점이 하나 있습니다 — 이번에는 3연속이 아니라 5문제 완주입니다. Crypto는 문제 간 유형 편차가 커서, 운 좋게 아는 유형만 연속으로 뽑히는 사고를 방지하려면 표본을 늘리는 쪽이 낫습니다. 5문제를 다 풀되, 풀이를 본 문제는 무효로 하고 새 문제로 교체합니다. 카운터는 리셋이 아니라 교체입니다.

2-2. 공정한 선정

  1. 안 풀어 본 것: 풀이 기록이 없는 문제만 후보
  2. 난이도 범위: 드림핵 난이도 2~3(보통), picoCTF라면 중간 점수대
  3. 유형 사전 차단 금지: 후보 목록에서 난수로 뽑습니다. 제목과 유형 설명은 확인만 하고 상세 설명은 읽지 않습니다
[출력 예시 — 선정 기록]
후보: 드림핵 Crypto 미해결 난이도 2~3 문제 24개
난수: 4, 11, 19, 7, 22 → 문제 A~E 확정
규칙: 문제당 3시간, 풀이 검색 금지, 기법 문서만 허용

2-3. 진행 규칙 — 3시간과 분류 우선

웹 점검의 4시간보다 짧습니다 — Crypto는 분류가 맞으면 공격 코드가 빠르고, 분류가 틀리면 어차피 못 풉니다. 그래서 동선도 분류 중심입니다:

0:00~0:20  관찰 — 주어진 수치·파일 전부 나열, 자릿수와 형태 기록
0:20~0:40  분류 — 후보 2개 확정, 각각의 검증 실험 설계
0:40~2:30  공격 — 체크리스트 순서로 소거, 코드 작성
2:30~3:00  정리 — 풀었으면 재현 검증, 못 풀었으면 막힘 지점 기록

2-4. 구현 버그와 공격 실패의 구분 — 자기 출제 검증법

Crypto 독립 해결의 고유 난제입니다. 코드가 안 풀릴 때, 공격 이론이 틀렸는지 코드가 틀렸는지 모르면 진단이 불가능합니다. 해답은 자기 출제입니다:

1. 같은 유형의 작은 문제를 내가 만든다 (내가 답을 아는 문제)
2. 내 공격 코드를 그 문제에 돌린다
3. 풀리면 → 코드는 정상, 공격 이론(분류)이 틀렸다 → 분류로 회귀
   안 풀리면 → 코드 버그 → 작은 문제에서 디버깅

이 책 전체에서 이미 해 온 것입니다 — Step 234의 토이 해시, Step 237의 미니 문제가 전부 자기 출제였습니다. 점검에서는 그 습관이 막힘 진단기가 됩니다.

2-5. 유틸 모듈 — 두 번 치는 명령은 함수가 된다

5문제를 지나면 같은 코드를 반복해서 쓴 자신을 발견합니다 — 모듈러 역원, 바이트↔정수 변환, XOR 전수 시도, factordb 결과로부터의 d 복구. 점검의 마지막 산출물은 이 반복들을 모은 crypto_util.py입니다. 이 모듈이 다음 트랙(Forensics) 이후에도 계속 자라납니다.


3. 따라 하기

3-1. 점검 선언

시작 전에 규칙을 문서 첫머리에 고정합니다.

[출력 예시 — 점검 선언문]
- 문제: 드림핵 Crypto 난이도 2~3, 미해결 중 난수 5개
- 규칙: 문제당 3시간, 풀이 검색 금지, 기법 문서와 factordb는 허용
- 판정: 5문제 완주(재현 검증 포함), 풀이 열람 시 교체
- 산출물: 기록표 + 풀이 문서 5편 + crypto_util.py v1

3-2. 문제 진행 — 분류부터 (출력 예시)

[출력 예시 — 문제 B, 첫 40분]
- 주어진 것: output.txt — n(1024비트), e=65537, c, 그리고 "힌트: p와 q는 친구"
- 자릿수 관찰: n은 정상 크기, e도 정상 → factordb? 없음
- 후보 2개: ① 페륾마 인수분해 (힌트의 "친구" = p≈q) ② Wiener (e는 정상이라 낮음)
- 검증 실험: isqrt(n) 근처에서 a²-n이 제곱수인지 → 47회 만에 히트

읽는 법: 힌트 문구("친구")를 수학 조건(p ≈ q)으로 번역한 것이 분류의 전부입니다. 번역이 맞으면 공격 코드는 Step 230에서 이미 쓴 것입니다.

3-3. 막혔을 때 — 자기 출제로 진단 (출력 예시)

[출력 예시 — 문제 D, 1:50 시점]
- 유형 추정: 공통 모듈러스 (같은 n, e1=7, e2=11, c1, c2)
- egcd(7, 11) → 7·(-3) + 11·2 = 1 → m = c1^-3 · c2^2 mod n 계산
- 결과가 평문처럼 안 보임. 막힘.
- 자기 출제: 작은 소수로 같은 구조 생성 → 내 코드 정상 작동 확인
- 결론: 코드 무결 → 분류 재검토 → n이 두 암호문에서 실은 달랐음(유사 값). 재분류.

읽는 법: "내 코드는 작은 문제에서 맞다"를 먼저 증명했기에, 실패의 원인을 코드 밖(관찰·분류)으로 돌릴 수 있었습니다. 이 한 번의 진단이 3시간을 살립니다.

3-4. 점검 중 환경 규칙

측정이 공정하려면 환경도 통일합니다.

  • 알림 차단: 메신저와 메일 알림을 끕니다. 3시간 블록은 끊기면 집중이 리셋됩니다
  • 기록 창 상시 열기: 코드를 치는 창 옆에 기록 문서를 항상 띄워 둡니다. 분류 후보는 공격 전에 적혀 있어야 합니다 — 사후에 적으면 측정이 오염됩니다
  • 도구 고정: 평소 쓰던 파이썬 환경과 편집기 그대로 갑니다. 점검 날에 새 라이브러리를 시험하지 않습니다 — 도구 변수가 섞이면 측정이 흐려집니다
  • 타이머는 물리적으로: 화면 구석이 아니라 눈에 보이는 별도 타이머를 켜 둡니다. 상한은 기억이 아니라 장치가 지키게 합니다

3-5. 성공의 판정 — 재현과 수식

Step 202와 같은 기준입니다:

  1. 처음부터 다시 — 공격 스크립트를 새 세션에서 혼자 재실행
  2. 경로의 각 단계를 "왜 이 공격인가" 한 줄씩으로 설명 — Crypto에서는 수식 포함이 필수입니다 (왜 세제곱근이 되는지, 왜 φ(n)이 나오는지)
  3. 설명이 막히면 그 문제는 아직 미완성 — 풀이 문서 작성 단계에서 보완합니다

3-6. 실패의 처리 — 교체와 재훈련 주소

3시간 초과 시의 절차입니다.

  1. 타이머를 끄고 손을 뗍니다
  2. 막힘의 소속을 자기 출제로 확정해 기록합니다 — 코드 버그였는지, 분류 오류였는지, 아예 모르는 유형이었는지
  3. 모르는 유형이었다면 그 기법의 챕터가 재훈련 주소입니다 — 분류표에 "미해결 — Step N 복습"으로 남깁니다
  4. 이 문제는 유효 기록에서 제외하고, 새 문제를 난수로 뽑아 5문제를 채웁니다

실패한 문제는 미래의 연습 문제가 됩니다. 한두 주 뒤 재도전하면 달라진 분류 눈을 확인할 수 있습니다.

3-7. 점검 후 — 풀이 문서 5편과 유틸 모듈

[출력 예시 — 풀이 문서 형식]
# 문제 OOO 풀이
- **주어진 것과 관찰**: (수치와 자릿수)
- **분류**: 후보 2개 → 확정 유형, 확정 근거
- **공격**: 사용 이론(수식) + 코드
- **검증**: 재현 결과, 자기 출제 여부
- **유틸 후보**: 이 문제에서 모듈로 뺄 함수

그리고 5편의 "유틸 후보"를 모아 crypto_util.py v1을 만듭니다. 최소 포함 목록: modinv, iroot(정수 n제곱근), xor_brute, int<->bytes 변환, rsa_from_pq(p, q → d, 복호).


4. 미션과 연습문제

미션 — Crypto 5문제 독립 해결

  1. 2-2의 기준으로 보통 난이도 Crypto 5문제를 랜덤 선정하고 선정 기록을 남깁니다
  2. 각 문제에 3시간 상한과 2-3의 루틴(관찰→분류→공격→정리)을 적용합니다
  3. 막힌 문제는 3-3의 자기 출제 검증으로 원인을 코드/분류로 구분합니다
  4. 5문제 완주 후 각각의 풀이 문서를 3-7 형식으로 작성합니다
  5. 자주 쓴 코드를 crypto_util.py v1으로 정리합니다

연습문제

문제 1. 이번 점검이 웹 점검(3연속)과 달리 5문제 완주 방식인 이유를 설명해 보세요.

문제 2. "자기 출제 검증법"의 절차 세 단계를 순서대로 적고, 각 단계의 판정 결과가 가리키는 원인을 연결해 보세요.

문제 3. Crypto 문제에서 리서치가 허용되는 것과 금지되는 것의 경계를, factordb 사용을 예로 들어 설명해 보세요.

문제 4. 유틸 모듈을 점검 "도중"이 아니라 "후"에 정리하는 이유를 생각해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

완성된 점검 기록의 골격입니다:

[출력 예시 — 5문제 기록표]
문제 | 소요      | 분류(사후 확인)      | 돌파 지점              | 판정
A    | 1:10      | 작은 e (e=3)        | c+k·n 세제곱근, k=41   | 성공(재현 완료)
B    | 0:55      | 페륾마              | a²-n 제곱수 47회 히트  | 성공(재현 완료)
C    | 3:00 초과 | (미확정)            | 분류 2개 모두 소거됨   | 실패 → 교체
D    | 2:35      | 공통 모듈러스       | 자기 출제 후 재분류    | 성공(재현 완료)
E    | 1:20      | 단일 바이트 XOR     | 256 전수 + 판별자      | 성공(재현 완료)
F(교체)| 1:45    | factordb 히트       | p,q 조회 → d 복구      | 성공(재현 완료)
→ C 교체 포함 5문제 완주

검증하는 법: ① 선정이 랜덤이었는가. ② 각 성공에 재현 절차가 붙었는가. ③ 풀이 문서에 수식 기반의 "왜"가 있는가. ④ 막힌 문제에서 자기 출제 진단 흔적이 있는가. ⑤ crypto_util.py가 실제로 임포트되어 작동하는가.

연습문제 해답

문제 1 해답. Crypto는 유형 간 편차가 커서, 3연속은 "아는 유형이 우연히 연속"일 가능성을 배제하기 어렵기 때문입니다. 표본을 5개로 늘리면 유형 다양성이 강제되어 분류 능력 전반이 측정됩니다. 대신 연속 조건은 완화하고, 풀이 열람 시 해당 문제만 교체합니다.

문제 2 해답. ① 같은 유형의 작은 문제를 직접 만든다(답을 아는 문제). ② 내 공격 코드를 그 문제에 돌린다. ③ 풀리면 코드는 무결하므로 원인은 분류·이론 → 관찰 단계로 회귀. 안 풀리면 코드 버그 → 작은 문제에서 디버깅. 핵심은 실패의 소속을 먼저 확정하는 것입니다.

문제 3 해답. factordb는 "n의 인수분해 공개 DB"라는 도구입니다 — 사용이 허용되는 것은 일반 도구의 조회이고, 금지되는 것은 그 문제의 풀이 문서 열람입니다. 다만 문제 제목으로 검색해 인수분해 결과가 사실상 답인 경우도 있으니, 점검 규정은 시작 전 선언문에 "factordb 허용 여부"를 명시해 두는 것이 정직한 측정입니다 (권장: 허용 — 실전에서도 쓰는 도구이므로).

문제 4 해답. 도중에 정리하면 "이번 문제용 코드"와 "재사용 함수"의 경계가 흐려져, 한 번 쓴 코드까지 모듈에 넣게 되기 때문입니다. 5문제가 끝나야 "무엇이 반복됐는가"가 데이터로 보이고, 반복된 것만이 모듈의 자격을 얻습니다. 정리는 측정 후의 회고 작업입니다.

완료 기준 체크리스트

  • [ ] 랜덤 선정 기록(후보 범위와 난수 결과)을 남겼다
  • [ ] 각 문제에 3시간 상한과 관찰→분류→공격→정리 루틴을 지켰다
  • [ ] 과정 기록에 분류 단서·시도 공격·실패 이유·돌파 지점이 있다
  • [ ] 풀이를 보지 않았다 (기법 문서·factordb 등 허용 도구만 사용)
  • [ ] 막힌 문제에서 자기 출제로 코드/분류를 구분했다
  • [ ] 성공한 각 문제를 재현으로 검증하고 수식 포함 풀이 문서를 썼다
  • [ ] 미션: 5문제 완주 + 풀이 문서 5편 + crypto_util.py v1 완성

6. 흔한 실수와 해결

벽 1. 분류 없이 코딩부터 시작한다

증상: output.txt를 열자마자 에디터로 손이 갑니다.
원인: 웹 트랙의 "일단 페이로드" 습관. Crypto에서는 분류 없는 코드가 시간을 가장 많이 태웁니다.
해결: 첫 20분은 키보드 금지 — 수치를 종이에 옮기고 자릿수를 적는 시간으로 고정하세요. 2-3의 루틴에서 관찰 단계가 선언적 이유가 있습니다.

벽 2. 코드와 이론 중 뭐가 틀렸는지 몰라 무한 수정한다

증상: 같은 함수를 한 시간째 고치고 있습니다.
원인: 2-4의 구분 없이 코드만 의심하는 것.
해결: 즉시 자기 출제로 전환하세요 — 5분짜리 작은 문제가 진단을 끝냅니다. 수정은 진단 다음입니다.

벽 3. 3시간이 순삭된다

증상: 공격 하나를 붙잡고 상한을 넘깁니다.
원인: 소거 순서 없이 한 후보에 매몰.
해결: 후보마다 40분의 내부 상한을 두세요. 소거된 후보는 실패가 아니라 분류표의 데이터입니다. 2시간 반이 지나면 남은 시간은 기록 정리에 씁니다.

벽 4. 풀고 나서 설명이 안 된다

증상: 플래그는 나왔는데 풀이 문서의 "왜" 칸이 막힙니다.
원인: 코드가 먼저 풀리고 이해가 뒤따르지 못한 상태 — Crypto에서 흔하고, 위험합니다.
해결: 그 문제는 판정 보류입니다. 공격의 수식을 손으로 한 번 전개해 보세요 (작은 수로). 손 전개가 되면 문서가 써집니다.

벽 5. 유틸 모듈이 미괄식 정리가 된다

증상: 반복되지 않은 함수까지 모듈에 들어갑니다.
원인: "나중에 쓸 것 같아서"라는 추측.
해결: 기준은 하나 — 5문제 중 2번 이상 쓰인 코드만 모듈행입니다. 나머지는 풀이 문서 안에 둡니다. 모듈은 재고가 아니라 반복의 기록입니다.

벽 6. 자기 출제 문제를 너무 크게 만든다

증상: 진단하러 만든 테스트 문제 자체가 안 풀려 이중으로 막힙니다.
원인: 자기 출제의 목적은 "내 코드의 무결 확인"이지 난이도가 아닌데, 원 문제에 가까운 크기로 만들어 버린 경우입니다.
해결: 자기 출제는 구조만 같고 크기는 최소로 — 소수 3~4자리, 메시지 한 글자 수준이면 충분합니다. 5분 안에 답을 알고 시작할 수 있는 크기가 기준입니다.


7. 정리

오늘의 개념

개념 한 줄 설명
독립 해결 풀이 없이, 기법 문서와 도구만으로 문제를 뚫는 것
5문제 완주 유형 편차를 감안한 표본 크기 — 열람 문제는 교체
관찰→분류→공격 Crypto 점검의 표준 동선 — 첫 20분은 손과 종이
자기 출제 검증 내가 답을 아는 문제로 코드 무결을 먼저 증명하는 진단법
재현 + 수식 Crypto 성공의 판정 — 결과와 이유(수식)의 이중 검증
crypto 유틸 모듈 2회 이상 반복된 코드만 모은 개인 무기고

오늘의 절차

단계 하는 일
선정 미해결 보통 난이도에서 난수 5개, 선언문 고정
진행 문제당 3시간, 관찰→분류→공격→정리
진단 막히면 자기 출제로 코드/분류 구분
판정 재현 성공 + 수식 설명으로 인정, 열람 시 교체
회고 풀이 문서 5편 + crypto_util.py v1

명령어보다 중요한 감각

이 점검이 묻는 것은 하나입니다 — 수치 나열 앞에서 여러분의 분류 루틴이 스스로 서는가. 정답은 5문제 완주가 아니라, 완주에 이르는 동안 기록된 관찰과 소거의 밀도, 그리고 막힘 앞에서 자기 출제를 꺼내는 습관입니다. 이 구간을 통과했다면 여러분은 더 이상 "암호학을 배운 사람"이 아니라 "암호를 공격하는 사람"입니다. Crypto 트랙의 문을 나설 자격이 있습니다.


전부 체크되면 Step 238 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.