
vsftpd 3.0.5 - 높음 - 원격 - 권한 잔여 - FTPS 데이터가 재개된 티켓을 모두 수락함
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vsftpd-ssl-data-any-ticket
분류: 권한 잔여 도달 범위: 원격
vsftpd 3.0.5 (Chris Evans) - 공식 tarball SHA-256 26b602ae454b0ba6d99ef44a09b6b9e0dfa7f67228106736df1f278c70bc91d3. 배포판 FTPS는 #define VSF_BUILD_SSL로 컴파일되며(기본 tarball은 #undef), 운영자는 ssl_enable=YES를 설정한다. 독립 실행형 listen=YES는 컴파일 및 샘플 기본값이다.
ssl_accept (ssl.c:494-501)는 데이터 채널 바인드이다. 이는 SSL_session_reused()만 검사한다. 제어 SSL과 비교하는 SSL_SESSION 비교는 없다. 데이터 SSL에는 FTP USER/PASS가 없다. 독립 실행형 ssl_init은 fork 이전에 리스너에서 실행되므로(main.c:147-150), 자식 프로세스는 하나의 SSL_CTX를 상속받는다. SSL_CTX_set_timeout(INT_MAX) (ssl.c:182-186). SSL_OP_NO_TICKET 없음. SSL_session_reused()==1은 이 ClientHello가 이 프로세스가 복호화할 수 있는 티켓을 실어 왔다는 의미일 뿐, 그것이 Alice의 제어 세션임을 의미하지 않는다.
require_ssl_reuse의 man 페이지는 재사용이 제어 채널과 동일한 마스터 시크릿을 증명한다고 말한다. C 코드는 그렇지 않다. 이는 3.0.3 Tim Kosse의 재사용 실패 시 종료(ftpdataio.c:184-187)와 구별되는데, 이는 새로운 핸드셰이크에 여전히 522를 반환하며 Mallory가 다른 제어에서 발급된 티켓을 재개하는 것을 막지 못한다.
이 잔여는 하나의 FTPS 전송이다. USER/PASS 건너뛰기가 아니고, 셸도 아니며, chroot 탈출도 아니다.
| ID | 아직 CVE 없음 |
| 분류 | 권한 잔여 (FTPS 데이터가 임의의 재개된 티켓을 수락) |
| 도달 범위 | 원격 (동일 IP PASV; 공유 NAT는 AC:H) |
| CWE | CWE-345, CWE-287 |
| CVSS | High: 7.4 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
| 제품 | vsftpd (Chris Evans) |
| 영향받음 | 3.0.5 with VSF_BUILD_SSL and ssl_enable=YES. require_ssl_reuse=YES (기본값). require_cert=NO (기본값) |
| 인증 | Mallory: AUTH TLS만 (USER/PASS 없음). Alice: 익명 PBSZ/PROT P |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:18700 제어, PASV 18701-18708. Compose vsftpd-ssl-data-any-ticket |
누가: Alice의 소스 IP를 공유하는 다른 FTPS 클라이언트(또는 경로 상의 공격자). PASV accept는 여전히 제어 피어 IP를 요구한다(privops.c:212-218). pasv_promiscuous가 아닌 한. 공유 NAT는 require_ssl_reuse가 막기 위해 추가된 일반적인 FTPS 사례이다. Mallory는 절대 로그인하지 않는다.
| 방법 + 싱크 | 권한 |
|---|---|
Mallory AUTH TLS만, TLS 1.2 ALPN ftp, 리스너 SSL_CTX의 세션 티켓 유지. Alice 익명 PBSZ/PROT P, PASV, RETR secret.txt가 accept까지 get_remote_transfer_fd에서 차단됨. Mallory 동일 IP PASV, 자신의 티켓 재개 (session_reused=True) | 해당 RETR 하나를 복호화. 랩: 데이터 소켓 35바이트 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS. Alice 150 후 226. 제어 TLS와 비밀번호는 Alice의 것으로 유지됨. 해당 전송 외 디렉터리 탐색 없음. |
ssl_accept 게이트에서 추론; 랩은 RETR 탈취였음)| 방법 + 싱크 | 권한 |
|---|---|
Alice STOR / APPE 중 동일 티켓 재개 | Alice가 지정한 파일이 Mallory의 TLS 평문으로부터, Alice의 uid / 익명 ftp uid로, 기존 chroot 내부에 기록됨 |
| 방법 + 싱크 | 권한 |
|---|---|
새로운 데이터 핸드셰이크 (reused=False) | 522 session reuse required (3.0.3 kill). 해당 전송은 종료됨. 제어는 Alice의 것으로 유지됨 |
privops.c:212-218)require_cert=YES와 제시된 인증서가 SHA-256 다이제스트를 바인딩PROT C (force_local_data_ssl 기본값 YES)ssl_init 상속 없음)ftp 이외의 ALPN (vsftpd FATAL 발생)GitHub 미러나 Debian/Fedora 트리가 아닌 공식 vsftpd 3.0.5 tarball을 고정했다. 열아홉 번의 소스 탐색. SSL 탐색은 ssl_accept에서 멈췄다: 재사용은 불리언이지, 이 제어 SSL_SESSION에 대한 바인드가 아니다. 리스너 SSL_CTX와 INT_MAX 티켓 수명이 나머지이다.
잘못된 방향: ALPN은 ftp여야 하며 그렇지 않으면 vsftpd가 FATAL을 낸다 (3.0.4 ALPACA 잔여는 이미 닫혀 있음). Arm64 링크에는 명시적 -lpam -lcap이 필요했다; 기본 vsf_findlibs.sh는 x86_64 경로만 탐색한다. 3.0.3 Tim Kosse kill을 이 버그로 착각하기: 이는 Alice의 데이터 fd에 대한 새로운 핸드셰이크에 522를 반환하며 다른 제어에서 발급된 티켓을 막지 못한다.
cd lab
./run.sh
공식 3.0.5 with #define VSF_BUILD_SSL. 설정: ssl_enable=YES, allow_anon_ssl=YES, force_anon_logins_ssl=YES, force_anon_data_ssl=YES, require_ssl_reuse=YES, require_cert=NO. 루프백 Docker. 동일 IP 클라이언트 두 개. TLS 1.2 티켓. ALPN ftp. 제어 127.0.0.1:18700, PASV 18701-18708. Compose vsftpd-ssl-data-any-ticket. Witness VSFTPD-SSL-DATA-ANY-TICKET-WITNESS. 마지막 줄:
SUCCESS vsftpd-ssl-data-any-ticket reused-ticket=yes fresh-handshake=522 VSFTPD-SSL-DATA-ANY-TICKET-WITNESS
데이터 SSL_SESSION을 제어 SSL_SESSION에 바인딩하라 (세션 ID / 마스터 시크릿 비교). 티켓 수명을 제어 연결로 제한하라. 또는 SSL_OP_NO_TICKET과 제어로 키가 지정된 세션 캐시를 사용하라. ProFTPD 1.3.9d는 세션을 비교한다.
벤더 접수는 [email protected] (security.appspot.com/vsftpd.html). 어떤 vsftpd 미러에도 공개 GitHub 이슈를 열지 말 것.
Abraxas Labs - abraxaslabs.tech - github.com/abraxas - @abraxas_null - [email protected]