Step 343. 종합 침투 시나리오 — 전체 역량의 운용: 기술의 나열에서 작전으로

Step 343. 종합 침투 시나리오 — 전체 역량의 운용: 기술의 나열에서 작전으로

Level 4 — 전문가 | 난이도 ★★★★★ | 예상 소요 시간 2일 (시나리오 설계 반나절 + 실행 8시간 + 보고서 반나절)

전제: Step 272의 침투 플레이북 v1.0, Step 264의 크리덴셜 표와 네트워크 지도, Step 278의 실전 점검 경험. 이 챕터의 랩 구성 스크립트와 침투 출력은 이 책의 랩(WSL, Ubuntu 24.04, Nmap 7.94, 파이썬 3.12)에서 실측한 것입니다.

  • 준비물: 로컬 랩(WSL 또는 가상 머신 묶음), Step 272의 플레이북, 타임라인 기록용 노트, 타이머. 이 챕터는 "1인 레드팀 — 로컬 랩 전체 침투 시나리오"입니다.
  • 주의: 이 챕터의 실측은 127.0.0.1 위의 축소 시나리오(웹 서버 1대 + 내부 API 1대)로 검증했습니다. 여러분의 랩에 웹 서버·워크스테이션·도메인이 연결돼 있다면 같은 절차를 전체 랩으로 확장하세요 — 절차와 기록 방식은 동일합니다.
  • ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 오늘의 모든 대상은 여러분이 직접 띄운 로컬 랩입니다.

실제 침투 테스트는 "취약점 찾기"가 아니라 "목표 달성 시나리오"입니다. 고객의 발주 문서는 이렇게 쓰입니다 — "외부에서 시작해 내부 문서 서버의 기밀 파일을 탈취하라." 개별 기술의 시험이 아니라, 정찰·웹 공격·초기 침투·권한 상승·내부 이동·증거 수집·보고서까지 전부를 하나의 작전으로 엮는 일.

지금까지 배운 모든 것이 오늘 하나의 체인으로 합쳐집니다. 개별 기술이 "작전"으로 변하는 경험 — 그것이 전문가의 마지막 퍼즐입니다. 오늘은 로컬 랩을 대상으로 그 작전을 설계하고, 실행하고, 산출물까지 완성합니다.


1. 학습 목표

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

  • 목표·시작점·규칙의 세 요소로 침투 시나리오를 정의한다
  • 예상 경로와 단계별 후보 기법을 담은 작전 계획을 세운다
  • 계획이 틀어질 때 현장에서 수정하며 전 과정을 타임라인으로 기록한다
  • 크리덴셜 표와 자산 지도로 "체인"을 만들어 목표까지 도달한다
  • 침투 경로 요약·단계별 근거·타임라인·개선 권고의 종합 보고서를 쓴다

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

오늘의 도구 한눈에 보기

구분 내용
언어·환경 리눅스 셸(WSL), 파이썬 3(랩 구성), nmap, curl, 타임라인 노트
오늘의 명령 nmap -sV 대상 -p 범위 · curl -si URL · curl -u 사용자:비밀번호 URL
필요한 개념 시나리오 기반 침투, 작전 계획, 크리덴셜 재사용, 자산 지도, 타임라인 기록
오늘의 산출물 시나리오 정의서 + 작전 계획 + 실행 타임라인 + 종합 보고서 1부

2-1. 시나리오 기반 침투 — 발주서가 시험지다

머신 풀이와 실제 침투 테스트의 차이는 "목표의 형태"에 있습니다. 머신의 목표는 user.txtroot.txt라는 정해진 정답이지만, 실제 작전의 목표는 발주 문서의 한 문장입니다 — "기밀 파일의 탈취 가능성을 입증하라", "도메인 관리자 권한의 획득 경로를 보여라".

이 차이가 모든 것을 바꿉니다. 정답이 없으니 "풀었다"의 판정은 내가 하고, 입증의 형태(증거·경로·보고서)까지 산출물입니다. 그래서 오늘의 첫 작업은 공격이 아니라 시나리오 정의입니다 — 목표, 시작점, 규칙의 세 요소를 문서로 고정하는 것.

2-2. 오늘의 시나리오 — lab-corp 축소 판

이 챕터에서 실측으로 실행할 시나리오입니다. 여러분의 랩이 더 크다면 이 골격을 그대로 확장하면 됩니다.

시나리오 정의서 (이 챕터의 실측용):
- 배경: 가상 기업 lab-corp. 외부에 공개 웹 서버 1대, 내부에 API 서버 1대
- 목표: 내부 API 서버의 /flag.txt 획득 (기밀 파일 탈취의 입증)
- 시작점: 외부 — 공개 웹 서버의 주소만 알고 있다
- 규칙: 시간 제한 없음 (재현 훈련), 대상은 127.0.0.1 위의 랩뿐
- 판정: 플래그 내용을 화면에 출력하고, 경로 전체를 타임라인으로 재현 가능해야 함

전체 랩으로 확장할 때의 시나리오 예시는 이렇습니다 — "외부 공개 웹 서버만 알고 시작해, 도메인 컨트롤러의 특정 파일을 획득하라. 시간 제한 8시간." 목표가 깊어질 뿐, 정의서의 형식은 같습니다.

2-3. 체인의 사고방식 — 개별 머신이 아니라 연결을 푼다

실무자들이 가장 많이 막히는 지점이 이 챕터의 핵심 주제입니다 — "개별 머신은 풀었는데 연결이 안 됩니다." 체인을 만드는 것은 기술이 아니라 두 장의 지도입니다.

크리덴셜 표 (Step 264) — 공략 중 발견한 모든 자격증명(아이디·비밀번호·키·토큰)을 발견 즉시 표에 추가합니다. 열은 "자격증명 / 발견 위치 / 어디에 써 봤나". ② 자산 지도 — 발견한 호스트·서비스·문서 경로를 그래프로 잇습니다. 체인이란 이 두 지도 위에서 "아직 안 써 본 자격증명 × 아직 안 가 본 자산"의 곱을 하나씩 시험하는 것입니다. 막힘은 기술의 고갈이 아니라 지도의 미갱신에서 옵니다.

2-4. 타임라인 기록 — 작전의 블랙박스

시나리오 실행 중의 기록 양식은 네 열입니다 — 시각 / 행동 / 결과 / 얻은 정보.

타임라인 양식 (화면 예시):
| 시각 | 행동 | 결과 | 얻은 정보 |
| 13:00 | nmap 전체 포트 스캔 | 8080, 9000 오픈 | 내부 서비스 존재 추정 |

이 기록이 세 가지가 됩니다 — 실행 중에는 "내가 지금 어디까지 왔나"의 위치 감각, 막혔을 때 되돌아갈 분기점 목록, 종료 후에는 보고서의 뼈대. 8시간짜리 작전에서 기억은 1시간이면 흐려집니다. 기록이 곧 입증입니다.


3. 따라 하기

3-1. 대상 랩 구성 — 실측

축소 랩을 직접 만듭니다. 공개 웹 서버(8080)와 내부 API(9000, Basic 인증) 두 대이고, 연결 고리는 "웹 서버에 실수로 남은 설정 백업"입니다. ~/lab343/에 파일을 만드세요.

공개 웹 서버의 문서들입니다. ~/lab343/web/index.html:

<!DOCTYPE html>
<html>
<head><title>lab-corp 공개 서버</title></head>
<body>
<h1>lab-corp에 오신 것을 환영합니다</h1>
<p>이 사이트는 로컬 랩 훈련용 더미 서비스입니다.</p>
<!-- TODO(dev): 배포 전에 /backup/ 정리할 것. 구성 백업이 아직 올라가 있음 -->
</body>
</html>

~/lab343/web/robots.txt:

User-agent: *
Disallow: /backup/

~/lab343/web/backup/config.bak:

# lab-corp deploy config (OLD - rotate me)
internal_api_url=http://127.0.0.1:9000/
internal_api_user=deploy
internal_api_pass=Sp-ring2026!

내부 API 서버 ~/lab343/internal_server.py와 목표 파일 ~/lab343/internal/flag.txt:

# internal_server.py — Basic 인증이 걸린 내부 API (랩용)
from http.server import BaseHTTPRequestHandler, HTTPServer
import base64, os

USER, PW = "deploy", "Sp-ring2026!"

class H(BaseHTTPRequestHandler):
    def do_GET(self):
        auth = self.headers.get("Authorization", "")
        ok = auth == "Basic " + base64.b64encode(f"{USER}:{PW}".encode()).decode()
        if not ok:
            self.send_response(401)
            self.send_header("WWW-Authenticate", "Basic realm="lab-internal"")
            self.end_headers()
            self.wfile.write(b"401 Unauthorizedn")
            return
        if self.path == "/flag.txt":
            body = open(os.path.expanduser("~/lab343/internal/flag.txt"), "rb").read()
            self.send_response(200); self.end_headers(); self.wfile.write(body)
        else:
            self.send_response(200); self.end_headers()
            self.wfile.write(b"lab-corp internal api v0.3 - endpoints: /flag.txtn")
    def log_message(self, *a):
        pass

HTTPServer(("127.0.0.1", 9000), H).serve_forever()

flag.txt의 내용은 flag{ch4in_0f_c0nfi6_l3ak}로 저장하고, 두 서버를 띄웁니다 (훈련이 끝나면 timeout으로 자동 종료되게 합니다):

timeout 300 python3 -m http.server 8080 --bind 127.0.0.1 -d ~/lab343/web &
timeout 300 python3 ~/lab343/internal_server.py &
sleep 1

3-2. 작전 계획 — 실행 전에 경로를 그린다

서버를 띄우기 전에(여러분의 랩에서는 스캔 전에) 작전 계획을 세웁니다. 계획은 예측이 아니라 분기표입니다.

작전 계획 (화면 예시):
예상 경로: 정찰(포트 스캔) → 공개 웹 열거 → 설정/백업 노출 확인
         → 크리덴셜 획득 → 내부 자산에 재사용 → 목표 파일 획득
단계별 후보 기법:
  정찰    : nmap -sV 전체 포트
  웹 열거 : index 원문 읽기(주석 포함), robots.txt, 흔한 경로
  인증 우회: 발견 크리덴셜의 재사용 (재사용이 체인의 기본 가정)
막힘 분기: 웹에서 아무것도 없으면 → 전체 포트 재스캔 + UDP 상위
         → 플레이북(Step 272) 08 막힘 대처 트리로

3-3. 실행 1 — 정찰 (실측)

타이머를 켜고 작전을 시작합니다. 첫 명령은 플레이북의 정찰 카드 그대로입니다.

nmap -sV 127.0.0.1 -p 1-10000

실측 출력입니다:

Not shown: 9998 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
8080/tcp open  http    SimpleHTTPServer 0.6 (Python 3.12.3)
9000/tcp open  http    BaseHTTPServer 0.6 (Python 3.12.3)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.27 seconds

읽는 법: 두 개의 HTTP 서비스가 보입니다. 8080은 공개 웹 서버(시작점)이고, 9000은 문서에 없는 두 번째 서비스 — "공개된 것 말고 또 무엇이 있는가"가 정찰의 유일한 질문입니다. 이 한 줄을 타임라인의 첫 행으로 기록합니다: 13:00 | nmap -sV 전체 포트 | 8080, 9000 오픈 | 내부 서비스 존재.

3-4. 실행 2 — 웹 열거와 단서 발견 (실측)

공개 웹 서버를 읽습니다. 침투자의 "읽기"는 화면을 보는 것이 아니라 원문을 보는 것입니다.

curl -s http://127.0.0.1:8080/
curl -s http://127.0.0.1:8080/robots.txt
curl -s http://127.0.0.1:8080/backup/config.bak

실측 출력입니다:

<!DOCTYPE html>
<html>
<head><title>lab-corp 공개 서버</title></head>
<body>
<h1>lab-corp에 오신 것을 환영합니다</h1>
<p>이 사이트는 로컬 랩 훈련용 더미 서비스입니다.</p>
<!-- TODO(dev): 배포 전에 /backup/ 정리할 것. 구성 백업이 아직 올라가 있음 -->
</body>
</html>

User-agent: *
Disallow: /backup/

# lab-corp deploy config (OLD - rotate me)
internal_api_url=http://127.0.0.1:9000/
internal_api_user=deploy
internal_api_pass=Sp-ring2026!

읽는 법: 세 개의 단서가 하나의 사슬로 이어졌습니다. ① HTML 주석의 개발자 메모가 /backup/의 존재를 알리고, ② robots.txt가 같은 경로를 확인하며(검색엔진에 숨기려다 공격자에게 알려 주는 고전적 실수), ③ config.bak이 내부 API의 주소와 자격증명을 통째로 줍니다. 타임라인에 기록하고, 크리덴셜 표에 즉시 추가합니다 — deploy / Sp-ring2026! / 발견: config.bak / 시도: 아직.

3-5. 실행 3 — 크리덴셜 재사용과 목표 획득 (실측)

먼저 무인증으로 내부 API를 두드려 보고(기록용), 발견한 자격증명으로 다시 갑니다.

curl -si http://127.0.0.1:9000/ | head -8
curl -s -u deploy:Sp-ring2026! http://127.0.0.1:9000/
curl -s -u deploy:Sp-ring2026! http://127.0.0.1:9000/flag.txt

실측 출력입니다:

HTTP/1.0 401 Unauthorized
Server: BaseHTTP/0.6 Python/3.12.3
WWW-Authenticate: Basic realm="lab-internal"

401 Unauthorized

lab-corp internal api v0.3 - endpoints: /flag.txt

flag{ch4in_0f_c0nfi6_l3ak}

읽는 법: 무인증 요청의 401은 "이 문은 자격증명으로 열린다"는 정보이고, WWW-Authenticate: Basic 헤더가 어떤 자격증명인지를 알려 줍니다. 그리고 두 단계 뒤 — 크리덴셜 표의 한 행이 플래그가 됩니다. 이것이 체인입니다: 정찰이 자산을, 열거가 자격증명을, 재사용이 목표를 열었습니다. 어느 한 단계도 "취약점 공격"이 아니지만, 연결된 전체는 완전한 침투입니다.

3-6. 종합 보고서 — 산출물의 형태

작전 종료 후 보고서를 작성합니다. 실제 모의해킹 산출물의 형태 그대로입니다.

종합 보고서 뼈대 (화면 예시 — 이 챕터 실측 기반):
1. 개요 — 시나리오 목표, 범위, 기간, 결과 한 줄
2. 침투 경로 요약 — 한 문단: "공개 웹의 설정 백업 노출로 내부 API 자격증명을
   획득, 재사용으로 기밀 파일 탈취에 성공"
3. 단계별 상세 — 각 단계: 근거(명령+출력), 획득 정보, 다음 단계로의 연결
4. 타임라인 — 2-4 양식의 기록 전체
5. 개선 권고 — 설정 백업의 웹 루트 제거, 자격증명 로테이션, robots.txt의
   경로 노출 검토, 내부 API의 네트워크 분리
6. 부록 — 사용한 명령 전체, 랩 구성 파일 목록

5번의 개선 권고를 가볍게 여기지 마세요 — 고객이 돈을 내는 것은 침투가 아니라 권고입니다. 침투는 권고의 근거를 만드는 과정이고, 그래서 모든 권고는 3번의 단계와 1:1로 연결되어야 합니다. 권고가 침투 없이도 쓸 수 있는 일반론("최신 패치 적용")이면, 그 보고서는 실패입니다.


4. 미션과 연습문제

미션 — 시나리오 완수와 종합 보고서

  1. 2-2의 양식으로 여러분의 랩에 맞는 시나리오 정의서를 씁니다 — 목표·시작점·규칙·판정의 네 항목 필수.
  2. 3-1을 참고해 축소 랩(또는 기존 전체 랩)을 점검·구성합니다.
  3. 3-2 양식의 작전 계획을 세우고, 막힘 분기까지 적습니다.
  4. 타이머를 켜고 실행합니다 — 전 과정을 타임라인(시각/행동/결과/얻은 정보)으로 기록하고, 크리덴셜 표와 자산 지도를 실시간으로 갱신합니다.
  5. 3-6의 뼈대로 종합 보고서 1부를 완성합니다 — 개선 권고가 침투 단계와 1:1로 연결되어야 합니다.

연습문제

문제 1. 머신 풀이와 시나리오 기반 침투의 차이를 "목표의 형태"로 설명하고, 이 차이가 "풀었다"의 판정과 산출물에 어떤 영향을 주는지 설명해 보세요.

문제 2. "개별 머신은 푸는데 연결이 안 되는" 상황의 원인을 크리덴셜 표와 자산 지도의 관점에서 설명하고, 체인을 만드는 절차를 한 문장으로 정리해 보세요.

문제 3. 3-4에서 robots.txt가 공격자에게 단서가 되는 원리를 설명하고, 방어자의 올바른 태도는 무엇인지 답해 보세요.

문제 4. 보고서의 개선 권고가 침투 단계와 1:1로 연결되어야 하는 이유를, "고객이 돈을 내는 대상"의 관점에서 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

검증 기준으로 확인하세요.

  1. 정의서의 완결: 목표·시작점·규칙·판정 네 항목이 있고, 판정이 검증 가능한 형태인가("해킹한다"가 아니라 "플래그 출력 + 타임라인 재현").
  2. 계획의 분기: 예상 경로뿐 아니라 막힘 분기가 적혔는가 — 계획이 "틀렸을 때"의 행동이 문서에 있는가.
  3. 타임라인의 연속성: 실행 기록에 공백이 없고, 각 행이 "얻은 정보"를 다음 행의 근거로 연결하는가.
  4. 지도의 실시간성: 크리덴셜 표가 발견 순간에 갱신된 흔적(시각)이 있는가.
  5. 권고의 1:1 연결: 보고서의 모든 개선 권고가 구체적 침투 단계를 근거로 가리키는가.

연습문제 해답

문제 1 해답. 머신의 목표는 정해진 정답 파일(user.txt, root.txt)이라 "풀었다"의 판정이 플랫폼에 있지만, 시나리오의 목표는 발주 문서의 한 문장("기밀 파일의 탈취 가능성을 입증하라")이라 판정이 수행자에게 있습니다. 이 차이의 영향은 두 가지입니다. 첫째, 완료의 정의를 스스로 문서화해야 합니다 — 무엇을 "달성"으로 볼지 시나리오 정의서의 판정 항목으로 사전에 고정하지 않으면 작전이 끝나지 않습니다. 둘째, 산출물이 증거와 경로를 포함해야 합니다 — 정답 파일은 그 자체가 증거이지만, "탈취 가능성"은 타임라인·명령 출력·화면의 축적으로만 입증됩니다. 그래서 시나리오 기반 침투에서는 기록이 부산물이 아니라 본산물입니다.

문제 2 해답. 연결이 안 되는 원인은 대부분 기술의 고갈이 아니라 정보의 방치입니다 — 공략 중에 발견한 자격증명과 자산을 즉시 지도에 올리지 않으면, "어디선가 본 비밀번호"가 뇌에서 증발하고 체인의 고리가 끊깁니다. 체인을 만드는 절차는 한 문장으로 이렇습니다 — 아직 안 써 본 자격증명 × 아직 안 가 본 자산의 곱을 하나씩 시험하라. 이 곱셈이 가능하려면 두 지도가 실시간으로 갱신되어야 하고, 그래서 크리덴셜 표의 "어디에 써 봤나" 열이 핵심입니다 — 체인이란 결국 시험하지 않은 조합의 목록을 소진하는 작업입니다.

문제 3 해답. robots.txt는 검색엔진에게 "이 경로를 색인하지 말라"는 요청인데, 그 문법이 경로의 존재 자체를 알려 줍니다 — "숨기고 싶은 것의 목록"을 공개 파일에 적는 셈입니다. 공격자의 디렉터리 열거에서 robots.txt는 항상 첫 확인 대상이고, 실측에서도 Disallow: /backup/이 침투 경로의 두 번째 고리였습니다. 방어자의 올바른 태도는 두 가지입니다. ① robots.txt를 비밀 보호 장치로 오해하지 않는다 — 민감 경로는 인증과 접근 제어로 지키고, robots.txt는 색인 제어로만 쓴다. ② 웹 루트에 설정 백업을 두지 않는다 — 숨길 것이 없으면 robots.txt가 알려 줄 것도 없습니다.

문제 4 해답. 고객이 지불하는 대상은 침투의 성공이 아니라 "무엇을 고치면 되는가"의 답입니다 — 침투는 그 답의 근거를 만드는 과정입니다. 권고가 침투 단계와 1:1로 연결되면 각 권고는 "실제로 뚫린 경로"를 닫는 구체적 조치가 됩니다 — "config.bak을 웹 루트에서 제거하라"는 이번 작전에서 실제로 사용된 고리를 끊습니다. 반대로 일반론 권고("패치를 최신으로")는 침투 없이도 쓸 수 있는 문장이라, 고객은 그 보고서에 침투 비용을 지불할 이유를 찾지 못합니다. 그리고 1:1 연결은 방어 검증도 가능하게 합니다 — 조치 후 같은 체인을 재시도해 막히는 것을 보여 주는 것이 권고 이행의 입증이 되니까요.

완료 기준 체크리스트

  • [ ] 시나리오 정의서(목표·시작점·규칙·판정)를 작성했다
  • [ ] 축소 랩 또는 전체 랩을 구성·점검했다
  • [ ] 작전 계획에 막힘 분기까지 적었다
  • [ ] 실행 전 과정을 타임라인으로 기록했다
  • [ ] 크리덴셜 표와 자산 지도를 실시간 갱신했다
  • [ ] 목표물(플래그)을 획득하고 출력을 증거로 남겼다
  • [ ] 종합 보고서 1부를 완성했고 권고가 단계와 1:1로 연결된다

6. 흔한 실수와 해결

벽 1. 서버를 띄웠는데 curl이 연결을 거부해요

증상: 이런 메시지가 뜹니다.

curl: (7) Failed to connect to 127.0.0.1 port 9000: Connection refused

원인: 세 가지를 순서대로 의심하세요. ① 서버 프로세스가 안 떴거나 죽었거나 — timeout 시간이 지났거나, ② 다른 포트에 떴거나, ③ 이전 실행의 서버가 포트를 잡고 새 서버가 Address already in use로 실패했거나.

해결: ss -tln | grep -E '8080|9000'으로 리스닝 포트를 확인하세요. 이전 서버가 남아 있으면 종료 후 다시 띄웁니다. 서버를 백그라운드로 띄운 직후에는 sleep 1을 넣어 기동을 기다리세요 — 이 챕터의 실측 중에도 포트 충돌로 한 번 실패한 뒤 재기동으로 해결한 바 있습니다. 랩 장애도 타임라인에 기록하세요 — "환경 문제 10분"도 작전의 일부입니다.

벽 2. flag.txt 요청이 200인데 내용이 비어 있어요

증상: 인증까지 됐는데 응답 본문이 빈 채로 옵니다.

원인: 서버 스크립트가 읽는 플래그 경로가 실제 파일 위치와 다른 경우입니다 — 특히 홈 디렉터리 전개(~)가 실행 사용자에 따라 달라지면서 생깁니다 (이 챕터의 랩을 만드는 과정에서 실제로 발생했습니다 — /root/...~/...의 불일치).

해결: 서버 로그(표준 에러)를 확인하고, 스크립트의 경로를 os.path.expanduser("~/lab343/internal/flag.txt")처럼 실행 환경에 맞게 고정하세요. 교훈은 하나입니다 — 공격 명령을 의심하기 전에 랩의 정상 동작을 먼저 확인하세요. 시나리오 훈련에서 "안 되는 것"의 절반은 공격 실패가 아니라 랩 오설정입니다.

벽 3. nmap이 포트를 안 보여 줘요 — 서버는 분명 떠 있는데

증상: nmap -sV 127.0.0.1 (포트 지정 없음)에서 9000이 안 나옵니다.

원인: nmap의 기본 스캔은 "흔한 1000 포트"만 봅니다 — 9000번은 기본 범위에 없습니다.

해결: 플레이북의 규칙대로 2차 스캔은 전체 포트입니다 — 이 챕터는 -p 1-10000을 썼고, 실전 랩에서는 -p-(전체 65535)를 씁니다. "기본 스캔에 안 나온다 = 없다"가 아니라 "아직 안 봤다"입니다. 이 한 끗이 머신 풀이에서는 습관이었고, 시나리오에서는 시나리오의 성패를 가릅니다 — 내부 서비스는 언제나 비표준 포트를 좋아하니까요.

벽 4. 실행 중에 계획이 틀어졌어요 — 예상 경로가 안 통합니다

증상: 작전 계획의 2단계에서 아무 단서도 안 나옵니다.

원인: 계획은 예측이 아니라 분기표입니다 — 틀어지는 것이 정상이고, 그래서 막힘 분기를 미리 적어 두었습니다.

해결: 감정 개입 없이 분기표의 다음 행으로 갑니다 — 전체 포트 재스캔, UDP 상위, 플레이북 08 막힘 대처 트리. 그리고 중요한 규칙 — 계획을 현장에서 수정할 때도 수정 사실을 타임라인에 기록합니다: 13:40 | 계획 수정: 웹 경로 열거 포기 -> 전체 포트 재스캔 | 사유: 단서 부재. 이 기록이 있어야 보고서가 "계획대로 된 척"하는 거짓 문서가 되지 않습니다. 실제 작전의 보고서는 계획과 실행의 차이까지 포함하는 것이 정직한 형태입니다.

벽 5. 플래그는 얻었는데 보고서가 "일기"처럼 쓰여요

증상: "~했다, 그래서 ~했다"의 시간순 나열만 있는 보고서가 나왔습니다.

원인: 타임라인을 보고서로 착각한 것입니다 — 타임라인은 재료이고, 보고서는 독자(고객)의 질문 순서로 재구성한 문서입니다.

해결: 3-6의 뼈대 순서를 지키세요 — 개요(결과 한 줄)가 먼저, 경로 요약이 그다음, 타임라인은 4번의 근거 자료입니다. 독자의 첫 질문은 "그래서 뚫렸나?"이고 두 번째는 "어떻게?"이며, 세 번째는 "뭘 고치면 되나?"입니다. 시간순 나열은 이 질문 순서를 무시합니다. 쓰고 나서 확인하세요 — 첫 페이지만 읽은 임원이 결과와 권고를 알 수 있는가. 그것이 보고서의 합격선입니다.


7. 정리

오늘의 개념

개념 한 줄 설명
시나리오 기반 침투 목표는 발주 문서의 한 문장 — 판정과 입증이 수행자의 몫
시나리오 정의서 목표·시작점·규칙·판정의 네 항목으로 작전을 고정
작전 계획 예상 경로 + 막힘 분기 — 틀어지는 것을 전제로 설계
크리덴셜 표 발견 즉시 기록 — "어디에 써 봤나" 열이 체인을 만든다
자산 지도 호스트·서비스·문서 경로의 그래프 — 안 가 본 곳이 다음 목표
타임라인 기록 시각/행동/결과/얻은 정보 — 작전의 블랙박스이자 보고서의 뼈대
1:1 권고 모든 개선 권고는 실제 침투 단계를 근거로 — 고객이 사는 것은 권고

오늘의 도구·명령어

도구·명령 하는 일
nmap -sV 대상 -p 범위 정찰 — 기본 1000 포트 밖의 서비스까지 본다
curl -s URL 웹 원문 읽기 — 주석·robots·백업의 세 단서
curl -si URL 응답 헤더 확인 — 401과 WWW-Authenticate가 힌트
curl -u 사용자:비밀번호 URL 크리덴셜 재사용 — 체인의 연결 고리
ss -tln 랩 서비스의 리스닝 확인 — 랩 장애의 1차 진단
타임라인 양식 시각/행동/결과/얻은 정보의 4열 기록

명령어보다 중요한 감각

오늘의 시나리오에서 사용된 기술은 전부 이 책의 앞부분에서 배운 것들입니다 — 포트 스캔, 원문 읽기, 헤더 확인, 자격증명 재사용. 새로운 기술은 하나도 없었습니다. 그런데 이 단순한 기술들이 "목표 → 계획 → 기록 → 보고"의 틀 안에서 움직이자, 그것은 더 이상 연습 문제가 아니라 작전이었습니다.

개별 기술이 작전으로 변하는 지점은 기술의 깊이가 아니라 운용의 구조에서 옵니다. 시나리오가 목표를 정하고, 지도가 체인을 만들고, 타임라인이 판단을 보존하고, 보고서가 가치로 바꿉니다. 여러분은 오늘 이 네 개의 틀을 손에 넣었습니다 — 남은 것은 이 틀을 더 큰 랩과 더 긴 작전에 반복해 입히는 일이고, 그 반복이 곧 전문가의 일상입니다.


전부 체크되면 Step 343 완료입니다.