
재현 가능한 Docker 랩 + CVE-2015-3306(ProFTPD mod_copy 인증 전 임의 파일 복사)용 raw-socket 익스플로잇 — 패치 비교 학습 연습
CVE-2015-3306에 대한 완전히 재현 가능한 실습 환경과 직접 작성한 익스플로잇 — 취약점 연구 학습 목적으로 제작되었습니다: 패치 비교(diffing), 수동 트리거, 그리고 raw 소켓 익스플로잇 개발.
ProFTPD의 mod_copy 모듈은 SITE CPFR / SITE CPTO 명령 쌍을 구현하며,
이 명령은 데이터를 클라이언트로 전송하지 않고 서버 측에서 파일을 복사합니다.
버전 1.3.5에서 두 핸들러 모두 세션이 인증되었는지 확인하지 않았습니다. 모듈은 단순히 *"로그인 전에는 아무도 SITE 명령을 보내지 않을 것"*이라고 가정했습니다 — 이 잘못된 가정이 CVE가 되었습니다. 인증되지 않은 모든 클라이언트가 서버 프로세스가 읽을 수 있는 모든 파일을 서버 프로세스가 쓸 수 있는 모든 위치에 복사할 수 있었습니다.
수정 사항(커밋 212d54271f, 1.3.5a에서 릴리스)은 두 가지를 수행합니다:
copy_cpfr 및 copy_cpto 상단에 인증 게이트를 추가합니다:
authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
if (authenticated == NULL || *authenticated == FALSE) {
pr_response_add_err(R_530, _("Please login with USER and PASS"));
errno = EPERM;
return PR_ERROR(cmd);
}
CopyEngine on|off 지시문을 추가합니다 — 이전에는 모듈이 포함된 빌드에서
비활성화조차 할 수 없었습니다.전체 통합 diff는 patch.diff에 있습니다. 패치를 읽는 것이
핵심 기술입니다: 수정 사항은 취약점이 어디에 있었는지 알려줍니다.
Dockerfile은 공식 소스 tarball에서 mod_copy가 활성화된 ProFTPD 1.3.5
(마지막 취약 버전)를 컴파일합니다:
docker build -t proftpd-135 .
docker run -d --name lab135 -p 127.0.0.1:2121:21 -p 127.0.0.1:30000-30010:30000-30010 proftpd-135
docker exec lab135 chmod 777 /home/ftp
proftpd.conf의 PassivePorts는 데이터 채널을 고정합니다 — FTP의 2채널
아키텍처(제어 + 동적 데이터)는 단순한 컨테이너 매핑이 실패하는 이유입니다:
제어 포트는 작동하지만 데이터 포트는 작동하지 않습니다.
exploit.py는 raw 소켓을 사용합니다 — ftplib는 프로토콜을 숨기기 때문에
사용하지 않습니다. 프로토콜을 숨기는 것이 바로 우리가 싸우고 있는 대상이기 때문입니다:
SITE CPFR /etc/segredo.txt -> 350 (USER/PASS 미전송: 이것이 바로 버그)
SITE CPTO /home/ftp/... -> 250 (임의 복사 수행)
USER ftp / PASS ... -> 230 (로그인은 단지 데이터 유출 경로일 뿐)
PASV / RETR -> 150 -> 226 (플래그 획득)
DELE -> 250 (정리: IOC(침해 지표) 남기지 않음)
AllowOverwrite, 포트 매핑)이 최종 영향을 결정합니다.time.time()이 아닌 time.time_ns()),
그리고 남은 상태에 의존하지 않습니다.RETR은 두 번 응답합니다: 150,
그 다음 226. 다음 명령 전에 둘 다 소진해야 합니다.-d10)는 어떤 검사가 실행되었는지
정확히 알려줍니다.교육 및 승인된 실습 환경 전용입니다. 소유하지 않았거나 서면 승인을 받지 않은 시스템에 대해 이 도구를 실행하는 것은 불법입니다.