Step 265. HTB Medium 1대 — 며칠 걸려도 독립 해결

Step 265. HTB Medium 1대 — 며칠 걸려도 독립 해결

Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★★★ | 예상 소요 시간 3일(하루 2~3시간)

전제: Step 252(THM Easy 누적 8 — 루틴 정착)와 Step 253(리눅스 privesc)을 마쳤다. Step 264(피벗팅)까지 읽었으면 내부 서비스를 만났을 때의 대처가 수월합니다.

  • 준비물: HTB 계정과 VPN(VIP 없어도 무료 머신 가능), Step 252에서 만든 공통 루틴 문서, 진척 로그용 폴더, 그리고 3일의 시간.
  • ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. HackTheBox(HTB)는 공격 실습을 위해 만들어진 합법 플랫폼입니다 — 그 머신들 외에는 오늘의 기술을 쓰지 않습니다.
  • 플랫폼 안내: 이 챕터의 HTB 화면과 공략 장면은 전부 화면 예시입니다. 이 책 서버에서 HTB에 접속해 검증할 수 없으므로, 실제 풀이는 여러분의 손으로 진행합니다.

첫 Medium 머신은 벽입니다. Easy에서 익힌 "표준 기법 하나로 입구가 열리는" 감각이 여기서는 통하지 않습니다 — 입구가 두 겹이고, 뚫려도 권한 상승이 꼬여 있습니다. 오늘의 목표는 빨리 푸는 것이 아닙니다. 며칠 걸려도 끝까지 혼자 푸는 것, 그리고 그 과정 전부를 진척 로그로 남기는 것입니다. 이 한 대가 Easy 열 대보다 실력을 올립니다.


1. 학습 목표

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

  • Easy와 Medium의 구조적 차이(체인, 꼬임, 열거 요구량)를 설명한다
  • 하루 단위의 가설-검증 사이클로 며칠짜리 공략을 운영한다
  • 막혔을 때 "기법 부족"과 "열거 부족"을 구분해 처방을 다르게 한다
  • 서비스 이름으로 HackTricks 등에서 공략법을 조사하는 리서치 루틴을 돌린다
  • 날짜별 진척 로그를 써서 나중의 Write-up과 복기의 재료로 만든다

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

오늘의 도구 한눈에 보기

구분 내용
언어·환경 Step 252의 공격 환경 그대로 (Kali + HTB VPN)
오늘의 명령 nmap -sV -p-, nmap -sU --top-ports 100, gobuster vhost, ffuf -u ... -H "Host: FUZZ.target" — 열거 심화 세트
필요한 개념 취약점 체인, 가설-검증 사이클, 열거 심화(UDP·vhost·서브도메인), 리서치 루틴
오늘의 산출물 Medium 1대 root + 날짜별 진척 로그 + 회고 타임라인

2-1. Easy와 Medium은 무엇이 다른가 — 구조로 보는 난이도

난이도 차이는 "더 어려운 기법"이 아니라 구조에 있습니다.

[Easy]   정찰 → 취약점 1개 → 쉘 → 상승 기법 1개 → root
[Medium] 정찰(더 깊게) → 정보 조각 A → A가 열쇠인 문 B → 쉘
         → 상승 경로가 꼬임 (보이는 것이 함정, 진짜 길은 따로)

차이 세 가지를 짚으면 이렇습니다.

  • 체인: Medium은 취약점 하나로 끝나지 않습니다. 페이지 소스의 주석에서 자격증명 조각을 얻고, 그것으로 로그인한 관리 페이지에서 업로드 취약점을 찾고, 업로드로 얻은 쉘 안에서 다시 상승 경로를 찾습니다. "이 발견이 어디의 열쇠인가"를 계속 물어야 합니다.
  • 꼬임: 보이는 길이 함정인 경우가 있습니다. 뻔한 SUID 바이너리는 막혀 있고, 진짜 길은 cron의 스크립트 권한에 있습니다. 첫 가설이 틀리는 것이 Medium의 기본값입니다.
  • 열거 요구량: Easy는 기본 스캔에 입구가 나오지만, Medium은 2차 열거(UDP, vhost, 더 큰 워드리스트)에서 입구가 나오는 경우가 흔합니다.

2-2. 며칠 걸리는 것이 정상입니다

Easy 누적 8대를 판당 1시간 안팎에 끝낸 손으로 Medium을 시작하면, 첫날 밤에 자괴감이 옵니다. "아무것도 못 찾았다"는 기록이 정상입니다.

HTB의 Medium 평가에서 숙련자도 수 시간을 쓰고, 이 난이도가 처음인 사람에게 사흘은 빠른 편입니다. 며칠 걸리는 이유는 실력 부족이 아니라 가설의 수 때문입니다 — Easy는 검증할 가설이 몇 개지만, Medium은 입구 후보가 열 개씩 생기고 그중 아홉을 폐기하는 시간이 필요합니다.

그래서 이 챕터의 시간 단위는 "판"이 아니라 "날"입니다. 하루 2~3시간씩, 매일 "오늘의 가설" 하나를 적고 시작하고, 결과를 적고 닫습니다. 끊고 이어가는 운영 자체가 훈련입니다.

2-3. 막힘의 70%는 열거 부족입니다

Medium에서 막혔을 때, 그 원인은 대체로 둘 중 하나입니다.

  • 열거 부족(다수): 입구는 있는데 못 봤습니다. UDP 포트를 스캔하지 않았거나, vhost를 안 훑었거나, 워드리스트가 작았거나, 페이지 소스의 주석을 지나쳤습니다. 처방은 "더 깊게·더 넓게 보기"입니다.
  • 기법 부족(소수): 입구는 봤는데 뚫는 법을 모릅니다. 처음 보는 서비스, 처음 보는 프레임워크입니다. 처방은 리서치입니다 — 서비스 이름과 버전으로 HackTricks 페이지를 찾고, 없으면 "서비스명 + pentest/exploit"로 검색합니다.

구분법은 간단합니다. "내가 수집한 정보에 아직 안 쓴 조각이 있는가?" — 있으면 열거 문제, 조각은 다 썼는데 방법을 모르겠으면 기법 문제입니다. 이 구분이 되면 막힘이 막막함에서 체크리스트로 바뀝니다.

2-4. 진척 로그 — 며칠짜리 공략의 항해 일지

며칠에 걸친 공략에서 기억은 믿을 수 없습니다. 사흘 전에 "이 포트는 아니었어"라고 판단한 근거를 넷째 날은 기억하지 못합니다. 그래서 날짜별로 씁니다.

### Day 1 (2.5h)
- 가설: 80번 웹의 /admin이 입구일 것
- 한 일: 풀스캔 완료(22, 80), 경로 스캔 common.txt → /admin 403
- 배운 것: 403은 존재한다는 뜻 — 접근 방법이 따로 있을 것
- 내일: 더 큰 워드리스트 + vhost 스캔

### Day 2 (3h)
- 가설: vhost에 개발용 서브도메인이 있을 것
- 한 일: ffuf vhost 퍼징 → dev.target 발견, 소스에 API 키 노출
- 막힘: API 키를 어디에 쓰는지 40분 헤맴 → /api/docs 발견
- 내일: 키로 인증되는 엔드포인트 전수 확인

이 로그는 세 가지 일을 합니다. 내일의 나에게 오늘의 맥락을 전해 주고(재개 비용 제거), 같은 시도를 두 번 하는 낭비를 막고, 풀고 나면 그대로 Write-up의 뼈대가 됩니다.


3. 따라 하기

3-1. 머신 선정 — 첫 Medium의 조건

첫 Medium은 "좋은 입문용 Medium"이 따로 있습니다. 고르는 기준은 셋입니다.

□ 커뮤니티 평가가 좋은가 (머신 페이지의 별점·리뷰)
□ '공략이 명확하다'는 평이 있는가 (가설-검증 연습에 적합)
□ 최근에 푼 사람이 많은가 (질문할 커뮤니티 스레드가 살아 있음)

읽는 법: 유형은 Step 252에서 가장 자신 있던 쪽으로 고르세요. 첫 Medium의 적은 난이도이지 생소함이어서는 안 됩니다. 익숙한 지형(웹 중심이었다면 웹 중심)에서 "깊이"만 새로 배우는 것이 이 단계의 설계입니다.

3-2. Day 1 — 정찰을 Easy보다 한 층 깊게

첫날의 목표는 침투가 아니라 정보 수집의 완결입니다 (화면 예시):

mkdir -p htb/first-medium && cd htb/first-medium
export TARGET=10.10.11.XXX
nmap -sV -p- $TARGET -oN 01_full_tcp.txt
nmap -sU --top-ports 100 $TARGET -oN 02_udp_top100.txt

읽는 법: Easy 루틴과 다른 점은 UDP 스캔 줄입니다. Medium에서는 SNMP(161/udp) 같은 UDP 서비스가 입구인 경우가 있어, TCP만 보고 닫으면 첫날부터 길이 없어집니다. -oN으로 저장하는 습관은 Step 268에서 체계가 됩니다 — 오늘부터 시작하세요.

3-3. Day 1 계속 — 웹이 있다면 2차 열거까지

웹 포트가 보이면 Easy에서 하던 것에 두 줄을 더합니다 (화면 예시):

gobuster dir -u http://$TARGET -w /usr/share/wordlists/dirb/common.txt -x php,txt -oN 03_dirs.txt
gobuster vhost -u http://$TARGET -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -oN 04_vhosts.txt

그리고 사람의 눈이 할 일을 합니다 — 모든 페이지의 소스 보기, 주석(<!-- -->), robots.txt, JS 파일 안의 엔드포인트. Medium의 단서는 스캐너가 아니라 소스에 숨는 경우가 많습니다.

읽는 법: vhost 스캔은 같은 IP에서 Host 헤더만 바꿔 가상 호스트를 찾습니다. Easy에서는 거의 필요 없었지만, Medium에서는 "같은 웹 서버의 다른 사이트"가 입구인 설계가 흔합니다. 개념은 Step 268에서 로컬 실측으로 더 깊게 다룹니다.

3-4. Day 2~3 — 가설-검증 사이클 운영

둘째 날부터는 매일 같은 형식으로 돌립니다.

1. 어제 로그를 읽는다 (5분) — 어디까지가 확인된 사실인가
2. 오늘의 가설을 하나 쓴다 — "X가 입구일 것이다, 왜냐하면 Y"
3. 검증한다 — 가설이 참이면 다음 단계로, 거짓이면 '폐기 이유'를 로그에 남긴다
4. 막히면 2-3의 구분을 적용한다 — 열거 부족인가, 기법 부족인가
5. 닫기 전에 '내일의 첫 행동'을 한 줄 적는다

기법 부족으로 판명되면 리서치 루틴으로 들어갑니다 (화면 예시):

# 서비스/버전이 가설의 출발점
searchsploit "서비스명 버전"
# 브라우저: book.hacktricks.xyz에서 서비스명 검색

읽는 법: 리서치의 규칙은 하나입니다 — "익스플로잇 코드"가 아니라 "이 서비스의 공략 단계"를 찾는 것. HackTricks의 서비스 페이지는 "이 서비스를 만나면 무엇부터 확인하는가"의 목록이라, Medium의 리서치에 가장 잘 맞습니다.

3-5. root 이후 — 타임라인 회고

root 플래그를 얻으면 끝이 아니라 회고의 시작입니다. 진척 로그를 펴고 묻습니다.

□ 입구까지 며칠 걸렸는가 — 그리고 그 입구는 첫날 스캔에 이미 있었는가
□ 폐기한 가설은 몇 개인가 — 폐기가 빨랐는가, 늦었는가
□ 돌파의 결정적 단서는 무엇이었나 — 그 단서를 더 일찍 볼 방법이 있었나
□ 상승에서 무엇에 막혔나 — 그 기법을 플레이북에 추가했는가

읽는 법: 이 회고의 대답이 다음 챕터(Step 266 복기)의 재료이고, 이 머신의 학습 가치는 여기서 결정됩니다. root는 순간이고, 회고는 남습니다.


4. 미션과 연습문제

미션 — Medium 1대 독립 해결과 진척 로그

  1. 3-1의 기준으로 Medium 머신 1대를 선정하고, 선정 근거를 로그 첫 줄에 적으세요.
  2. 최소 3일에 나눠 진행합니다 — 하루를 시작할 때 "오늘의 가설"을, 닫을 때 "내일의 첫 행동"을 적습니다.
  3. 정찰에 UDP 스캔과 vhost 스캔을 포함하고, 모든 스캔 출력을 파일로 저장합니다.
  4. 막힐 때마다 2-3의 구분(열거/기법)을 로그에 표시하고, 적용한 처방을 적습니다.
  5. root 도달 후 3-5의 회고 네 질문에 답한 회고 섹션을 로그 끝에 씁니다.

규칙: 공식 Write-up이나 유튜브 풀이는 보지 않습니다. 막혀도 리서치(HackTricks, 문서, 검색)까지만 허용합니다. 남의 풀이를 본 경우 로그에 표시하고 Step 266에서 재공략 대상으로 삼습니다.

연습문제

문제 1. Medium이 Easy보다 어려운 이유를 "기법의 난이도"가 아니라 구조(체인·꼬임·열거 요구량)의 관점에서 설명해 보세요.

문제 2. "오늘의 가설"을 하루의 시작에 적는 이유를, 가설을 적지 않고 바로 도구부터 실행할 때 생기는 문제와 함께 설명해 보세요.

문제 3. 막힘을 "열거 부족"과 "기법 부족"으로 구분하는 기준을 쓰고, 각각의 처방이 왜 다른지 설명해 보세요.

문제 4. 진척 로그가 "며칠짜리 공략"에서 특히 중요한 이유를, 하루짜리 공략과 비교해 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

로그의 형태 예시입니다 (내용은 여러분의 실제 풀이로):

머신: (이름) — Medium / 선정 이유: 커뮤니티 평가 상위, 웹 중심
Day 1: 가설 "80번이 입구" → TCP 22,80 + UDP 스캔 완료. 경로/vhost 스캔 저장.
       발견: vhost에서 dev 서브도메인. 폐기 가설: /admin 우회(403 고정).
Day 2: 가설 "dev 사이트의 API가 입구" → JS에서 엔드포인트 3개 추출.
       막힘 14:00-15:20 [열거 부족] → 처방: 더 큰 리스트로 재스캔 → /backup 발견.
Day 3: 가설 "backup 아카이브의 설정 파일에 자격증명" → 적중. SSH 진입(user).
       상승: sudo -l은 함정, cron 스크립트 쓰기 권한으로 root. 총 7.5시간.
회고: 입구(vhost)는 Day 1 스캔에 있었으나 재스캔 전까지 못 봄 → 첫날 vhost까지
      마치는 루틴으로 교체. cron 권한 기법 플레이북에 추가.

검증하는 법: ① HTB 프로필에 해당 머신 완료(user+root) 표시. ② 로그에 날짜별 "가설/한 일/폐기 이유/내일의 첫 행동"이 있는가. ③ 막힘마다 [열거/기법] 구분이 붙어 있는가. ④ 회고 네 질문의 답이 있는가. ⑤ Write-up을 보지 않고 풀었는가 — 봤다면 표시하고 Step 266에서 다시 다룹니다.

연습문제 해답

문제 1 해답. Easy는 취약점 하나가 곧 입구이고 상승도 표준 기법 하나로 끝나지만, Medium은 정보 조각들이 서로의 열쇠가 되는 체인 구조이고, 보이는 길이 함정인 꼬임이 있으며, 입구 자체가 2차 열거(UDP·vhost·큰 워드리스트)에 숨어 있습니다. 즉 어려움의 주체가 "개별 기법의 고난도"가 아니라 "찾아야 할 것의 양과 연결의 수"입니다. 그래서 처방도 더 어려운 기법 학습이 아니라 열거 심화와 가설 운영입니다.

문제 2 해답. 가설 없이 도구부터 돌리면 출력의 바다에서 "무엇을 찾고 있었는지"를 잃습니다 — 스캔은 나오는데 판단이 서지 않고, 같은 시도를 다른 날에 반복하게 됩니다. 가설을 먼저 적으면 그날의 작업이 "참/거짓의 검증"이 되어, 거짓이어도 폐기라는 진척이 남습니다. 며칠짜리 공략에서는 "폐기된 가설의 목록"이 곧 진행도입니다.

문제 3 해답. 기준은 "수집한 정보 중 아직 안 쓴 조각이 있는가"입니다. 있으면 열거 부족이고 처방은 더 깊고 넓은 수집(재스캔, 다른 각도의 열거)입니다. 조각을 다 썼는데 방법이 없으면 기법 부족이고 처방은 리서치(서비스명+버전으로 공략 단계 조사)입니다. 처방이 다른 이유는 병의 위치가 다르기 때문입니다 — 재료가 부족한데 요리법을 공부해도, 요리법이 문제인데 재료를 더 사 와도 해결되지 않습니다.

문제 4 해답. 하루짜리 공략은 맥락이 작업 기억 안에서 유지되지만, 며칠짜리는 잠과 다른 일이 사이에 끼어 기억이 리셋됩니다. 로그가 없으면 다음 날 "어디까지 확인했더라"를 다시 확인하는 재개 비용이 생기고, 사흘 전의 판단 근거를 잊어 같은 가설을 다시 검증하는 낭비가 생깁니다. 로그는 외부 기억 장치입니다 — 며칠짜리 공략에서 로그는 부산물이 아니라 연속성 그 자체입니다.

완료 기준 체크리스트

  • [ ] 선정 근거를 적은 Medium 머신 1대를 정했다
  • [ ] 최소 3일에 걸쳐 진행했고, 매일 "오늘의 가설"과 "내일의 첫 행동"이 로그에 있다
  • [ ] 정찰에 UDP 스캔과 vhost 스캔을 포함했고 출력 파일이 남아 있다
  • [ ] 막힘마다 [열거/기법] 구분과 처방을 기록했다
  • [ ] Write-up 없이 root에 도달했다 (본 경우 표시했고 재공략 계획이 있다)
  • [ ] 회고 네 질문에 답했다
  • [ ] 새로 만난 기법을 플레이북에 추가했다

6. 흔한 실수와 해결

벽 1. "첫날 아무것도 못 찾았다 — 내가 부족한 건가"

증상: Easy 누적 8대의 감각으로 시작했다가, 하루를 통째로 쓰고 진척 없이 끝납니다.
원인: 비교 대상이 잘못됐습니다. Easy의 1시간 루틴은 Medium의 척도가 아닙니다 — 첫날 "입구를 못 찾음"은 Medium의 정상 진행입니다.
해결: 진척의 정의를 바꾸세요. "root에 가까워졌는가"가 아니라 "오늘 폐기된 가설이 몇 개인가"로 셉니다. 폐기 가설 5개는 진척 5개입니다. 사흘은 빠른 편임을 기억하세요.

벽 2. "nmap -p-를 돌렸는데도 입구가 안 보인다"

증상: TCP 풀스캔 결과가 22, 80뿐인데 웹에서는 끝이 안 보입니다.
원인: 열거가 TCP에만 갇혀 있습니다. Medium의 입구는 UDP 서비스, vhost, 더 깊은 경로에 숨는 것이 흔합니다.
해결: 2차 열거 체크리스트를 순서대로 돌리세요 — UDP 상위 포트 스캔(-sU --top-ports 100), vhost 퍼징, 더 큰 워드리스트로 경로 재스캔, JS·소스 정독. "다 했다"는 이 넷이 다 끝난 뒤에만 쓸 수 있는 말입니다.

벽 3. "검색해 봐도 내 머신 얘기가 안 나온다"

증상: 서비스 이름으로 검색해도 해당 머신의 풀이만 나오고 일반론이 없습니다.
원인: 검색어가 머신을 향해 있습니다 — 머신 이름이 검색어에 들어가면 Write-up이 나올 뿐입니다.
해결: 검색어를 "서비스명 + 버전 + pentest" 또는 "프레임워크명 + exploit"처럼 기술을 향하게 바꾸세요. HackTricks에서 서비스명으로 찾는 것이 표준입니다. 열거가 모아 둔 정보(배너, 버전, 페이지 타이틀)가 곧 검색 키워드 목록입니다.

벽 4. "자격증명을 찾았는데 어디에도 안 통해요"

증상: 소스에서 찾은 계정·키를 SSH와 웹 로그인에 넣었지만 전부 실패입니다.
원인: 대입 지점을 다 안 써 봤거나, 자격증명이 "다른 형태"로 쓰이는 경우입니다. API 키는 로그인 폼이 아니라 헤더에 들어가고, 찾은 암호는 다른 사용자 이름과 짝일 수 있습니다.
해결: 자격증명 발견 즉시 "모든 로그인 지점 × 모든 사용자명" 조합 표를 만들어 빠짐없이 대입하세요. 그리고 그 자격증명이 어떤 프로토콜의 것인지(폼 로그인? HTTP Basic? API 헤더? SSH?)를 먼저 묻는 습관을 붙이세요 — 이 감각은 Step 269의 체인 공략에서 완성됩니다.

벽 5. "나흘째인데 손이 안 움직인다"

증상: 로그를 열어도 무엇부터 할지 모르겠고, 머신을 끄고 싶어집니다.
원인: 가설 고갈입니다 — 검증할 가설이 바닥나면 의욕도 바닥납니다. 이것은 실력의 문제가 아니라 가설 생산 루틴의 부재입니다.
해결: "내일의 첫 행동"이 비어 있는 날을 만들지 않은 것이 원인인지 확인하고, 가설 고갈 시의 고정 루틴을 쓰세요 — ① 로그 전체 재독(처음부터), ② 수집 정보 중 미사용 조각 목록화, ③ 각 조각 × 각 공격 표면의 조합 표 작성. 조합 표를 쓰다 보면 안 해 본 칸이 가설이 됩니다. 그래도 안 되면 하루 쉬는 것도 전략입니다 — 단, 로그는 켜 두고 며칠 뒤 신선한 눈으로 읽으세요.


7. 정리

오늘의 개념

개념 한 줄 설명
취약점 체인 정보 조각 A가 문 B의 열쇠가 되는 Medium의 기본 구조
꼬임 보이는 길이 함정이고 진짜 길은 따로 있는 설계
가설-검증 사이클 하루를 "가설 선언 → 검증 → 폐기/진전"으로 운영하는 방식
열거 부족 vs 기법 부족 막힘의 두 원인 — 처방이 각각 재수집과 리서치로 다르다
진척 로그 날짜별 가설·시도·폐기 이유·다음 행동의 외부 기억
리서치 루틴 서비스명+버전으로 공략 ‘단계’를 찾는 검색 습관

오늘의 명령어·도구

명령 하는 일
nmap -sV -p- $TARGET -oN 파일 TCP 풀스캔 + 파일 저장
nmap -sU --top-ports 100 $TARGET UDP 상위 포트 스캔 (Medium 필수 추가)
gobuster vhost -u URL -w 리스트 가상 호스트 퍼징
ffuf -u http://$TARGET -H "Host: FUZZ.target" -w 리스트 vhost 퍼징의 다른 표현
searchsploit "서비스 버전" 공개 익스플로잇 검색
HackTricks 서비스 페이지 서비스별 공략 단계 조회

명령어보다 중요한 감각

Medium이 가르치는 것은 기법이 아니라 시간을 다루는 법입니다. Easy가 한 시간의 질주였다면, Medium은 사흘의 행군입니다 — 하루의 끝에 폐기된 가설 다섯 개가 진척이라는 것, 내일의 나에게 맥락을 넘기는 로그가 연속성이라는 것, 막힘의 대부분이 몰라서가 아니라 안 봐서라는 것.

이 한 대를 혼자 힘으로 뚫었다면, 여러분은 이제 "처음 보는 벽 앞에서도 꺾이지 않는 운영 체계"를 가진 것입니다. 다음 챕터에서는 이 머신을 한 번 더 봅니다 — 풀었으니까, 이제 남들은 어떻게 풀었는지 비교할 자격이 생겼습니다.


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