Step 256. HTB Easy 2대 — 혼자서 root까지: 안내 없는 첫 완주
Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★★☆ | 예상 소요 시간 8시간+ (머신당 4시간 안팎)
전제: Step 255(Starting Point 완주, HTB식 규칙), Step 253(privesc 패턴 노트), Step 251의 루틴 문서를 갖췄다.
- 준비물: Step 255의 HTB 환경과 완주 노트, Step 253의 privesc 패턴 노트, 실시간 메모용 에디터, 충분한 시간(하루에 한 대씩 잡는 것을 권장).
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. Hack The Box(
hackthebox.com)는 운영자가 공격 연습용으로 공식 개방한 합법 학습 플랫폼입니다 — 이 플랫폼의 머신 외에는 오늘의 기술을 쓰지 않습니다. - 플랫폼 안내: 이 챕터의 HTB 화면과 명령 출력은 전부 화면 예시입니다. 실제 공략은 여러분이 직접 합니다.
오늘은 이 커리큘럼에서 가장 조용하고 가장 무거운 챕터입니다. 해야 할 일은 단순합니다 — HTB Easy 머신 두 대를, write-up도 힌트도 없이, 정찰부터 root까지 혼자 뚫는 것. Starting Point까지는 안내가 있었습니다. 오늘부터는 없습니다.
"혼자서"의 의미를 먼저 합의합시다. 검색 엔진으로 기술 문서를 찾는 것까지 금지하지는 않습니다 — CVE의 공식 설명, man 페이지, 도구 문서는 실전에서도 쓰는 자원입니다. 금지인 것은 딱 하나, 이 머신의 풀이를 담은 것 — write-up, 풀이 영상, 머신 이름이 들어간 블로그 글입니다. 그 경계를 지키는 것 자체가 오늘의 훈련입니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- "혼자 푼다"의 허용 자원과 금지 자원의 경계를 설명한다
- Active/Retired 머신의 차이를 알고 훈련용 머신을 선정한다
- 막힘을 감정이 아니라 절차로 처리하는 루틴(30분 규칙)을 적용한다
- 공략 과정을 실시간으로 기록해 write-up의 원재료를 만든다
- 6시간 이상의 막힘에서 허용되는 최소 힌트의 사용 규칙을 안다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | HTB Easy 머신(Active 권장) + 공격 머신 + 루틴 문서 |
| 오늘의 명령 | 지금까지 배운 전부 — 새 명령은 없다. nmap -sV -p-부터 플래그 제출까지 |
| 필요한 개념 | Active/Retired 머신, 막힘 관리(30분 규칙), 실시간 공략 로그 |
| 오늘의 산출물 | Easy 2대 독립 해결(user+root) + 공략 로그 2부 + Easy 패턴 정리 |
2-1. HTB Easy의 진짜 뜻
HTB에서 "Easy"는 "쉽다"가 아닙니다. "필요한 기법이 표준적이다"라는 뜻입니다. 이상한 트릭이나 난독화는 없지만, 표준 기법의 전 사이클 — 정찰, 열거, 침투, 권한 상승 — 을 빠짐없이 요구합니다.
THM Easy에서 힌트를 받아 넘어갔던 구간이 있다면, 그 구간이 오늘 바로 시험에 나옵니다. 그래서 Step 251~252에서 "힌트 본 룸은 재풀이 목록에"라는 규칙을 두었던 것입니다. 그 재풀이가 안 됐다면 오늘이 사실상 그 재시험입니다.
2-2. Active와 Retired — 어떤 머신을 고를 것인가
HTB 머신은 두 상태로 나뉩니다.
| 상태 | 설명 | write-up | 오늘의 선택 |
|---|---|---|---|
| Active | 현재 시즌에 점수가 걸린 머신 | 공식 공유 금지 — 널려 있지 않음 | 권장 |
| Retired | 은퇴한 머신 | 공식 write-up과 영상이 널려 있음 | 자제력이 필요 |
Retired 머신은 검색 한 번에 정답이 나옵니다. 그 환경에서 "혼자 풀기"는 기술이 아니라 의지의 문제가 됩니다. Active 머신은 구조적으로 정답이 없습니다 — 공식 규칙상 풀이 공유가 금지되어 있어, 검색해도 방향성 힌트 수준만 나옵니다. 오늘의 독립 훈련에는 Active가 맞습니다. 단, Active 머신은 유료 구독 없이 선택 폭이 좁을 수 있고, 무료 슬롯은 다중 사용자 환경이라는 점(Step 255)을 감안하세요.
2-3. 막힘 관리 — 30분 규칙
독립 공략의 진짜 적은 난이도가 아니라 막힘 속에서의 판단력 붕괴입니다. 한 경로에 세 시간을 쏟은 뒤에야 "처음부터 틀렸다"를 깨닫는 것 — 이것을 막는 것이 절차입니다.
[30분 규칙]
한 가설(경로)에 30분을 썼는데 새로운 사실이 하나도 안 나왔다
→ 멈추고 다음 셋 중 하나로:
① 열거로 회귀 — 놓친 포트/경로/버전이 있는가 (풀스캔 재확인)
② 가설 목록 재정렬 — 다음 우선순위 후보로 이동
③ 15분 휴식 — 뇌의 배경 처리를 믿는다
핵심은 "새로운 사실"의 유무입니다. 30분 동안 로그가 늘고 단서가 나왔다면 그 경로는 살아 있습니다. 아무것도 안 나왔는데 계속 두드리는 것이 함정입니다.
2-4. 힌트의 계급 — 어디까지가 허용인가
막힘이 6시간을 넘을 때를 대비해, 허용 자원을 계급으로 정리해 둡니다.
허용 (언제든): 도구 문서, man 페이지, CVE/기법 설명 글 (머신 이름 없는 것)
최후 수단 (6시간+): HTB 포럼의 공식 힌트 스레드 — "방향성" 댓글 1개까지만
금지: write-up, 풀이 영상, 머신 이름이 들어간 블로그/깃허브/디스코드 풀이
포럼 힌트를 봤다면 그 사실을 로그에 기록합니다 — "6시간 20분, 포럼 힌트 1개 열람: 웹 열거 방향". Starting Point 때의 규칙과 같습니다. 힌트로 넘어간 구간은 아직 내 것이 아니며, 재풀이 대상입니다.
2-5. 실시간 공략 로그 — 쓰면서 푸는 이유
독립 공략에서는 기록이 결과물이 아니라 사고 도구입니다. 막힌 상태에서 "지금까지 뭘 했지?"를 로그에서 읽으면, 반복한 경로와 안 본 경로가 구분됩니다. 그리고 이 로그가 훗날 여러분의 write-up 원고가 됩니다 — 머신이 Retired 되면 공유할 수 있는 자산이 됩니다.
형식은 3번 섹션에서 만듭니다.
3. 따라 하기
오늘의 3번 섹션은 "실행할 명령"이 아니라 "진행할 절차"입니다. 화면은 전부 예시이고, 실제 공략은 여러분의 몫입니다.
3-1. 머신 선정과 개시 선언
HTB 머신 목록에서 난이도 Easy, 상태 Active인 머신을 고릅니다. 고르는 기준:
- 최근 몇 주 내에 나온 것보다 약간 지난 것 (초기 불안정이 가라앉은 것)
- OS는 리눅스 우선 (Step 253의 패턴 노트를 바로 쓸 수 있도록)
- 두 대는 서로 다른 시즌의 것으로 (같은 출제자의 패턴 반복 방지)
머신을 스폰하고 IP를 받으면 로그 파일을 만들고 개시를 선언합니다 (화면 예시):
mkdir -p ~/htb/machinename && cd ~/htb/machinename
export TARGET=10.129.10.10
echo "# 머신명 — 시작 $(date '+%F %T')" > log.md
머신당 폴더 하나, 로그 하나 — 이 구조가 Step 257~258에서도 이어집니다.
3-2. 정찰 — 로그와 함께하는 첫 1시간
입력 (화면 예시):
nmap -sV -p- $TARGET -oN nmap-full.txt
출력 예시:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5
80/tcp open http nginx 1.18.0 (Ubuntu)
읽는 법: -oN으로 출력을 파일에 저장하는 것이 THM 때와 다른 점입니다 — 독립 공략에서는 모든 증거가 파일로 남아야 나중에 로그가 재구성됩니다. 웹(80)이 보이면 정찰은 여기서 안 끝납니다:
# 경로 스캔까지가 "정찰 한 세트"입니다 (화면 예시)
gobuster dir -u http://$TARGET -w /usr/share/wordlists/dirb/common.txt -o gobuster.txt
정찰 단계의 완료 조건을 정해 두세요 — "풀스캔 + 버전 + (웹이면) 경로 스캔까지, 그리고 가설 3개를 로그에 적는 것". 가설이 없는 정찰은 정찰이 아니라 스캔일 뿐입니다.
3-3. 가설 우선순위 — 로그의 핵심 페이지
정찰이 끝나면 로그에 가설 목록을 씁니다 (예시):
## 가설 (우선순위 순)
1. [ ] nginx 뒤의 웹앱 — /admin 경로 발견, 기본 자격증명 시도
2. [ ] ssh — 유효 사용자명을 웹에서 수집해 무차별 대입 (최후 수단)
3. [ ] nginx 1.18.0 자체 취약점 — searchsploit 확인 (가능성 낮음)
## 시도 기록
- 14:20 가설1 — /admin 로그인 폼, admin:admin 실패
- 14:35 가설1 — 로그인 폼의 SQLi 흔적 없음
- 14:50 (30분 규칙 발동) — 가설1 보류, gobuster 재스캔(더 큰 워드리스트)
읽는 법: "시도 기록"의 타임스탬프가 30분 규칙의 심판입니다. 시간과 결과를 적다 보면 "같은 곳을 세 번 두드렸다"는 것이 스스로 보입니다. 이 로그 습관이 Step 258(시간 제한 훈련)의 직접적인 전제입니다.
3-4. user에서 root로 — 패턴 노트 전개
user.txt까지 왔다면, 이제 Step 253의 도구를 꺼낼 시간입니다 (화면 예시):
sudo -l
find / -perm -4000 2>/dev/null
cat /etc/crontab
읽는 법: 순서는 출현 빈도 순 — sudo -l → SUID → cron. HTB Easy의 상승 경로는 대부분 이 첫 화면에서 답이 보입니다. 보이지 않으면 그때 linPEAS를 올려 후보를 넓히고, 각 후보는 수동으로 검증합니다(Step 253의 원칙 — 도구는 후보를 주고, 사람이 검증한다).
root.txt를 읽으면 로그에 경로를 한 줄로 요약합니다:
## 완료
- user: 웹앱 업로드 우회 → 리버스 쉘 (3시간 10분)
- root: sudo -l → /usr/bin/특정도구 → GTFOBins (40분)
- 힌트 사용: 없음
3-5. 두 대째의 규칙 — 패턴 정리
두 번째 머신은 첫 번째와 다른 입구를 가진 것이 좋습니다. 첫 대가 웹이었다면, 둘째는 서비스(SMB/FTP/기타) 중심의 머신을 고르세요. 이유는 Step 257에서 본격화하는 "입구 유형 다양화"의 전초입니다.
두 대를 끝내면 마지막 산출물을 만듭니다 — Easy에서 자주 나오는 패턴 정리:
## Easy 패턴 (2대 관찰)
- 입구는 결국 "열거를 다 한 사람"에게 보인다 — 둘 다 첫 스캔에서 놓친 게 답이었다
- 상승은 sudo -l이 2/2 — 첫 명령의 가치
- 웹 머신은 결국 경로 스캔 워드리스트 크기 싸움
2대로는 표본이 작습니다. 그래서 이 표는 Step 257(누적 4), Step 258(누적 6)에서 계속 자랍니다.
4. 미션과 연습문제
미션 — Easy 2대 독립 해결
- Active Easy 머신 2대를 선정합니다 (OS·입구 유형이 겹치지 않게)
- 머신당 폴더를 만들고, 로그에 개시 시각을 기록합니다
- 모든 스캔 출력을
-oN/-o옵션으로 파일에 남깁니다 - 가설 목록과 30분 규칙의 발동 기록을 로그에 남기며 진행합니다
- user.txt와 root.txt를 모두 제출합니다 — 두 대 모두
- 힌트를 사용했다면 시각과 내용(어느 수준까지 봤는지)을 로그에 기록하고 재풀이 목록에 올립니다
- 3-5의 "Easy 패턴" 정리를 작성합니다
연습문제
문제 1. "혼자 푼다"는 규칙에서 CVE 설명 글은 허용이고 write-up은 금지입니다. 이 둘을 가르는 기준을 한 문장으로 써 보세요.
문제 2. 30분 규칙에서 판단 기준은 "시간"만이 아니라 "새로운 사실의 유무"라고 했습니다. 왜 시간만으로는 부족한지 예를 들어 설명해 보세요.
문제 3. Retired 머신이 독립 훈련에 부적합한 구조적 이유를 설명하고, 그럼에도 Retired 머신이 유용한 상황을 하나 들어 보세요.
문제 4. 정찰 단계에서 nmap만 치고 웹 경로 스캔을 건너뛰면 어떤 일이 생기는지, "완료 조건을 정해 둔 정찰"과 비교해 설명해 보세요.
5. 모범 답안과 완료 기준
미션 모범 답안
머신 로그의 완성 형태 예시입니다 (내용은 여러분의 실제 풀이입니다):
# 머신A — 시작 2026-09-10 14:00
## 정찰
- nmap -sV -p- (nmap-full.txt): 22 ssh, 80 http nginx
- gobuster (gobuster.txt): /admin, /uploads 발견
## 가설
1. [x] /uploads 업로드 우회 → 쉘 ← 정답이었다
2. [ ] ssh 무차별 대입 (보류)
## 시도 기록
- 14:40 업로드 폼 발견, 확장자 필터 확인 중
- 15:30 (30분 규칙) 필터 우회 실패 → 워드리스트 확장 재스캔
- 16:10 .phtml 업로드 성공 → 리버스 쉘
## 완료
- user: 17:20 (3시간 20분)
- root: sudo -l → GTFOBins, 17:55 (35분)
- 힌트 사용: 없음
## 배운 것
- 업로드 필터 우회: 확장자 대소문자·이중확장자는 시도했는데 .phtml을 늦게 떠올림 → 체크리스트에 추가
검증하는 법: ① HTB 프로필에 두 머신의 user/root 제출 기록이 있는가. ② 로그에 타임스탬프가 실시간 순서로 쌓여 있는가(완성 후 조작한 흔적이 없는가). ③ 스캔 출력 파일이 로그와 같은 폴더에 있는가. ④ 힌트 사용 여부가 정직하게 적혀 있는가. ⑤ 패턴 정리가 "느낌"이 아니라 관찰(2대에서 무엇이 반복됐는가)인가.
연습문제 해답
문제 1 해답. "이 머신의 답을 알려 주는가, 아니면 기법 일반을 알려 주는가"가 기준입니다. CVE-XXXX의 설명과 익스플로잇 코드는 그 취약점 일반에 대한 것이고 실전에서도 참고하는 자원입니다. 반면 write-up은 "이 머신에서는 어디를 보세요"라는 답지입니다 — 그것을 읽는 순간 이번 판은 연습이 아니라 베끼기가 됩니다.
문제 2 해답. 살아 있는 경로는 30분을 넘겨도 계속 단서를 뱉기 때문입니다. 예를 들어 로그인 폼을 공격하는데 30분 동안 오류 메시지의 차이를 발견하고 유효 계정 하나를 건졌다면, 이 경로는 시간 초과가 아니라 진행 중입니다. 반대로 30분 동안 출력이 하나도 안 바뀌었다면 그것은 "더 두드려도 나올 게 없다"는 데이터입니다. 규칙의 본질은 타이머가 아니라 "경로의 생사를 결과물로 판정하는 것"입니다.
문제 3 해답. Retired 머신은 공식 write-up과 풀이 영상이 검색 한 번에 나오므로, "혼자 풀기"가 정보 환경이 아니라 자제력에 의존하게 됩니다 — 그리고 막힌 시간이 길어질수록 자제력은 반드시 무너집니다. 유용한 상황은 검증과 복습입니다 — Active에서 독립으로 푼 뒤 같은 머신이 Retired 되면 공식 write-up과 내 풀이를 비교해 더 나은 경로를 배우는 것, 또는 특정 기법(예: 특정 CMS 공략)만 집중 연습하고 싶을 때 일부러 정답이 있는 환경을 쓰는 것입니다.
문제 4 해답. nmap은 "어떤 문이 있는가"를 알려 주지만 웹 머신의 진짜 입구 — 업로드 페이지, 백업 파일, 관리자 경로 — 는 문 안쪽에 있습니다. 경로 스캔 없이 "포트는 80 하나뿐이고 취약점도 안 보인다"는 결론은, 사실은 "안쪽을 안 본" 것입니다. 완료 조건이 있는 정찰(풀스캔 + 버전 + 경로 + 가설 3개)은 이 공백을 절차로 막습니다 — 가설을 3개 쓰려고 하면 보통 그 과정에서 경로 스캔이 강제되기 때문입니다.
완료 기준 체크리스트
- [ ] Active Easy 머신 2대를 선정했다 (유형이 겹치지 않게)
- [ ] 머신당 로그 파일과 스캔 출력 파일을 남겼다
- [ ] write-up·풀이 영상 없이 두 대 모두 user+root를 제출했다
- [ ] 30분 규칙을 발동하고 그 기록이 로그에 있다
- [ ] 힌트 사용 시 기록하고 재풀이 목록에 올렸다
- [ ] 두 대의 입구 유형이 서로 달랐다
- [ ] "Easy 패턴" 정리를 작성했다
6. 흔한 실수와 해결
벽 1. 세 시간째 아무것도 안 나온다 — 멘탈이 먼저 무너진다
증상: 같은 명령을 반복해서 치고 있고, 로그의 마지막 타임스탬프가 오래됐습니다.
원인: 막힘의 실체는 기술이 아니라 시야의 좁아짐입니다. 한 가설에 갇히면 열거 결과에 이미 있는 답도 안 보입니다.
해결: 30분 규칙을 강제 발동하세요 — ① 풀스캔 결과를 처음부터 다시 읽기(처음에 "별거 아님"으로 넘긴 포트가 답인 경우가 잦습니다), ② 15분 자리를 비우기, ③ 로그의 "시도 기록"을 소리 내어 읽기. 세 시간은 실패가 아니라 데이터입니다 — 어디서 시간이 갔는지가 Step 258의 재료가 됩니다.
벽 2. 검색하다가 write-up을 봐 버렸다
증상: 기법을 검색했는데 결과 페이지에 이 머신의 풀이 글이 떴고, 첫 문단을 읽어 버렸습니다.
원인: Active 머신도 비공식 풀이는 돌아다닙니다. 완벽하게 피하는 것은 불가능에 가깝습니다.
해결: 본 것을 없던 것으로 할 수는 없으니, 정직하게 처리하세요 — 로그에 "어떤 내용까지 봤는지"를 기록하고, 그 부분은 더 이상 ‘독립 해결’이 아님을 인정합니다. 머신을 끝까지 완주하되, 이 머신은 재풀이 목록에 올립니다. 오늘의 훈련 목표는 플래그가 아니라 "혼자 뚫는 경험"임을 기억하세요.
벽 3. user는 잡았는데 root에서 두 시간째 헤맨다
증상: sudo -l, SUID, cron에 전부 답이 없고 linPEAS도 빨간 후보만 잔뜩입니다.
원인: 윈도우 머신인데 리눅스 패턴 노트만 펼치고 있거나, 반대의 경우이거나 — 또는 열거의 깊이가 부족합니다.
해결: 체크리스트로 회귀하세요 — OS 재확인(uname -a 또는 systeminfo), 실행 중인 프로세스(ps aux / Get-Process), 홈 폴더와 /opt, /var의 비정상 파일, 설정 파일 속 자격증명. linPEAS의 후보는 하나씩 수동 검증하세요 — 빨간색 열 개보다 "실제로 재현된 하나"가 답입니다. 그래도 안 되면 6시간 규칙(2-4)에 따라 포럼 방향성 힌트 1개까지 허용됩니다.
벽 4. 다중 사용자 머신에서 다른 플레이어가 판을 어지럽힌다
증상: 서비스가 죽어 있다가 살아나고, 심어 둔 파일이 사라지고, 포트 상태가 수시로 바뀝니다.
원인: 무료 Active 슬롯은 공유 환경입니다(Step 255). 누군가는 익스플로잇으로 서비스를 죽이기도 합니다.
해결: 머신 리셋을 요청하세요 — HTB는 머신 페이지에 리셋(재시작) 버튼이 있습니다. 단, 리셋하면 머신 위의 내 흔적도 전부 사라지니 필요한 파일은 로컬에 보관합니다. 사람이 적은 시간대(대상 지역의 새벽~이른 아침)를 노리는 것도 실전 요령입니다.
벽 5. 두 대째에서 첫 대와 같은 기법만 반복해서 시도한다
증상: 첫 대가 업로드 우회였다면, 둘째에서도 업로드 지점만 찾고 있습니다.
원인: 성공한 경로는 뇌에 깊이 새겨집니다 — 그런데 그것이 다음 판의 편향이 됩니다.
해결: 가설 목록을 쓸 때 첫 대의 기법은 의식적으로 후순위에 두세요. 그리고 3-5의 규칙 — "두 대째는 입구가 다른 머신" — 를 선정 단계에서 지키면 이 함정은 구조적으로 피해집니다. 편향 교정은 Step 257의 주제 그 자체입니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| Active / Retired | 현행 점수 머신(풀이 공유 금지) / 은퇴 머신(write-up 공개) |
| 독립 해결 | 머신의 풀이를 담은 자원 없이 완주하는 것 |
| 30분 규칙 | 새 사실 없이 30분이면 가설을 갈아타는 절차 |
| 6시간 규칙 | 그 이상의 막힘에는 포럼 방향성 힌트 1개까지 허용 |
| 실시간 공략 로그 | 타임스탬프가 붙은 시도 기록 — 사고 도구이자 write-up 원재료 |
| 가설 우선순위 | 정찰의 완료 조건 — 다음에 두드릴 것 3개의 목록 |
오늘의 명령어·도구
| 명령 | 하는 일 |
|---|---|
nmap -sV -p- $TARGET -oN 파일 |
풀스캔 + 증거 파일 저장 |
gobuster dir -u URL -w 워드리스트 -o 파일 |
웹 경로 스캔 + 저장 |
sudo -l / find / -perm -4000 / cat /etc/crontab |
상승 첫 화면 (빈도 순) |
mkdir ~/htb/머신명 |
머신당 폴더 — 로그와 증거의 집 |
| (절차) 30분 타이머 | 막힘 관리의 물리적 장치 — 폰 알람으로 |
명령어보다 중요한 감각
오늘의 완료 조건은 플래그 네 개가 아니라 "아무도 알려 주지 않는 머신 앞에서 내 루틴이 굴러갔다"는 확인입니다. 돌이켜 보면 막힘의 대부분은 기술 부족이 아니라 절차 이탈에서 옵니다 — 풀스캔을 건너뛰거나, 가설 없이 두드리거나, 죽은 경로에 매달리거나. 그래서 30분 규칙과 로그는 장식이 아니라 구명줄입니다. 그리고 혼자 힘으로 root.txt를 연 그 순간의 감각 — 그것은 어떤 강의도 주지 못합니다. 두 대로는 시작일 뿐입니다. 이 경험을 네 대, 여섯 대로 쌓아 가는 것이 다음 두 챕터입니다.
전부 체크되면 Step 256 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.