Step 276. 속도 훈련: Easy 4시간 컷 — 루틴을 자동화 수준으로 끌어올린다
Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★☆☆ | 예상 소요 시간 1일 (4시간 타임어택 + 분석 1시간)
전제: Step 130(타임어택 모의 침투)의 배분표·30분 규칙, Step 251 이후의 실전 머신 루틴, 파이썬 3(랩타임 분석기용).
- 준비물: 처음 보는 HTB 또는 THM Easy 머신 1대, 타이머, 랩타임 로그 파일, 파이썬 3. 이 챕터의 머신 공략 장면은 화면 예시, 파이썬 랩타임 분석기 실행은 실측(2026-09-09, Python 3.12)으로 표시했습니다.
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. Hack The Box(
hackthebox.com)와 TryHackMe는 운영자가 공격 연습용으로 공식 개방한 합법 학습 플랫폼입니다 — 이 플랫폼들의 머신 외에는 오늘의 기술을 쓰지 않습니다. - 이 챕터는 훈련 방법론 챕터입니다. 새 기법이 아니라 "기존 루틴의 속도"를 측정하고 깎는 날입니다.
대회에서 상위권을 가르는 것은 Hard를 푸는 사람이 아니라 Easy를 빨리 정리하는 사람입니다. Easy급에 8시간을 쓰는 팀은 어려운 문제를 볼 시간 자체가 없습니다. 지금까지 쌓은 정찰 → 침투 → 상승 루틴을, 생각하지 않아도 나오는 수준으로 끌어올려 Easy를 4시간 안에 끝내는 것이 오늘의 목표입니다.
단, 속도 훈련의 적은 느림이 아니라 성급함입니다. 빨리 하되 건너뛰지 않는 것 — 그 균형의 답은 병렬화에 있습니다. 기다리는 시간을 다른 조사로 채우는 사람은 건너뛰지 않고도 빠릅니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- Easy 머신 4시간 타임어택의 구간별 예산표를 세우고 지킨다
- 스캔·브루트포스처럼 기다리는 작업을 백그라운드로 돌리며 조사를 병렬화한다
- 리버스 쉘·권한 상승 명령을 플레이북에서 즉시 꺼내 쓰는 템플릿 동선을 만든다
- 단계별 타임스탬프를 기록하고 랩타임 분석기로 병목 구간을 수치로 확인한다
- "언제 포기하고 Write-up을 보는가"의 기준선을 세운다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | HTB/THM Easy 머신, Kali 또는 WSL, 타이머, 파이썬 3(랩타임 분석기) |
| 오늘의 명령 | 전부 복습 — nmap(빠른 스캔+전수 병렬), gobuster, 리버스 쉘·상승 템플릿 |
| 필요한 개념 | 병렬화(parallelization), 단계별 시간 예산, 병목(bottleneck), 포기 기준선 |
| 오늘의 산출물 | 랩타임 로그 + 병목 분석 결과(예산 대비 편차 표) |
2-1. 4시간 예산표 — Easy의 시간 지도
Easy 4시간의 기본 배분입니다. Step 130의 6시간 배분표를 Easy에 맞게 압축한 형태입니다.
| 구간 | 예산 | 목표 | 종료 신호 |
|---|---|---|---|
| ① 정찰·열거 | 0:00~0:30 | 공격 표면 + 취약점 후보 목록 | 후보 목록 완성(전수 스캔 완료 아님) |
| ② 침투 | 0:30~2:30 | 첫 쉘 | whoami 출력 |
| ③ 권한 상승 | 2:30~4:00 사이 2시간 | root/SYSTEM | id에서 uid=0 |
| ④ 기록 | 마지막 30분 | 재현 가능한 로그 | 랩타임 로그 완성 |
| 여유 | 30분 | 밀린 구간 흡수 | — |
Easy에서 4시간을 넘기는 가장 흔한 원인은 ①이 1시간을 넘는 것입니다. 정찰이 길어지는 것은 스캔이 느려서가 아니라 스캔을 기다리는 동안 아무것도 안 해서입니다.
2-2. 병렬화 — 대기 시간을 조사 시간으로 바꾼다
속도 훈련의 기술은 사실 하나입니다. 기다리지 않는다.
시각 0:00
├─ 터미널 1: nmap -sV 대상 (1~2분, 이걸 먼저 읽는다)
├─ 터미널 2: nmap -p- 대상 -oN full.txt (느림 → 백그라운드)
└─ 터미널 3: 웹 포트가 보이면 gobuster 즉시 시작 (느림 → 백그라운드)
시각 0:03부터: 터미널 1의 결과를 읽으며 웹 수동 탐색
— 터미널 2, 3은 여러분이 판단하는 동안에도 일하고 있습니다
사람이 판단하는 시간 동안 기계가 열거하는 구조 — 이것이 "건너뛰지 않는 속도"의 전부입니다. 반대로 gobuster가 끝나길 멍하니 기다리는 10분은 실력이 아니라 일정 설계의 실패입니다.
2-3. 템플릿 동선 — 손이 뇌보다 먼저
Easy의 리버스 쉘, 권한 상승 열거는 이미 아는 것들입니다. 아는 것을 느리게 꺼내는 이유는 찾는 데 시간을 쓰기 때문입니다. 속도 훈련 전에 플레이북의 "즉시 복붙 구역"을 정리합니다.
플레이북 즉시 복붙 구역 (예시 목차):
- 리버스 쉘 3종: bash, python3, php — 리스너 여는 명령과 한 쌍으로
- 쉘 안정화: python3 -c 'import pty;pty.spawn("/bin/bash")' + stty 한 묶음
- 상승 열거 한 덩어리: Step 130의 whoami&&id&&... 시퀀스
- 웹 기본: gobuster/dirsearch 표준 명령, 워드리스트 경로
기준은 10초 규칙입니다 — 필요한 명령을 10초 안에 터미널에 붙여넣을 수 없으면 템플릿 정리가 미완성입니다.
2-4. 포기 기준선 — Write-up을 보는 것도 전략이다
속도 훈련에서 Write-up은 금지가 아니라 미리 정한 조건에서만 허용되는 도구입니다. 기준선 예시:
- 침투 구간(2시간)을 통째로 초과했는데 새 가설이 0개 → 힌트 수준(방향만) 열람 허용
- 힌트 후 30분 안에 진전 없음 → 해당 구간의 Write-up 단락만 열람
- 단, 열람 사실과 시각을 로그에 기록 — "혼자 4시간"과 "Write-up 동반 4시간"은 다른 성적입니다
기준선 없이 "막히면 보는" 것은 훈련의 붕괴이고, 절대 보지 않는 것은 시간의 낭비입니다. 기준선은 시작 전에 정합니다 — 막힌 상태의 뇌는 공정한 심판이 못 됩니다.
3. 따라 하기
3-1. 시작 전 — 머신 선정과 예산표 세팅
처음 보는 Easy 머신을 고릅니다 — 아는 머신으로는 속도를 측정할 수 없습니다. 랩타임 로그 파일을 만듭니다.
입력 (laps.txt의 형식 — 구간이 끝날 때마다 한 줄씩 추가):
정찰 | 0:00
왜 이 형식인가: "구간명 | 경과시각" 두 칸이면 충분합니다. 정교한 표를 도중에 채우다가 흐름이 끊기느니, 한 줄 추가가 5초인 형식이 살아남습니다. 종료 후 분석은 스크립트가 합니다(3-4).
3-2. 정찰 구간 — 세 터미널의 동시 가동
화면 예시 (정찰 5분 차의 화면 — 여러분의 머신에서 직접 확인하세요):
# 터미널 1 (0:00 시작, 0:02 종료)
$ nmap -sV 10.10.11.50
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu
80/tcp open http nginx 1.18.0
# 터미널 2 (0:00 시작, 백그라운드 계속)
$ nmap -p- 10.10.11.50 --min-rate 2000 -oN full.txt
# 터미널 3 (0:02 시작, 백그라운드 계속)
$ gobuster dir -u http://10.10.11.50 -w /usr/share/wordlists/dirb/common.txt
읽는 법: 2분 만에 "웹과 SSH"라는 윤곽이 섰고, 여러분은 지금부터 웹사이트를 손으로 훑는 동안 전수 스캔과 디렉터리 탐색이 뒤에서 돕니다. 0:30에 후보 목록이 서면 이 구간의 성공입니다.
3-3. 침투·상승 구간 — 템플릿 동선의 실전
후보를 버전 일치 순으로 시도하되(Step 130의 기준), 명령은 전부 즉시 복붙 구역에서 나와야 합니다. 타이핑이 아니라 판단에 시간을 쓰는 것이 이 훈련의 정상 상태입니다.
화면 예시 (랩타임 로그가 채워지는 모습):
정찰 | 0:00
정찰 | 0:35
침투 | 2:50 ← whoami: www-data 확보
상승 | 3:40 ← id: uid=0(root)
기록 | 4:25
읽는 법: 각 줄은 "그 구간이 끝난 경과시각"입니다. 이 다섯 줄이 오늘의 전체 성적표입니다 — root 여부보다 이 숫자들이 훈련의 대상입니다.
3-4. 종료 후 — 랩타임 분석기로 병목 확인
로그를 분석기에 넣어 예산 대비 편차를 봅니다.
입력 (tmp_test/lap_budget.py의 핵심 부분):
BUDGET = {"정찰": 30, "침투": 120, "상승": 120, "기록": 30} # 분, Easy 4시간 기준
for name, end in laps[1:]:
actual = end - prev
budget = BUDGET.get(name, 0)
diff = actual - budget
verdict = "초과 — 원인 기록 필요" if diff > 0 else "예산 내"
출력 (2026-09-09 실측, 3-3의 예시 로그 입력, Python 3.12):
구간 예산 실제 편차 판정
--------------------------------------------
정찰 30분 35분 +5분 초과 — 원인 기록 필요
침투 120분 135분 +15분 초과 — 원인 기록 필요
상승 120분 50분 -70분 예산 내
기록 30분 45분 +15분 초과 — 원인 기록 필요
--------------------------------------------
총 소요 265분 (4시간 25분) / 목표 240분
읽는 법: 25분 초과의 정체가 숫자로 보입니다 — 상승에서 70분을 아꼈는데 침투와 기록에서 흘렸습니다. 다음 훈련의 과제는 "전체적으로 더 빨리"가 아니라 "침투의 +15분과 기록의 +15분" 두 개뿐입니다. 병목이 이름을 가지면 처방이 가능합니다.
왜: "4시간 컷 실패"는 감정이지만 "+25분, 원인 2건"은 계획입니다. 속도 훈련의 반복이 실력으로 쌓이려면 매 판이 이 표로 끝나야 합니다.
4. 미션과 연습문제
미션 — Easy 4시간 타임어택과 병목 분석
- 처음 보는 Easy 머신을 골라 4시간 타이머를 맞추고,
laps.txt에 시작을 기록합니다. - 정찰을 병렬화합니다 — 빠른 스캔/전수 스캔/디렉터리 탐색의 동시 가동을 로그에 명시합니다.
- 플레이북 즉시 복붙 구역을 정리하고, 공략 중 10초 규칙을 지켰는지 자가 점검합니다.
- 포기 기준선(2-4)을 시작 전에 문장으로 적고, Write-up을 봤다면 시각과 범위를 기록합니다.
- 종료 후 랩타임 분석기로 구간별 편차를 내고, 초과 구간마다 원인 한 줄을 붙입니다.
연습문제
문제 1. 병렬화가 "건너뛰지 않는 속도"라고 불리는 이유는 무엇인가요? 성급함과 무엇이 다른가요?
문제 2. 3-4 실측에서 상승 구간이 예산보다 70분 빨랐는데도 총 목표를 초과했습니다. 이 결과가 "속도 훈련 실패"와 다른 의미를 갖는 이유를 설명해 보세요.
문제 3. 템플릿 즉시 복붙 구역의 완성 기준을 "10초 규칙"으로 정하는 이유는 무엇인가요?
문제 4. Write-up 열람의 기준선을 막힌 뒤가 아니라 시작 전에 정해야 하는 이유는 무엇인가요?
5. 모범 답안과 완료 기준
미션 모범 답안
4시간 내 root가 이상형이지만, 채점은 과정 기준입니다.
- 병렬화의 흔적: 로그에 동시에 굴린 작업이 2개 이상 명시돼 있는가.
- 10초 규칙: 즉시 복붙 구역이 실제로 쓰였는가 — 공략 중 명령을 "검색해서" 찾았다면 템플릿 미완성으로 기록.
- 랩타임의 완결: 다섯 줄(시작+4구간)이 빠짐없이 있는가. 기록이 없는 속도는 측정 불가라 훈련이 안 됩니다.
- 병목의 명명: 초과 구간마다 원인 한 줄이 붙어 있는가 — "침투 +15분: 익스플로잇 3개를 무순서 시도" 수준.
- 기준선 준수: Write-up을 봤다면 시각·범위가 기록돼 있고, 시작 전에 적은 기준선 안인가.
연습문제 해답
문제 1 해답. 병렬화는 절차를 생략하지 않고 대기 시간만 제거하기 때문입니다. 전수 스캔을 안 돌리는 것은 성급함(정보를 버림)이지만, 전수 스캔을 돌리는 동안 웹을 손으로 훑는 것은 병렬화(같은 정보를 더 빨리 얻음)입니다. 둘의 결과물 — 후보 목록 — 은 동일하고, 걸린 시간만 다릅니다. 속도 훈련에서 깎아야 할 것은 절차가 아니라 대기입니다.
문제 2 해답. 총 초과(+25분)가 두 개의 구체적 원인으로 분해됐기 때문입니다. "실패"는 원인 불명의 정체된 상태지만, 이 표는 다음 훈련의 과제가 "침투 +15분, 기록 +15분" 두 건임을 알려 줍니다. 상승의 -70분은 이미 몸에 붙은 강점으로 확인됐으니 손댈 필요가 없습니다. 훈련의 성패는 목표 달성이 아니라 다음 과제의 확정으로 판정합니다.
문제 3 해답. 10초를 넘는 순간 찾기 행위 자체가 새로운 몰입이 되어 공략의 흐름을 끊기 때문입니다. 명령을 검색하다 보면 문서를 읽게 되고, 문서를 읽다 보면 판단 중이던 가설의 실마리가 휘발됩니다. 또한 10초는 측정 가능한 기준입니다 — "빨리 찾을 수 있다"는 자기 평가는 과대평가되기 쉬워서, 숫자로 된 기준이 있어야 템플릿 정리의 완료 여부를 채점할 수 있습니다.
문제 4 해답. 막힌 상태의 뇌는 공정한 심판이 아니기 때문입니다. 2시간을 허비한 직후에는 "힌트 하나쯤은"이라는 판단이 합리화로 스며듭니다 — 기준선이 없으면 열람의 문턱이 막힘의 강도에 따라 매번 낮아집니다. 시작 전에 정한 기준선은 냉정한 상태의 나가 막힌 상태의 나에게 내리는 규칙입니다. 그리고 기록의 의무(시각·범위)가 있어야 "혼자 푼 4시간"과 "동반한 4시간"이 성적표에서 구분됩니다.
완료 기준 체크리스트
- [ ] Easy 4시간 예산표(구간·종료 신호)를 시작 전에 세웠다
- [ ] 정찰 구간을 세 갈래 이상 병렬로 진행했다
- [ ] 플레이북 즉시 복붙 구역을 정리하고 10초 규칙을 점검했다
- [ ] 포기 기준선을 시작 전에 문장으로 적었다
- [ ] 다섯 줄의 랩타임 로그를 완성했다
- [ ] 랩타임 분석기로 구간별 편차를 냈다
- [ ] 초과 구간마다 원인 한 줄을 기록했다
6. 흔한 실수와 해결
벽 1. 전수 스캔이 안 끝나서 정찰 구간이 끝나버려요
증상: -p- 스캔이 30분을 넘깁니다.
원인: 스캔 속도 자체보다, 종료 조건을 "전수 스캔 완료"로 잡은 설계 오류입니다.
해결: 정찰 구간의 종료 신호는 "취약점 후보 목록 완성"입니다(2-1 표). 빠른 스캔 결과로 열거를 시작하고, 전수 스캔은 뒤에서 돌게 하세요. 침투 구간 중간에 full.txt를 열어 놓친 포트가 있는지 한 번만 확인하면 됩니다 — 그 확인이 후반부의 헤맴을 막는 보험입니다. 또한 --min-rate 등으로 속도 옵션을 플레이북에 고정해 두세요.
벽 2. 병렬로 돌려놓고 정작 어느 터미널이 뭔지 헷갈려요
증상: 터미널이 다섯 개 열려 있고 무엇이 끝났는지 모릅니다.
원인: 병렬화에 이름표가 없었습니다. 개수는 늘렸는데 관리가 안 된 상태입니다.
해결: 터미널마다 제목을 붙이거나(tmux 창 이름, 탭 이름), 출력을 전부 파일로 남기세요 — -oN full.txt처럼. 그리고 병렬 작업은 3개가 상한입니다. 그 이상은 관리 비용이 절약분을 먹습니다. "지금 내가 기다리는 것은 무엇인가"에 즉답이 안 나오면 병렬이 아니라 산만입니다.
벽 3. 랩타임 분석기가 엉뚱한 숫자를 뱉어요
증상 (2026-09-09 실측):
ValueError: invalid literal for int() with base 10: '4시간'
원인: 로그의 시각 칸에 4:25가 아니라 4시간 25분처럼 한글이 섞여 들어갔습니다. 분석기는 시:분 형식만 읽습니다.
해결: 로그 형식은 기계가 읽는 것이 우선입니다 — h:mm만 쓰세요. 도중의 메모("이때 점심")는 같은 줄이 아니라 별도 줄이나 로그 말미로 빼는 습관을 들이면, 어떤 분석 스크립트에 넣어도 깨지지 않습니다.
벽 4. 빨리 하려다 쉘을 자꾸 놓쳐요
증상: 리버스 쉘이 연결됐다 끊기고, 웹쉘이 응답 없이 죽습니다. 급할수록 어이없는 실수가 늘어납니다.
원인: 속도를 손가락에서 내고 있습니다. 타이핑을 서두르면 리스너 포트 오타, IP 오타가 나옵니다 — 오타 하나의 복구 비용이 템플릿 복붙 열 번보다 큽니다.
해결: 속도는 절차에서 냅니다 — 병렬화, 템플릿, 포기 기준선. 손가락은 오히려 평소보다 느리게, 한 번에 맞게 치는 쪽이 총시간이 짧습니다. "빠른 사람은 정확한 사람이다"를 이 훈련 기간의 좌우명으로 삼으세요.
벽 5. 4시간 안에 못 뚫었는데 계속할지 말지 모르겠어요
증상: 4시간이 울렸는데 "거의 다 온 것 같습니다."
원인: 타임어택의 종료 조건과 학습의 욕심이 충돌하는 정상적 순간입니다.
해결: 시계를 멈추고 성적을 확정한 뒤, 이어서 하는 것은 허용합니다 — 단, 로그를 분리하세요. "4:00 시점 최대 진척: user 쉘"이 이번 판의 성적이고, 그 이후의 공략은 별도 로그의 학습 시간입니다. 성적과 학습을 섞으면 다음 타임어택의 비교 기준이 사라집니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 병렬화 | 기다리는 시간을 다른 조사로 채우는 것 — 건너뛰기가 아닌 속도 |
| 시간 예산표 | 구간별 시간과 종료 신호를 미리 정하는 Easy 4시간 지도 |
| 10초 규칙 | 필요한 명령을 10초 안에 붙여넣을 수 있는 템플릿 완성 기준 |
| 포기 기준선 | Write-up 열람을 허용하는 사전 조건 — 시작 전에 정한다 |
| 병목 분석 | 랩타임 로그에서 초과 구간과 원인을 수치로 확정하는 사후 절차 |
오늘의 명령·도구
| 명령·도구 | 하는 일 |
|---|---|
nmap -sV <IP> / nmap -p- <IP> --min-rate 2000 -oN full.txt |
빠른 스캔(전면) + 전수 스캔(백그라운드)의 분리 |
gobuster dir -u <URL> -w <워드리스트> |
웹 디렉터리 탐색 — 백그라운드로 |
| 플레이북 즉시 복붙 구역 | 리버스 쉘·쉘 안정화·상승 열거의 10초 동선 |
laps.txt + lap_budget.py (예제 스크립트) |
구간별 종료 시각 기록과 예산 대비 편차 계산 |
명령어보다 중요한 감각
속도 훈련이 끝나면 깨닫게 됩니다 — 4시간 컷을 가르는 것은 새로운 기술이 아니라 대기의 제거와 손의 정확성입니다. 기계가 일하는 동안 사람이 판단하고, 사람은 아는 명령을 틀리지 않고 한 번에 치는 것. 이 두 가지가 맞물리면 Easy는 "풀리는 문제"에서 "처리하는 문제"로 바뀝니다.
그리고 이 감각이 다음 단계 — Medium 8시간의 장기전 — 의 입장권입니다. Easy에서 시간을 아끼는 사람이 Medium에서 시간을 배분할 수 있습니다.
전부 체크되면 Step 276 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.