
SMTPLib 원시 TCP 소켓을 통한 SSRF로 AutoGPT SendEmailBlock의 HTTP 차단 목록 우회
CVE-2026-33234 | 중간 5.0 | GHSA-4jwj-6mg5-wrwf 작성자: Pavan Nallamothu
AutoGPT Platform에서 네트워크에 닿는 모든 사용자 제어 입력을 매핑하고 있었습니다. HTTP 계층은 철저히 잠겨 있었습니다. 사설 IP 대역(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), 루프백, 클라우드 메타데이터 엔드포인트 — 모두 차단 목록에 있었습니다. 여러 각도에서 HTTP 게이트를 확인했습니다. 아무것도 통과하지 못했습니다.
그런 다음 SendEmailBlock 구성 스키마를 열었습니다.
SMTP 서버 필드는 자유 텍스트 입력이었습니다. 관리자 자격 증명도 아니었고, 배포 시 한 번 설정되는 잠긴 구성도 아니었습니다. 인증된 사용자라면 누구나 원하는 값으로 채울 수 있는 필드였습니다. 코드 경로를 추적한 결과 smtplib.SMTP()가 원시 TCP 소켓을 연다는 것을 발견했습니다. 그 연결은 IP 차단 목록이 있는 HTTP 경로를 절대 통과하지 않습니다. 플랫폼에는 두 개의 아웃바운드 경로가 존재했습니다. 하나만 보호되고 있었습니다.
SMTP 서버를 localhost:22로 지정했습니다.
SSH 배너가 오류 메시지에 돌아왔습니다. smtplib는 입력된 대상에 연결하고 SMTP 220 인사말을 읽으려 시도하며, 다른 응답이 오면 원시 바이트를 SMTPConnectError로 감쌉니다. 그 예외는 AutoGPT의 실행 프레임워크를 통해 전파되어 블록 출력에 깔끔하게 표시됩니다. HTTP 계층에 전혀 닿지 않고 대상의 SSH 버전 문자열을 보고 있었습니다.
이것이 흥미로웠던 점입니다. smtplib는 단순한 이메일 클라이언트가 아닙니다. 구조화된 오류 보고 기능을 갖춘 TCP 배너 수집기입니다. 포트 6379로 지정하면 Redis의 프로토콜 시그니처를 얻습니다. 닫힌 포트로 지정하면 ConnectionRefusedError가 호스트는 살아 있지만 포트가 닫혀 있음을 알려줍니다. 169.254.169.254:80으로 지정하면 클라우드 메타데이터 엔드포인트에 도달 가능한지 확인할 수 있습니다. 각 연결 시도는 서로 다른 유용한 오류를 반환합니다. 이메일을 보내야 하는 기능을 통한 비맹목적 SSRF입니다.
SMTPConfig 설계가 문제를 악화시킵니다. 안전한 아키텍처에서 SMTP 서버 주소는 관리자 제어 자격 증명이어야 합니다 — 한 번 설정되고, 잠기고, 사용자에게 노출되지 않아야 합니다. 대신 실행별 입력입니다. 모든 인증된 사용자가 플랫폼이 TCP 연결을 여는 위치를 제어합니다.
# SendEmailBlock 구성 - SMTP 서버를 내부 대상으로 설정
# SSH 스캔
smtp_server = "10.0.0.5"
smtp_port = 22
# 오류가 공개: "SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6"
# Redis 스캔
smtp_server = "10.0.0.5"
smtp_port = 6379
# 오류가 공개: "-ERR unknown command ..."
# 닫힌 포트 스캔
smtp_server = "10.0.0.5"
smtp_port = 9999
# 오류가 공개: "ConnectionRefusedError" (포트 닫힘, 호스트 활성)
# 클라우드 메타데이터 접근
smtp_server = "169.254.169.254"
smtp_port = 80
# 메타데이터 엔드포인트 도달 가능성 확인
블록 실행 API를 통해 전체 체인을 검증했습니다:
# 블록 실행 API에 대한 동등한 직접 테스트
curl -X POST https://autogpt-platform/api/blocks/execute \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"block_id": "send_email_block",
"inputs": {
"smtp_server": "10.0.0.5",
"smtp_port": 22,
"to": "[email protected]",
"subject": "test",
"body": "test"
}
}'
# 응답에 SSH 배너가 포함된 SMTPConnectError 포함
graph LR
A[공격자가 SMTP 서버를 내부 IP로 설정] --> B[SendEmailBlock이 smtplib.SMTP 호출]
B --> C[대상:포트로 원시 TCP 연결]
C --> D{서비스가 응답?}
D -->|예| E[배너가 SMTP 인사말로 읽힘]
E --> F[배너 데이터가 포함된 SMTPConnectError]
F --> G[오류가 블록 출력으로 전파]
D -->|아니오| H[ConnectionRefused = 포트 닫힘]
G --> I[공격자가 서비스 버전 읽음]이것이 열어주는 공격 표면은 상당합니다. SSH 배너는 정확한 버전(OpenSSH_8.9p1 Ubuntu-3ubuntu0.6)을 드러냅니다. Redis는 프로토콜 시그니처를 유출합니다. MySQL은 버전 문자열을 보냅니다. 각 배너는 CVE 조회를 기다리는 대상입니다. 공격자는 내부 네트워크를 매핑하고, 실행 중인 모든 서비스와 정확한 버전을 식별한 다음, 가장 취약한 대상을 공격합니다. "SMTP 서버"라는 라벨이 붙은 텍스트 필드에서 모두 가능합니다.
이를 만든 세 가지 누락된 검사: SMTP 경로에 IP 검증 없음, 포트 제한 없음, 예외 정화 없음. 플랫폼은 "발신 메일"이라는 라벨이 붙은 문을 제외한 모든 아웃바운드 문을 보호했습니다.
이 문제를 Significant Gravitas에 보고했습니다. 그들은 아키텍처의 공백을 즉시 이해했습니다.
수정 버전: autogpt-platform-backend 0.6.52 (차단 목록 적용에 SMTP 서버 검증 추가, 포트 제한 적용)