
수동 DNS 서버로, DNS 요청을 확인하고 CNAME 체인을 추적하며 정찰 중 잠재적인 서브도메인 탈취를 플래그하여 노출된 클라우드 스토리지 버킷(AWS S3, GCP, Azure)을 탐지합니다.
# S3DNS **s3dns**는 DNS 요청을 분석하고, CNAME을 추적하며, 알려진 버킷 URL 패턴과 일치시켜 클라우드 스토리지 버킷(AWS S3, Google Cloud Storage, Azure Blob)을 찾아내는 경량 DNS 서버입니다. **침투 테스터**, **버그 바운티 헌터**, **클라우드 보안 분석가**에게 유용한 도구로, DNS 트래픽 분석 중 노출된 클라우드 버킷을 발견하는 데 도움을 줍니다. S3DNS가 리콘 세션에서 시간을 절약해 주었다면, ⭐️를 눌러 주세요. 다른 사람들이 프로젝트를 찾는 데 도움이 됩니다. --- --- ### 🆕 업데이트 2026/03/06 * **TCP/53 지원** — S3DNS가 이제 UDP와 TCP 포트 53 모두에서 수신합니다. 잘린 UDP 응답 후 TCP로 재시도하는 클라이언트를 올바르게 처리하며, 쿼리를 TCP를 통해 업스트림으로 전달하여 전체 응답을 가져옵니다. * **더 큰 DNS 버퍼** — UDP 수신 버퍼가 512바이트에서 4096바이트로 증가했습니다. 클라이언트의 EDNS0 옵션이 변경되지 않고 업스트림 리졸버로 전달됩니다. * **응답 캐시** — TTL 기반 LRU 캐시가 UDP 및 TCP 경로에서 DNS 응답을 공유합니다. 활성 리콘 세션 중 업스트림 부하와 지연 시간을 줄여줍니다. `CACHE_SIZE`로 설정 가능(기본값: `1000`개 항목, `0`으로 설정하면 비활성화). * **속도 제한** — 클라이언트 IP별 요청 속도 제한으로 남용을 방지합니다. `RATE_LIMIT`으로 설정 가능(기본값: `100` req/s, `0`으로 설정하면 비활성화). * **서브도메인 탈취 탐지** — 도메인이 클라우드 스토리지 패턴과 일치하지만 `NXDOMAIN`을 반환하는 경우, S3DNS가 이를 **가능한 도메인 탈취**로 플래그합니다. 이는 공격자가 등록할 수 있는 클레임되지 않은 버킷을 가리키는 죽은 DNS 레코드를 나타냅니다. * **IPv6 IP 범위 확인** — AAAA 레코드도 확인하여 알려진 클라우드 스토리지 IP 범위와 대조합니다. AWS IPv6 S3 접두사가 IPv4 범위와 함께 로드됩니다. * **CNAME 깊이 제한** — 재귀적 CNAME 체인 추적이 제한됩니다(기본값: 10홉). 조작되거나 순환 레코드에서 무한 루프를 방지하기 위해 `max_cname_depth` 매개변수로 설정 가능합니다. ### 업데이트 2025/08/19 * 오프라인 AWS IP 범위를 JSON 파일로 추가했습니다. * 오프라인 Azure Storage IP 범위를 JSON 파일로 추가했습니다. * 다음을 사용하여 각 서비스에 대한 IP 범위 확인을 비활성화하는 옵션을 추가했습니다: * `AZURE_IP_RANGES=false` 또는 `AWS_IP_RANGES=false` (기본값은 true). * `regex_patterns` 및 하드코딩된 패턴을 `patterns` 폴더로 YAML 파일로 이동했습니다. 사용자 패턴을 추가할 수 있습니다. * **정규식 패턴은 `regex_`로 시작해야 합니다.** * 여러 클라우드 제공업체를 추가했습니다 * IBM Cloud Object Storage * Oracle Object Storage * Alibaba OSS * Backblaze B2 * Linode Object Storage * Scaleway Object Storage * Vultr Object Storage * Cloudflare R2 ### 업데이트 2025/06/21 * AWS GovCloud 지원을 추가했습니다. ### 업데이트 2025/04/16 * 정규식 패턴을 업데이트했습니다. * 가시성을 위해 출력을 업데이트했습니다(CNAME의 원래 도메인, 클라이언트 IP, IP 범위 표시기 표시). * AWS에서 IP 범위 자동 다운로드 — 이제 그것들도 확인합니다! * 사용자 IP 범위를 추가하는 옵션(클래스에서 패턴 또는 IP 범위를 수동으로 조정). ### 업데이트 2025/04/14 * **Google Cloud Storage** 및 **Azure Blob Storage** 버킷에 대한 정규식 지원을 추가했습니다. --- ## 🚀 기능 * 포트 `53`(UDP **및** TCP)에서 DNS 서버로 실행 * DNS 요청에서 잠재적 클라우드 스토리지 버킷 탐지: * **AWS S3** (가상 호스트 및 경로 스타일, GovCloud 포함) * **GCP 버킷** * **Azure Blob 컨테이너** * **DigitalOcean Spaces**, **Wasabi**, **IBM COS**, **Oracle Object Storage**, **Alibaba OSS**, **Backblaze B2**, **Linode**, **Scaleway**, **Vultr**, **Cloudflare R2** * **CNAME 체인**을 재귀적으로 추적(설정 가능한 깊이 제한)하여 마스킹된 클라우드 버킷 링크 포착 * **잠재적 서브도메인 탈취** 플래그 — NXDOMAIN을 반환하는 클라우드 스토리지 패턴 * 확인된 IP(A 및 AAAA 모두)를 알려진 **AWS S3 및 Azure Storage IP 범위**와 대조 * **TTL 인식 응답 캐시**로 지연 시간 및 업스트림 부하 감소 * **IP별 속도 제한**으로 남용 방지 * 모든 발견 사항을 콘솔과 파일에 기록 * 컨테이너 친화적 --- ## ⚙️ 작동 방식 S3DNS는 DNS 쿼리를 위해 **포트 53(UDP 및 TCP)**에서 수신합니다. 각 요청에 대해 다음을 수행합니다: 1. **요청된 도메인 추출** 2. **응답 캐시 확인** — 유효한 캐시된 응답이 있으면 즉시 반환 3. **요청을 실제 DNS 리졸버**(예: `1.1.1.1`)로 전달 — UDP 클라이언트는 UDP로, TCP 클라이언트는 TCP로 4. **유효한 DNS 응답을 클라이언트에 반환** 병렬로 다음을 수행합니다: * **클라우드 스토리지 버킷 패턴 확인**(정규식 및 하드코딩된 호스트 이름 일치) * **확인된 IP를 알려진 AWS S3 및 Azure Storage 범위와 대조**(IPv4 및 IPv6) * **CNAME 체인을 재귀적으로 추적**(설정된 깊이까지) * **일치하는 패턴에서 NXDOMAIN 히트**를 가능한 서브도메인 탈취 후보로 플래그 * **모든 발견 사항을 콘솔과 `s3dns.log`에 기록** ⚡ 리콘 중에 DNS로 사용하면 도구나 브라우저가 확인하는 모든 도메인에 대해 클라우드 버킷과 탈취 후보를 수동적으로 표면화합니다. --- ## 🧱 전제 조건 다음 중 하나만 필요합니다: * Python **3.11+** * Docker (선택 사항이지만 권장됨) --- ## 🔧 설치 *Python으로 로컬에서 실행하려는 경우에만 필요합니다* ### 리포지토리 클론 ```bash git clone https://github.com/olizimmermann/s3dns.git cd s3dns ``` ### 의존성 설치 (가상 환경 사용 권장) ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` --- ## 🧪 사용법 ### Python으로 실행 포트 53은 상승된 권한이 필요합니다: ```bash sudo python s3dns.py ``` *`sudo`에서 모듈 누락 오류가 발생하면 `sudo venv/bin/python s3dns.py`를 시도하세요* * 이미지를 직접 빌드하는 경우 Docker Hub 버전과 일관성을 위해 동일하게 태그하세요: `docker build -t ozimmermann/s3dns:latest .` ### Docker 사용 *S3DNS를 시작하는 가장 쉬운 방법입니다.* ```bash docker pull ozimmermann/s3dns:latest docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` ### Docker로 빌드 및 실행 ```bash docker build -t ozimmermann/s3dns:latest . ``` ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` 발견 사항 저장 위치: * **터미널** 및/또는 * `./bucket_findings/` 디렉터리 ### 문제 해결 분석을 수행하는 동일한 머신에서 S3DNS를 사용할 때 `--network host` 플래그를 설정하면 도움이 될 수 있습니다: ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --network host \ --name "s3dns" \ ozimmermann/s3dns:latest ``` 포트 53은 상승된 권한이 필요하므로 일부 사용자(예: Mac 사용자)는 `sudo`가 필요할 수 있습니다: ```bash sudo docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## 🌐 리콘에서 S3DNS 사용 시스템 또는 도구의 **DNS 리졸버**를 S3DNS 인스턴스로 설정하세요. > 대상 브라우징 또는 퍼징 중에 S3DNS는 모든 도메인을 분석하고 다음으로 확인되는지 알려줍니다: > > * **AWS S3 버킷** > * **GCP 버킷** > * **Azure Blob 컨테이너** > * 지원되는 13개 이상의 클라우드 스토리지 제공업체 > > **CNAME을 추적**하므로 도메인이 `cdn.example.com`을 가리키고, 이 도메인이 다시 클라우드 버킷을 가리키는 경우에도 포착합니다. > > 또한 **잠재적 서브도메인 탈취를 플래그**합니다 — 도메인이 클라우드 스토리지 패턴과 일치하지만 대상이 존재하지 않는 경우(NXDOMAIN), 죽은 레코드가 탈취 가능 후보로 강조 표시됩니다. 사이트를 분석하는 동안 수동적으로 사용하여 **노출된 버킷과 탈취 기회를 능동적인 프로빙 없이 발견**하세요. --- ## ⚙️ 설정 명령줄 플래그, 환경 변수 또는 `s3dns.py` 수정을 통해 동작을 조정할 수 있습니다. 모든 옵션의 우선순위는 **명령줄 플래그 > 환경 변수 > 대화형 프롬프트 / 기본값**입니다. 플래그 없이 실행하면 이전과 동일하게 작동합니다. ### 명령줄 플래그 전체 목록은 `python s3dns.py -h`를 실행하세요: | 플래그 | 해당 환경 변수 | 설명 | |---|---|---| | `-h`, `--help` | – | 도움말 표시 및 종료 | | `--version` | – | 버전 표시 및 종료 | | `-d`, `--debug` | `DEBUG` | 상세 디버그 출력 활성화 | | `-l`, `--listen IP` | `LOCAL_DNS_SERVER_IP` | 수신할 로컬 인터페이스 | | `-u`, `--upstream IP` | `REAL_DNS_SERVER_IP` | 전달할 업스트림 DNS 리졸버 | | `-b`, `--bucket-file PATH` | `BUCKET_FILE` | 발견된 버킷 도메인을 쓸 파일 경로 | | `--aws-ip-ranges` / `--no-aws-ip-ranges` | `AWS_IP_RANGES` | AWS S3 IP 범위 확인 전환 | | `--azure-ip-ranges` / `--no-azure-ip-ranges` | `AZURE_IP_RANGES` | Azure Storage IP 범위 확인 전환 | | `--rate-limit N` | `RATE_LIMIT` | 클라이언트 IP당 최대 DNS 요청/초 (`0` = 비활성화) | | `--cache-size N` | `CACHE_SIZE` | 최대 캐시된 DNS 응답 수 (`0` = 비활성화) | | `--max-cname-depth N` | – | 추적할 최대 CNAME 체인 깊이 (기본값: 10) | 예시: ```bash sudo python s3dns.py -l 0.0.0.0 -u 1.1.1.1 --rate-limit 200 --no-azure-ip-ranges ``` ### 환경 변수 | 변수 | 기본값 | 설명 | |---|---|---| | `DEBUG` | `false` | 상세 디버그 출력 활성화 | | `AWS_IP_RANGES` | `true` | AWS S3 IP 범위 확인 활성화 | | `AZURE_IP_RANGES` | `true` | Azure Storage IP 범위 확인 활성화 | | `REAL_DNS_SERVER_IP` | `1.1.1.1` | 쿼리를 전달할 업스트림 DNS 리졸버 | | `LOCAL_DNS_SERVER_IP` | `0.0.0.0` | 수신할 로컬 인터페이스 | | `BUCKET_FILE` | `buckets.txt` | 발견된 버킷 도메인을 쓸 파일 경로 | | `RATE_LIMIT` | `100` | 클라이언트 IP당 최대 DNS 요청/초 (`0` = 비활성화) | | `CACHE_SIZE` | `1000` | 최대 캐시된 DNS 응답 수 (`0` = 비활성화) | #### ⚠️ Azure IP 범위 참고 사항 Microsoft는 Azure Blob Storage IP 범위를 명시적으로 명명하지 않으므로, S3DNS는 **공개적으로 제공되는 모든 Azure Storage IP 주소**를 사용합니다. 이로 인해 오탐이 발생할 수 있습니다. 문제가 발생하면 이 확인을 비활성화하는 것을 고려하세요: ```bash AZURE_IP_RANGES=false ``` ### 사용자 패턴 추가 `patterns/` 디렉터리에 YAML 파일을 추가하세요. `regex_` 접두사가 있는 파일은 정규식 패턴으로 처리되며, 그 외의 파일은 부분 문자열 일치로 처리됩니다. --- ### 디버그 모드 **Python:** ```bash sudo su export DEBUG=true python s3dns.py ``` **Docker:** ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ -e "DEBUG=true" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` Docker에서 여러 환경 변수 설정: ```bash docker run --rm -p 53:53/udp -p 53:53/tcp \ -v "./bucket_findings/:/app/buckets/" \ -e "LOCAL_DNS_SERVER_IP=0.0.0.0" \ -e "REAL_DNS_SERVER_IP=1.1.1.1" \ -e "RATE_LIMIT=200" \ -e "CACHE_SIZE=2000" \ --name "s3dns" \ ozimmermann/s3dns:latest ``` --- ## 샘플 출력  --- ## 기여 기여는 환영합니다 — 새로운 클라우드 제공업체 패턴, 버그 수정, 개선 사항. 자세한 내용은 [CONTRIBUTING.md](https://github.com/olizimmermann/s3dns/blob/main/CONTRIBUTING.md)를 참조하세요. 패턴 파일은 `patterns/`에 있습니다. 새 제공업체에 대한 지원을 추가하는 것은 YAML 항목을 추가하는 것만큼 간단합니다 — Python이 필요하지 않습니다. --- ## 📄 라이선스 MIT 라이선스 — 자유롭게 사용, 개선 및 공유할 수 있습니다. --- ## ⚠️ 면책 조항 책임감 있게 사용하세요. **소유**하고 있거나 **명시적 권한**이 있는 도메인만 스캔하세요. 무단 액세스 또는 프로빙은 불법일 수 있습니다.