Step 279. ★ CTF 대회 #1: 주말 대회 풀 참가 — 첫 대회의 목표는 성적이 아니라 완주다

Step 279. ★ CTF 대회 #1: 주말 대회 풀 참가 — 첫 대회의 목표는 성적이 아니라 완주다

Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★☆☆ | 예상 소요 시간 1개 주말 (대회 24~48시간 + 준비·회고 반나절)

전제: Step 190의 CTFtime 일정표와 첫 대회 확정, Step 191~250의 주력 분야 트랙, Step 278의 실전 점검 완료.

  • 준비물: CTFtime에서 확정한 주말 대회 1개, Kali 리눅스(또는 여러분의 공격 환경), 침투 플레이북(Step 272), 타이머, 그리고 오늘 만들 대회 로그 스크립트.
  • ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. CTFtime에 등록된 CTF 대회는 주최 측이 참가하라고 연 합법 플랫폼입니다 — 대회가 제공하는 문제 서버 외에는 어떤 대상도 공격하지 않습니다.
  • 주의: 대회 플랫폼의 점수판·문제 목록 장면은 전부 화면 예시입니다. 대회마다 플랫폼(CTFd 등)과 규칙이 다르므로 실제 화면은 반드시 여러분이 직접 확인하세요. 이 챕터에서 실제로 실행해 검증한 것은 로컬 로그 스크립트뿐이며, 그 출력은 실측으로 표기합니다.

드디어 대회입니다. Step 176의 맛보기에서 시작해 5개 분야 트랙과 실전 머신 구간을 지나 여기까지 왔습니다. 첫 대회의 목표를 분명히 정하고 시작하겠습니다 — 완주와 데이터 수집입니다. 어느 분야에서 점수가 나오는지, 시간이 어디로 새는지, 멘탈이 언제 흔들리는지를 기록으로 남기는 것. 그 기록이 Step 280의 복기와 Step 283의 목표 설정의 원재료입니다.


1. 학습 목표

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

  • 첫 대회 전에 환경·도구·플레이북을 점검하는 체크리스트를 돌린다
  • 대회 시작 30분의 "전체 훑기"와 쉬운 문제 우선 전략을 실행한다
  • 문제별 착수·해결·막힘·포기를 시각과 함께 기록하는 대회 로그를 운용한다
  • "2시간 규칙"으로 막힌 문제를 손절하고 시간을 재배분한다
  • 대회 종료 직후 회고 메모를 작성해 다음 스텝의 복기 재료를 확보한다

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

오늘의 도구 한눈에 보기

구분 내용
언어·환경 대회 플랫폼(CTFd 등, 화면 예시), Kali 리눅스, 파이썬(로그 스크립트)
오늘의 화면·도구 CTFtime 대회 페이지, 대회 문제판, ctf_log.py(착수/해결/막힘/포기 기록)
필요한 개념 완주 목표, 전체 훑기 30분, 2시간 규칙, 다이내믹 스코어링, 회고 골든타임
오늘의 산출물 대회 로그 CSV + 종료 직후 회고 메모 1부

2-1. 첫 대회의 목표는 완주 — 성적은 두 번째 대회부터

입문자의 첫 대회에서 가장 흔한 실패는 "0점"이 아니라 중도 이탈입니다. 문제가 안 풀리는 좌절 속에서 "나는 아직 멀었다"는 결론을 내리고 창을 닫는 것. 그래서 첫 대회의 성공 조건을 미리 계약합니다: 끝까지 로그를 남기는 것.

성적이 목표가 아닌 이유는 하나 더 있습니다 — 첫 대회의 점수는 실력의 측정값이 아니라 노이즈입니다. 대회마다 난이도 편차가 크고, 운 좋게 아는 유형이 나오면 과대평가되고 반대면 과소평가됩니다. 대신 이 대회에서 수집할 진짜 데이터는 세 가지입니다.

  1. 어느 분야에서 점수가 나오는가 — 주력 분야의 실전 검증
  2. 시간이 어디로 갔는가 — 착수에서 포기까지의 시간 분포
  3. 멘탈이 언제 흔들렸는가 — 로그의 막힘 메모가 그대로 보여 줍니다

2-2. 대회의 시간 구조 — 48시간은 "하루 반"이다

주말 대회의 표준은 금요일 밤(한국 시간) 시작, 일요일 밤 종료의 48시간입니다. 그러나 실제로 쓸 수 있는 시간은 수면과 식사를 빼면 절반 남짓입니다. 대회 전에 몰입 시간대를 미리 정하세요.

[48시간 대회 시간 설계 예시] — 화면 예시가 아닌 계획 템플릿
금 21:00  대회 시작 → 전체 훑기 30분 → 쉬운 문제 워밍업
금 24:00  취침 (첫날 밤샘 금지 — 둘째 날 오후의 집중력을 살리는 투자)
토 09:00  본격 공략 블록 1 (주력 분야)
토 14:00  블록 2 (주력 외 쉬운 문제 수확)
토 19:00  블록 3 → 자정 전 취침
일 09:00  블록 4 — "가장 가까운 문제"에 화력 집중
일 21:00  종료 → 즉시 회고 메모 30분

포인트는 첫날 밤샘 금지입니다. 경험자들이 반복해서 보고하는 패턴이 있습니다 — 금요일 밤을 새운 참가자는 토요일 오후에 판단력이 무너지고, 그 시간대가 정작 점수가 갈리는 시간입니다. 48시간 대회에서 수면은 이탈이 아니라 전략입니다.

2-3. 문제 선정 — 점수판이 알려 주는 것

대회 문제판은 대략 이런 모양입니다 (화면 예시):

┌──────────┬──────────┬──────────┬──────────┬──────────┐
│   Web    │   Pwn    │   Rev    │  Crypto  │Forensics │
├──────────┼──────────┼──────────┼──────────┼──────────┤
│ 50  ★12  │ 100 ★3   │ 100 ★5   │ 100 ★8   │ 100 ★9   │
│ 150 ★4   │ 200 ★1   │ 200 ★2   │ 150 ★6   │          │
│ 300 ★0   │          │          │          │          │
└──────────┴──────────┴──────────┴──────────┴──────────┘
(★숫자 = 풀이자 수)

풀이자 수가 사실상의 난이도입니다. 최근 대회 플랫폼은 다이내믹 스코어링(많이 풀릴수록 배점이 내려가는 방식)을 쓰는 경우가 많아, 처음 표시된 배점보다 "몇 명이 풀었나"가 더 정직한 신호입니다. 시작 직후 30분의 전체 훑기에서 할 일은 각 문제의 설명을 읽고 ① 내 분야인가 ② 풀이자가 늘고 있는가를 메모하는 것입니다.

첫 착수는 전략이 정해져 있습니다: 풀이자가 가장 많은 문제부터. 이유는 점수가 아니라 흐름입니다 — 첫 플래그를 빨리 따야 "오늘은 되는 날"의 감각이 생기고, 그 감각이 어려운 문제를 붙잡는 체력이 됩니다.

2-4. 왜 로그인가 — 대회가 끝나면 기억은 삭제된다

대회 중의 여러분은 생각보다 기억을 못 합니다. 셸을 따낸 짜릿함 뒤에는 "그때 무슨 명령을 쳤더라"가 사라지고, 막힌 문제의 좌절 뒤에는 "어디까지 갔더라"가 사라집니다. 복기(Step 280)의 품질은 대회 중 기록의 품질이 결정합니다.

기록할 이벤트는 네 종류로 충분합니다.

이벤트 의미 메모에 남길 것
start 문제 착수 분야, 문제명, 배점
solve 플래그 제출 성공 (해결 시각이 자동 기록)
stuck 진행이 멈춤 멈춘 지점의 구체적 원인
drop 손절 손절 사유(2시간 규칙 등)

stuck의 메모가 핵심입니다. "안 됨"은 복기 재료가 안 되고, "안티 디버깅 구간에서 진행 멈춤"은 복기의 출발점이 됩니다. 미래의 나에게 보내는 편지라고 생각하고 한 줄을 남기세요.

2-5. 2시간 규칙 — 손절도 실력이다

한 문제에 진전이 없는 채 2시간이 지나면, 그 문제는 오늘의 여러분이 풀 수 없는 문제일 확률이 높습니다. 이때 물러나는 것이 2시간 규칙입니다. 중요한 것은 "포기"가 아니라 "보류"라는 점 — stuck 메모와 함께 drop하면, 그 문제는 대회가 끝난 뒤 복기 블록 A의 재료가 됩니다.

2시간은 절대값이 아니라 기준선입니다. 주말 48시간 대회에서 여러분의 총 가용 시간이 20시간이라면, 한 문제에 3시간을 쓰는 순간 다른 문제 서너 개의 기회가 사라집니다. 첫 대회에서는 규칙을 딱딱하게 지키는 쪽이 낫습니다. 예외 판단은 데이터가 쌓인 세 번째 대회부터 해도 늦지 않습니다.


3. 따라 하기

3-1. 대회 확정과 등록 점검 (화면 예시)

Step 190에서 확정한 대회를 다시 확인합니다. 확인할 것은 네 가지입니다.

[대회 페이지 최종 점검] — 화면 예시
□ 시작/종료 시각을 한국 시간으로 환산해 캘린더에 넣었다
□ 대회 플랫폼(별도 사이트)에 계정을 만들고 로그인을 확인했다
□ 팀 등록이 필요한 대회라면 팀 코드/초대를 완료했다
□ 규칙 페이지의 금지 사항(자동화 스캔 제한, 공유 금지 등)을 읽었다

마지막 항목이 법적·규칙적 안전장치입니다. 대회마다 "문제 서버에 대한 디도스성 스캔 금지", "대회 중 Write-up 공개 금지" 같은 규칙이 있고, 어기면 실격됩니다. 규칙 읽기 5분이 첫 대회의 가장 싼 보험입니다.

3-2. 환경 점검 — 대회 전날의 30분

대회 중에 도구가 안 돌아가면 그 시간은 그대로 증발합니다. 전날 이 목록을 돌립니다.

[환경 점검 체크리스트]
- [ ] Kali 부팅과 업데이트 상태 확인 (대회 당일 업데이트는 금물)
- [ ] VPN/네트워크 — 대회 인프라 접속에 필요한 설정이 있다면 미리 테스트
- [ ] 분야별 핵심 도구 기동 확인: Burp Suite, gdb/pwntools, Ghidra, CyberChef, Wireshark
- [ ] 침투 플레이북(Step 272) 최신화 — 지난 실전 머신의 새 기법 반영 여부
- [ ] 스크린샷 도구와 메모 앱을 항상 떠 있게 배치
- [ ] ctf_log.py를 홈 디렉터리에 배치하고 한 번 실행해 본다

3-3. 대회 로그 스크립트 만들기 (실측)

대회 중 기록은 가벼워야 합니다 — 셸에서 한 줄 치면 끝나야 대회 흐름이 안 끊깁니다. 다음 스크립트를 ctf_log.py로 저장하세요. 이벤트를 CSV에 쌓고, report로 요약을 보는 도구입니다.

# ctf_log.py — 대회 중 문제별 착수/해결/막힘/포기를 CSV에 기록
import csv, sys, os
from datetime import datetime

LOG = "ctf_log.csv"
FIELDS = ["시각", "이벤트", "분야", "문제", "배점", "메모"]

def now():
    return datetime.now().strftime("%m-%d %H:%M")

def load():
    if not os.path.exists(LOG):
        return []
    with open(LOG, newline="", encoding="utf-8") as f:
        return list(csv.DictReader(f))

def save(rows):
    with open(LOG, "w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=FIELDS)
        w.writeheader()
        w.writerows(rows)

def add(event, problem_arg, points, memo, at):
    rows = load()
    if " - " in problem_arg:
        field, problem = problem_arg.split(" - ", 1)
    else:
        field, problem = "", problem_arg
    if event != "start":   # start 이후 이벤트는 분야·배점을 start 기록에서 이어받는다
        for r in rows:
            if r["이벤트"] == "start" and r["문제"] == problem:
                field = field or r["분야"]
                points = points or r["배점"]
    rows.append({"시각": at or now(), "이벤트": event, "분야": field,
                 "문제": problem, "배점": points or "", "메모": memo or ""})
    save(rows)
    print(f"기록: [{at or now()}] {event} {field + ' - ' if field else ''}{problem}")

명령은 네 가지입니다 (report는 아래 3-4에서).

python ctf_log.py start "Web - warmup-cookie" 50     # 착수 (배점은 선택)
python ctf_log.py solve "warmup-cookie"              # 해결
python ctf_log.py stuck "license-check" "안티 디버깅 구간에서 멈춤"   # 막힘
python ctf_log.py drop "license-check" "2시간 규칙 발동"              # 손절

시각을 생략하면 현재 시각이 들어가고, 대회 후 정리할 때는 네 번째 인자로 "04-11 21:12" 같은 시각을 직접 넣을 수 있습니다.

3-4. 대회 운영 시연 — 로그 기록 (실측)

첫 대회의 이틀이 어떻게 로그에 남는지, 예시 대회(가상의 "Weekend CTF 1")를 실제로 스크립트에 기록해 보았습니다. 아래는 Git Bash에서의 실측 출력입니다 (시각은 사후 입력 모드로 넣은 예시 데이터).

$ python ctf_log.py start "Web - warmup-cookie" 50 "04-11 21:12"
기록: [04-11 21:12] start Web - warmup-cookie
$ python ctf_log.py solve "warmup-cookie" "04-11 21:34"
기록: [04-11 21:34] solve Web - warmup-cookie
$ python ctf_log.py start "Crypto - caesar-training" 100 "04-11 21:40"
기록: [04-11 21:40] start Crypto - caesar-training
$ python ctf_log.py solve "caesar-training" "04-11 22:05"
기록: [04-11 22:05] solve Crypto - caesar-training
$ python ctf_log.py start "Rev - license-check" 200 "04-11 22:20"
기록: [04-11 22:20] start Rev - license-check
$ python ctf_log.py stuck "license-check" "안티 디버깅 구간에서 진행 멈춤" "04-11 23:30"
기록: [04-11 23:30] stuck Rev - license-check
$ python ctf_log.py drop "license-check" "2시간 규칙 발동, 오늘은 접기" "04-11 23:40"
기록: [04-11 23:40] drop Rev - license-check
$ python ctf_log.py start "Forensics - packet-present" 100 "04-12 09:10"
기록: [04-12 09:10] start Forensics - packet-present
$ python ctf_log.py solve "packet-present" "04-12 09:48"
기록: [04-12 09:48] solve Forensics - packet-present
$ python ctf_log.py start "Web - admin-panel" 300 "04-12 10:20"
기록: [04-12 10:20] start Web - admin-panel
$ python ctf_log.py stuck "admin-panel" "SQLi 페이로드 전부 차단됨" "04-12 12:10"
기록: [04-12 12:10] stuck Web - admin-panel
$ python ctf_log.py start "Crypto - xor-note" 150 "04-12 12:30"
기록: [04-12 12:30] start Crypto - xor-note
$ python ctf_log.py stuck "xor-note" "키 길이 추정에서 막힘" "04-12 14:00"
기록: [04-12 14:00] stuck Crypto - xor-note

이 로그를 읽으면 대회의 스토리가 보입니다: 금요일 밤 워밍업 두 문제를 빠르게 따고(각 22분, 25분), 200점짜리 Rev에서 첫 벽을 만나 2시간 규칙으로 접었습니다. 토요일 오전 Forensics로 흐름을 되찾았고, 오후에 300점 Web과 Crypto에서 차례로 막혔습니다. 3문제 해결, 3문제 막힘 — 첫 대회치고 아주 정상적인, 그리고 복기 가치가 큰 결과입니다.

3-5. 종료 직후 — report로 요약 보기 (실측)

대회가 끝나면(또는 중간 점검에) report 한 줄이 대회를 숫자로 보여 줍니다. 실측 출력입니다.

$ python ctf_log.py report
=== 대회 로그 요약 (ctf_log.csv) ===
이벤트 13건 / 착수 6문제 / 해결 3문제

[해결한 문제]
  Web        warmup-cookie        50점  소요 22분
  Crypto     caesar-training     100점  소요 25분
  Forensics  packet-present      100점  소요 38분

[못 푼 문제 — 복기 후보]
  Rev        license-check      stuck 메모: 안티 디버깅 구간에서 진행 멈춤
  Rev        license-check      drop  메모: 2시간 규칙 발동, 오늘은 접기
  Web        admin-panel        stuck 메모: SQLi 페이로드 전부 차단됨
  Crypto     xor-note           stuck 메모: 키 길이 추정에서 막힘

읽는 법: ① 해결 문제의 소요 시간(22~38분)은 여러분의 "쉬운 문제 처리 속도"입니다 — 다음 대회 워밍업 계획의 근거가 됩니다. ② "못 푼 문제" 목록이 Step 280 복기 블록 A의 대상 풀입니다. stuck 메모를 구체적으로 써 둔 덕분에, 대회가 끝나고 일주일이 지나도 어디서 멈췄는지 바로 복원됩니다.

3-6. 회고 메모 — 골든타임 30분

종료 직후 30분 안에 쓰는 회고가 가장 정확합니다. 다음 틀에 세 문단만 채우세요.

[대회 회고 — Weekend CTF 1]
1. 숫자: 푼 문제 3개(250점), 순위 ○○/○○○, 착수 6개 중 해결 3개
2. 잘된 것: 워밍업 두 문제를 30분 안에 따서 흐름을 탔다
3. 아쉬운 것: admin-panel에서 2시간을 쓰고도 stuck — WAF 우회 학습 부족
4. 가장 가까웠던 미해결: xor-note (키 길이까지는 접근)
5. 다음 대회 전까지 할 것: 복기 블록 A 3문제(license-check, admin-panel, xor-note)

마지막 항목이 3-5의 "복기 후보"와 연결되는 고리입니다. 이 회고 메모와 ctf_log.csv 두 개가 이번 챕터의 산출물 전부입니다 — 작아 보이지만, Step 280과 Step 283이 이 두 파일 위에서 돌아갑니다.


4. 미션과 연습문제

미션 — 첫 대회 완주

  1. 확정한 주말 대회에 등록하고, 3-2의 환경 점검 체크리스트를 대회 전날에 완료합니다.
  2. 대회 시작 직후 30분 동안 전체 문제를 훑고, 풀이자 수 기준 쉬운 문제부터 착수합니다.
  3. 대회 기간 내내 모든 착수·해결·막힘·손절을 ctf_log.py에 기록합니다.
  4. 종료 후 30분 안에 3-6의 회고 메모를 작성합니다.
  5. report 출력과 회고 메모를 보관합니다 — Step 280에서 그대로 사용합니다.

연습문제

문제 1. 첫 대회의 목표를 "성적"이 아니라 "완주와 데이터 수집"으로 정하는 이유 두 가지를 말해 보세요.

문제 2. 대회 시작 직후, 배점이 높은 문제보다 풀이자가 많은 문제를 먼저 잡으라고 권하는 이유를 설명해 보세요.

문제 3. 3-4의 로그에서 license-check는 왜 drop이 정답이었나요? 2시간 규칙의 관점에서 설명해 보세요.

문제 4. stuck 메모에 "안 됨" 대신 "안티 디버깅 구간에서 진행 멈춤"처럼 구체적으로 써야 하는 이유를 복기 절차와 연결해 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

검증하는 법: ① ctf_log.csv를 열어 이벤트가 대회 시작부터 종료까지 분포해 있는가 — 첫날만 있고 둘째 날이 비어 있으면 중도 이탈 신호입니다. ② stuck/drop 이벤트의 메모가 "안 됨"이 아니라 멈춘 지점의 설명인가. ③ 회고 메모에 숫자(푼 문제 수, 점수)와 "가장 가까웠던 미해결"이 적혀 있는가. ④ 풀지 못한 문제가 3개 이상 로그에 남아 다음 복기 대상이 확정됐는가. 한 문제도 못 풀었어도 ①~④가 채워져 있으면 이 미션은 성공입니다 — 0점의 로그도 완전한 데이터입니다.

연습문제 해답

문제 1 해답. ① 첫 대회의 점수는 대회별 난이도 편차와 문제 유형의 운에 좌우돼 실력의 측정값이 되지 못합니다. ② 완주하며 남긴 로그 — 어느 분야에서 점수가 나왔는지, 시간이 어디로 갔는지 — 가 다음 대회의 전략과 복기의 원재료가 되기 때문입니다. 성적은 두 번째 대회부터 의미를 갖습니다.

문제 2 해답. 풀이자 수는 사실상의 난이도 지표이고, 쉬운 문제를 빨리 해결하면 초반에 "오늘은 되는 날"의 흐름이 생깁니다. 이 흐름(사기)이 후반의 어려운 문제를 붙잡는 집중력의 원천이 됩니다. 다이내믹 스코어링 대회라면 일찍 푼 쪽이 배점도 높게 유지되는 부수적 이득도 있습니다.

문제 3 해답. 22:20 착수 → 23:30 stuck까지 70분간 진전이 없었고, 메모가 "안티 디버깅 구간" — 입문자가 대회 중 학습 없이 뚫기 어려운 유형입니다. 첫날 밤의 남은 시간을 이 문제에 쓰면 둘째 날 오전의 컨디션까지 잃습니다. drop으로 보류해 두면 대회 후 Write-up으로 배울 수 있으므로, 그날의 시간과 문제의 학습 가치를 둘 다 지키는 선택입니다.

문제 4 해답. 복기 블록 A의 첫 질문은 "내가 어디까지 도달했는가"입니다. 메모가 구체적이면 정답 Write-up과 내 도달 지점을 바로 비교해 "다음 한 발"을 찾을 수 있지만, "안 됨"은 비교 기준이 없어 복기 자체가 불가능합니다. 기록의 구체성이 복기의 출발점 좌표입니다.

완료 기준 체크리스트

  • [ ] 첫 대회의 목표가 "완주와 데이터 수집"인 이유를 설명할 수 있다
  • [ ] 대회 전날 환경 점검 체크리스트(도구·계정·플레이북)를 완료했다
  • [ ] 시작 30분의 전체 훑기와 "풀이자 많은 문제 우선" 전략을 실행했다
  • [ ] 착수·해결·막힘·손절을 시각과 함께 로그로 남겼다
  • [ ] 2시간 규칙을 최소 한 번은 의식적으로 적용했다
  • [ ] 종료 30분 안에 회고 메모를 작성했다
  • [ ] report 출력에서 복기 후보 문제 목록을 확인했다

6. 흔한 실수와 해결

벽 1. 대회 시작 시간을 착각해 첫날을 날렸어요

증상: 금요일 저녁에 접속했는데 대회가 아직 안 열렸거나, 반대로 이미 진행 중입니다.

원인: CTFtime은 UTC 표기입니다. 한국은 UTC+9라서, UTC 금요일 12:00 시작은 한국 시간 금요일 밤 9시입니다.

해결: 대회 페이지의 시각을 캘린더 앱에 넣을 때 처음부터 한국 시간으로 환산해 등록하세요. 시작 1시간 전 알림과 시작 알림 두 개를 겁니다.

벽 2. 플래그를 맞게 구했는데 제출이 안 돼요

증상: 플래그 제출 시 이런 메시지가 뜹니다 (화면 예시 — 플랫폼마다 다릅니다).

Incorrect flag. You have 4 attempts remaining before a 60 second lockout.

원인 1순위: 플래그 앞뒤의 공백·줄바꿈이 같이 복사됐습니다. 2순위: 대회마다 플래그 형식(flag{...}, CTF{...}, 대회명 접두사)이 다릅니다.

해결: 제출 전에 앞뒤 공백을 지우고, 문제 설명에 적힌 플래그 형식을 확인하세요. 반복 실패로 잠금(lockout)되면 그 문제의 제출 시도 자체가 시간 낭비가 됩니다 — 대회 시작 때 문제 설명의 형식 안내를 읽는 습관이 답입니다.

벽 3. 한 문제에 매달려 대회가 끝났어요

증상: "조금만 더 하면 될 것 같은데"가 네 시간을 먹었고, 로그에는 이벤트가 하나뿐입니다.

원인: 몰입 중에는 시간 감각이 꺼집니다. 2시간 규칙은 의지가 아니라 장치로 지켜야 합니다.

해결: 착수와 동시에 2시간 타이머를 켜세요. 타이머가 울릴 때 "마지막으로 새로 배운 사실이 언제인가"를 묻습니다 — 답이 한 시간 전이면 drop이 정답입니다.

벽 4. 로그 스크립트가 에러를 뱉어요

증상 (실측):

$ python ctf_log.py stuck onlyname
Traceback (most recent call last):
  File ".../ctf_log.py", line 81, in <module>
    add("stuck", sys.argv[2], "", sys.argv[3], ...)
IndexError: list index out of range

원인: stuckdrop은 메모가 필수 인자인데 빠졌습니다.

해결: python ctf_log.py stuck "문제명" "막힌 지점 설명"처럼 메모를 반드시 붙이세요. 어차피 메모 없는 stuck은 복기 가치가 없으니, 이 에러는 스크립트가 옳은 것입니다.

벽 5. 한 문제도 못 풀고 대회가 끝났어요

원인: 첫 대회 선정이 무거웠거나, 단순히 문제 유형이 안 맞았을 수 있습니다. 둘 다 실력 부족의 증거가 아닙니다.

해결: "어느 분야가 가장 가까웠나"를 회고에 적으세요 — 그것이 다음 목표입니다. stuck 메모들이 남아 있다면 이번 대회는 0점이 아니라 복기 재료 3개를 확보한 대회입니다. 다음 대회는 "Beginner/Junior" 표기 대회로 난이도를 조정하고, 막힌 유형은 Step 280의 복기로 메웁니다.


7. 정리

오늘의 개념

개념 한 줄 설명
완주 목표 첫 대회의 성공 조건은 점수가 아니라 끝까지 남긴 로그
전체 훑기 30분 시작 직후 모든 문제 설명을 읽고 분야·풀이자 수를 메모하는 시간
풀이자 수 사실상의 난이도 지표 — 배점보다 정직한 신호
다이내믹 스코어링 많이 풀릴수록 배점이 내려가는 방식 — 일찍 풀수록 유리
2시간 규칙 진전 없이 2시간이면 drop(보류) — 손절도 실력
대회 로그 start/solve/stuck/drop 네 이벤트의 시각 기록 — 복기의 원재료
회고 골든타임 종료 직후 30분 — 기억이 살아 있을 때 쓰는 회고가 가장 정확

오늘의 명령어

명령 하는 일
python ctf_log.py start "분야 - 문제" 배점 문제 착수 기록
python ctf_log.py solve "문제" 플래그 해결 기록
python ctf_log.py stuck "문제" "멈춘 지점" 막힘 기록 — 메모 필수
python ctf_log.py drop "문제" "사유" 손절(보류) 기록
python ctf_log.py report 해결/미해결 요약 — 복기 후보 목록

핵심 감각

대회는 시험이 아니라 측정 장치입니다. 첫 대회에서 여러분이 가져오는 것은 점수가 아니라 "내 실력의 좌표"입니다 — 어느 분야가 되는지, 어느 유형에서 멈추는지, 시간이 어디로 새는지. 좌표가 있어야 지도가 그려지고, 그 지도의 첫 구간이 바로 다음 챕터의 복기입니다.

그리고 하나 더 — 대회 채팅방을 구경하세요. 혼자 온 사람들, 같은 문제에서 막힌 사람들이 거기 있습니다. 오늘의 완주가 Step 281의 팀 대회로 가는 다리가 됩니다.


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