
ProFTPD 1.3.9d - 높음 - 원격 - 권한 잔여 / 파일 쓰기 - SITE COPY 대상이 심볼릭 링크를 따름
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-site-copy-dest-follow
분류: 권한 잔여 / 파일 쓰기 도달 범위: 원격
ProFTPD 1.3.9d (f59f248) - proftpd.org
Contrib mod_copy의 SITE COPY는 dest를 dir_canonical_vpath(미해석)로 Limit 검사한다. 이어서 pr_fs_copy_file2가 dest를 O_NOFOLLOW 없이 open하므로 dest 심볼릭 링크가 따라진다. FTP STOR는 해석된 경로(dir_realpath / dir_best_path)로 Limit 검사한다. SITE COPY dest는 그렇지 않다.
인증된 FTP 사용자가 dest 심볼릭 링크를 대상 파일로 향하게 하고 SITE COPY를 실행하여 WRITE가 거부된 파일을 덮어쓴다. 피해자에 대한 직접 STOR와 SITE COPY는 550을 유지한다. 링크에 대한 STOR / SITE RMDIR / RMD도 550을 유지한다. DELE는 링크 노드만 제거한다. 셸은 없다. Unix DAC는 여전히 적용된다.
이것은 공개된 Issue 2095(SITE COPY 소스 READ 건너뛰기)의 반대이다. 공개된 Issue 2256(RNTO EXDEV 심볼릭 링크 따라가기)과는 구별된다. 이 잔여는 EXDEV에만 국한되지 않고 모든 복사에서의 SITE COPY dest이다.
| ID | 아직 CVE 없음 |
| 분류 | 권한 잔여 / 파일 쓰기 |
| 도달 범위 | 원격 (인증된 FTP) |
| CWE | CWE-59, CWE-863 |
| CVSS | 높음: 7.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| 제품 | ProFTPD |
| 영향받음 | 1.3.9d 태그 v1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_copy |
| 인증 | 인증된 FTP (mod_copy 로드됨, CopyEngine 기본 활성). SITE SYMLINK 심기 또한 링크가 이미 존재하지 않는 한 contrib mod_site_misc가 필요하다 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
누가: 인증된 FTP 사용자. mod_copy 로드됨. WRITE가 허용된 디렉터리에 있는 dest 심볼릭 링크(SITE SYMLINK, 또는 기존 링크). SITE SYMLINK src는 dir_check_canon G_READ를 사용하므로, 피해자 파일로 향하는 링크를 심으려면 그 파일에 대한 READ가 필요하다. 분할은 READ 허용, WRITE 거부이다. 세션 UID는 여전히 대상에 대해 Unix 쓰기를 할 수 있어야 한다.
| 방법 | 싱크 | 권한 |
|---|---|---|
| WRITE가 허용된 디렉터리에 있는, 대상이 UID가 Unix 쓰기를 할 수 있는 WRITE 거부 파일인 SITE SYMLINK(또는 기존 링크); 읽기 가능한 src에서 그 링크로 SITE COPY | pr_fsio_open dest 따라감 | 무결성 (랩 입증): 세션 UID로서 Limit 거부 파일을 자르거나 덮어쓴다. 랩: /secret/victim이 ORIGINAL에서 SITE COPY /readable/src.txt /upload/link 후 witness로 바뀌었다. /secret/victim으로의 직접 SITE COPY는 550을 유지했다. |
| 같은 링크에 대한 SITE RMDIR | dir_check_canon -> dir_best_path | 차단됨 (랩 입증): 550 RMDIR /upload/link: Operation not permitted. 피해자 무사. |
| 같은 링크에 대한 코어 RMD | dir_best_path + WRITE | 차단됨 (랩 입증): 550 Permission denied. 피해자 무사. |
| dest 링크에 대한 STOR | dir_best_path + WRITE | 차단됨 (랩 입증): STOR /upload/link -> 550. 피해자 무사. |
| dest 링크에 대한 DELE | 링크 노드 unlink | 피해자에 대해 차단됨 (랩 입증): DELE는 링크만 제거했다; 피해자는 여전히 witness를 보유했다. |
호스트 /etc로의 DefaultRoot jail | chroot | 차단됨. Unix DAC는 여전히 적용된다. 비인증 없음. 셸 없음. |
랩 입증 vs 추론: 미해석 dest 심볼릭 링크를 통한 덮어쓰기, 거부된 STOR/RMDIR/RMD, 링크만 제거하는 DELE는 랩 입증이다. 비인증과 Unix DAC는 인증/chroot 모델에서 추론된 상태로 남는다.
proftpd/proftpd v1.3.9d (f59f248)를 고정했다. 샘플 basic.conf를 사용한 기본 코어 FTP에는 미공개 Crit/High가 없었다. 다음은 contrib mod_copy였다.
copy_copy(contrib/mod_copy.c)는 dest를 dir_canonical_vpath로 만든 다음 그 미해석 문자열에 대해 dir_check(..., G_WRITE, to)를 수행한다. pr_fs_copy_file2(src/fsio.c)는 stat/open이 dest 심볼릭 링크를 따라간다고 주석에 달고, O_NOFOLLOW 없이 pr_fsio_open(dst, O_WRONLY|O_CREAT|O_NONBLOCK)을 수행한다.
공개 Issue 2095는 SITE COPY의 소스 READ 건너뛰기이다. 그 정확한 버그는 건너뛴다. 공개 Issue 2256은 RNTO EXDEV 따라가기이다. 이 잔여는 모든 복사에서의 SITE COPY dest이다.
SITE RMDIR 재귀 따라가기는 부모 드롭이었다: SITE RMDIR는 dir_check_canon / dir_best_path를 사용하며, 이는 Limit 전에 심볼릭 링크를 해석한다. 랩에서 SITE RMDIR과 dest 링크의 코어 RMD가 거부 상태를 유지함을 확인했다.
이미 기록된 잘못된 방향: STOR가 그러하므로 dest Limit을 해석된 것으로 취급하기; Issue 2256을 이 잔여로 취급하기; SITE RMDIR이 피해자를 순회한다고 주장하기. 연극: 리버스 셸. 오라클은 /upload/link를 통한 SITE COPY 후 /secret/victim이 witness를 보유하고, 링크의 STOR는 여전히 550인 것이다.
python3 proftpd-site-copy-dest-follow-Abraxas-Labs.py
또는:
cd lab
./run.sh
루프백 FTP 127.0.0.1:18720, 패시브 18721-18730. Compose 프로젝트 proftpd-site-copy-dest-follow. Witness PROFTPD-SITE-COPY-DEST-FOLLOW-WITNESS. 마지막 줄:
SUCCESS PROFTPD-SITE-COPY-DEST-FOLLOW victim-has-witness=yes stor-secret=denied stor-link=denied site-rmdir-walk=no rmd-walk=no dele-victim=intact PROFTPD-SITE-COPY-DEST-FOLLOW-WITNESS
해석된 dest(dir_realpath / dir_best_path)를 Limit 검사하거나, dest를 O_NOFOLLOW로 열어라. STOR는 이미 해석된 경로를 Limit 검사한다.
벤더 접수는 [email protected]이다. proftpd/proftpd에 공개 GitHub 이슈를 열지 마라.
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_copy.c copy_copysrc/fsio.c pr_fs_copy_file2<Limit READ>GNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.