
ProFTPD 1.3.9d - 높음 - 원격 - 크래시 - RewriteMap int:utf8trans BSS 오버플로
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · proftpd-rewrite-utf8trans
분석 문서: https://abraxaslabs.tech/research/proftpd-rewrite-utf8trans
분류: 크래시 도달 범위: 원격
ProFTPD 1.3.9d (f59f248) - ProFTPD (proftpd.org)
contrib mod_rewrite는 RewriteMap int:utf8trans를 제공합니다. 이 내장 기능은 클라이언트 FTP 인자(최대 CommandBufferSize, 512 KiB)를 목적지 크기 제한 없이 1024 슬롯짜리 BSS 버퍼 두 개에 복사합니다. 긴 ASCII STOR 이름은 크기 8의 ASan global-buffer-overflow WRITE를 일으킵니다. 세션 자식 프로세스가 중단됩니다. 데몬은 계속 실행됩니다. 분류는 크래시입니다. RCE는 아닙니다.
| ID | 아직 CVE 없음 |
| 분류 | 크래시 |
| 도달 범위 | 원격 (int:utf8trans에 전달되는 FTP 인자) |
| CWE | CWE-120 |
| CVSS | 높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (RewriteRule이 인증 전일 경우). 실험실에서는 로그인 후 STOR를 사용했으므로 해당 실행에서는 PR:L이 정직한 값입니다 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H). |
| 제품 | ProFTPD |
| 영향받는 버전 | 1.3.9d (f59f248e26bdfa514443e42bf72a145641df635d) contrib mod_rewrite |
| 인증 | 실험실은 인증된 STOR입니다. USER 등에 대한 인증 전 RewriteRule이라면 PR:N이 됩니다. |
| 라이선스 | GNU Affero GPL v3.0 |
| 실험실 | 127.0.0.1 전용 |
RewriteEngine은 구성하기 전까지 꺼져 있습니다. 문서화된 패턴은 RewriteRule (.*) ${map:$1}입니다. RewriteRule이 클라이언트 인자를 int:utf8trans를 통해 전달하면, 1024바이트보다 긴 키가 세션 자식 프로세스의 정적 버퍼 두 개를 오버플로합니다.
| 방법 | 싱크 | 권한 |
|---|---|---|
| 인자가 utf8trans 맵 키이고 길이가 1024를 초과하는 FTP 명령 | rewrite_utf8_to_ucs4 다음 utf8_val[i] = ucs4_longs[i] | 가용성 (실험실 입증): 세션 자식 프로세스 크래시. ASan: global-buffer-overflow WRITE of size 8, 이어서 ABORTING. Prefork: 새 로그인은 여전히 작동했고 데몬은 계속 실행됨. 200 ASCII 바이트의 짧은 STOR는 견뎠음. 인접한 rewrite BSS 무결성은 추론된 것이며 컴파일러 레이아웃에 의존함. |
| RIP / 코드 실행 | 주장 없음 | 종결. 페이로드 없음. 분류는 크래시. RCE 아님. |
.ftpaccess에 RewriteMap 심기 | CONF_DYNDIR | 종결. RewriteMap은 .ftpaccess에서 허용되지 않음. |
prg: 셸 | 해당 맵 유형 없음 | 종결. FIFO는 라인 I/O임. |
실험실 입증 vs 추론: 크기 8의 ASan WRITE, 세션 자식 프로세스 중단, 짧은 인자 대조군의 생존, 트리거 후 로그인은 실험실에서 입증되었습니다. RIP/RCE는 주장되지 않습니다.
이슈 2173은 이 핀에서 int:unescape의 1바이트 OOB를 패치했습니다. 이번 잔여 문제는 int:utf8trans입니다. 다른 내장 기능. 다른 버그.
저는 proftpd/proftpd 태그 v1.3.9d를 고정했습니다. 2026년 CVE 무리와 해당 tarball에 여전히 남아 있는 공개 GitHub 이슈들(2170, 2173, 2175, 2180, 2095, 2256, 2286, 2319, 2330, 2301)은 건너뛸 목록이었습니다. 샘플 basic.conf를 사용한 기본 코어 FTP로는 미공개 Crit/High를 얻지 못했습니다. contrib rewrite가 그것을 제공했습니다.
rewrite_map_int_utf8trans (contrib/mod_rewrite.c)에는 다음이 있습니다:
static unsigned char utf8_val[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
static unsigned long ucs4_longs[PR_TUNABLE_BUFFER_SIZE]; /* 1024 */
ucs4strlen = rewrite_utf8_to_ucs4(ucs4_longs, strlen(key), (unsigned char *) key);
rewrite_utf8_to_ucs4는 ASCII 바이트당 하나의 unsigned long을 상한 없이 기록합니다. PR_TUNABLE_CMD_BUFFER_SIZE는 512 KiB입니다. 이슈 2173은 이미 unescape를 수정했습니다. 이 맵은 그 수정에 포함되지 않았습니다.
잘못된 방향: 2173을 이 버그로 취급하는 것; ASan이 크기 8의 WRITE를 보고했다고 해서 RIP라고 주장하는 것; .ftpaccess가 RewriteMap을 심을 수 있기를 바라는 것. 첫 번째는 다른 함수입니다. 두 번째는 여전히 Crash입니다. 세 번째는 CONF_DYNDIR입니다.
ASan과 기본 libcrypt는 rewrite 싱크 이전에 PASS에서 SIGSEGV가 발생합니다. 랩은 로그인이 작동하도록 작은 crypt(3) 스텁을 미리 로드합니다. 그 스텁은 익스플로잇이 아닙니다.
python3 proftpd-rewrite-utf8trans-Abraxas-Labs.py
또는:
cd lab
./run.sh
루프백 127.0.0.1:18740 및 패시브 18741-18750. Compose 프로젝트 proftpd-rewrite-utf8trans. Witness PROFTPD-REWRITE-UTF8TRANS-WITNESS. 이미지는 1.3.9d mod_rewrite의 ASan 빌드입니다. 200 ASCII 바이트의 제어 STOR는 성공합니다. 2048 ASCII 바이트의 STOR는 크기 8의 ASan global-buffer-overflow WRITE이며 세션 자식이 중단됩니다. 트리거 후 새 로그인은 여전히 작동합니다.
SUCCESS PROFTPD-REWRITE-UTF8TRANS asan=global-buffer-overflow write=yes child-dead=yes PROFTPD-REWRITE-UTF8TRANS-WITNESS
rewrite_utf8_to_ucs4의 대상 길이를 PR_TUNABLE_BUFFER_SIZE-1로 제한합니다. ucs4_longs / utf8_val을 넘어서는 쓰기를 중단합니다. 맞지 않는 맵 키는 거부하거나 잘라냅니다.
f59f248e26bdfa514443e42bf72a145641df635d)contrib/mod_rewrite.c rewrite_utf8_to_ucs4 / rewrite_map_int_utf8transint:unescapeGNU Affero GPL v3.0. LICENSE를 참조하세요. 루프백 랩 전용입니다. 보증은 없습니다.