개발자 참고자료
하위 도메인 파인더
하위 도메인 파인더 API 문서에서 요청 매개변수, 응답 필드, 코드 예제, DomScan 통합을 위한 오류 처리를 확인하세요.
하위 도메인 파인더
공개 호스트 이름 증거를 가능한 범위에서 반환합니다. sources=ct 매개변수는 호환 파이프라인을 선택합니다. 이 파이프라인은 먼저 crt.sh를 시도한 뒤 필요하면 HackerTarget, ThreatMiner, Wayback Machine, CertSpotter 순서로 대체 소스를 시도합니다. DomScan은 이름을 무차별 대입하거나 대상 사이트를 크롤링하지 않으므로 결과는 완전한 자산 목록이 아닙니다. 캐시 전용 요청에서 결과가 없으면 HTTP 202를, 모든 소스가 실패하면 HTTP 503을 반환합니다. 두 응답 모두 크레딧을 환불합니다.
GET
/v1/subdomains
쿼리 매개변수
| 매개변수 | 유형 | 설명 |
|---|---|---|
| domain 필수 | string | 하위 도메인을 찾을 루트 도메인 (예: "github.com") |
| prefer_cache 선택 사항 | boolean token | 캐시된 결과만 제공합니다. 새 캐시나 오래된 캐시가 없으면 API는 202를 반환하고 백그라운드 새로고침을 큐에 넣은 뒤 요청 크레딧을 환불합니다. 허용값: true, false, 1, 0, yes, no. 기본값: false. |
| sources 선택 사항 | string | 호환성을 위한 선택값입니다. ct만 허용됩니다. 이 값은 수동 검색 파이프라인을 시작하지만, 각 결과에는 증거를 제공한 공급자로 crtsh, hackertarget, threatminer, wayback, certspotter 중 하나가 표시됩니다. 오래된 캐시 항목에는 ct가 표시될 수 있습니다. |
| verify 선택 사항 | boolean token | 응답에 이미 선택된 이름만 DNS로 확인합니다. 검증 과정에서 이름을 추가로 찾지는 않습니다. 허용값: true, false, 1, 0, yes, no. 기본값: false. |
| include_wildcards 선택 사항 | boolean token | 와일드카드 인증서 증거를 별도의 wildcards 배열에 반환합니다. 와일드카드는 구체적인 호스트 이름 결과에 섞이지 않습니다. 허용값: true, false, 1, 0, yes, no. 기본값: false. |
| limit 선택 사항 | integer | 반환할 구체적인 호스트 이름 항목의 최대 수입니다. 1부터 2000 사이의 정수를 입력합니다. 기본값: 500. |
사용 사례
- 공격 표면 매핑 및 보안 감시
- 잊혔을 가능성이 있거나 섀도우 IT에 속한 호스트 이름 검토
- 인수 전 기술 실사
- 인프라의 경쟁 분석
- 버그 바운티 정찰
응답 필드
| 필드 | 설명 |
|---|---|
subdomains[].name | 반환된 호스트 이름입니다. 소스에 루트 도메인이 포함되면 루트 도메인도 나타날 수 있습니다. |
subdomains[].source | 증거를 제공한 공급자입니다. 가능한 값은 crtsh, hackertarget, threatminer, wayback, certspotter와 오래된 캐시의 ct입니다. |
subdomains[].first_seen | crt.sh와 CertSpotter 증거에서는 해당 호스트 이름에 대해 찾은 유효한 인증서 중 가장 이른 not-before 값입니다. 다른 수동 대체 소스에는 비교 가능한 인증서 시점이 없어 null을 반환합니다. |
subdomains[].verified | verify가 활성화되고 반환된 호스트 이름의 DNS 확인이 성공한 경우에만 true이며, 그 외에는 false입니다. |
subdomains[].dns_records | 반환된 호스트 이름을 선택적으로 검증하여 얻은 A 및 CNAME 레코드이거나 null입니다. 이 필드는 결과에 이름을 추가하지 않습니다. |
summary.total_found | 응답 제한을 적용하기 전에 찾은 구체적인 호스트 이름 항목의 총수입니다. 소스에 루트 도메인이 있으면 포함됩니다. |
summary.verified_count | 선택적 DNS 검증에서 확인된 반환 호스트 이름의 수입니다. |
HTTP 상태 코드
| HTTP 상태 코드 | 설명 |
|---|---|
200 성공 | 요청 성공 |
202 수락됨 | 캐시 전용 하위 도메인 요청에서 캐시가 없어 백그라운드 새로고침으로 수락되었습니다. 크레딧은 차감되지 않으며 Retry-After 지연 후 다시 시도하세요. |
400 잘못된 요청 | 잘못된 매개변수 |
402 결제 필요 | 이 요청을 실행할 크레딧이 부족합니다. |
503 서비스 이용 불가 | 업스트림 서비스를 사용할 수 없거나 일시적으로 속도 제한 중입니다. |
504 게이트웨이 시간 초과 | 업스트림 조회가 시간 초과되었습니다. |
예제 요청
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&sources=ct&include_wildcards=yes&limit=100"
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&sources=ct&verify=yes&limit=50"
curl -H "X-API-Key: your-api-key" "https://domscan.net/v1/subdomains?domain=example.com&prefer_cache=1"
import requests
domscan = requests.Session()
domscan.headers.update({"X-API-Key": "your-api-key"})
response = domscan.get(
"https://domscan.net/v1/subdomains",
params={
"domain": "example.com",
"sources": "ct",
"verify": "yes",
"include_wildcards": "yes",
"limit": 100
}
)
data = response.json()
print(f"Returned {data['summary']['returned']} hostname entries")
print(f"Verified: {data['summary']['verified_count']}")
live_subs = [s for s in data['subdomains'] if s['verified']]
for sub in live_subs[:10]:
print(f" {sub['name']}")
const domscanFetch = (url, options = {}) =>
fetch(url, {
...options,
headers: { ...options.headers, "X-API-Key": "your-api-key" },
});
const response = await domscanFetch(
'https://domscan.net/v1/subdomains?' + new URLSearchParams({
domain: 'example.com',
sources: 'ct',
verify: 'yes',
include_wildcards: 'yes',
limit: '100'
})
);
const data = await response.json();
console.log(`Returned ${data.summary.returned} hostname entries`);
console.log(`Verified: ${data.summary.verified_count}`);
data.subdomains
.filter(s => s.verified)
.forEach(s => console.log(` ${s.name}`));
예제 응답
{
"domain": "example.com",
"subdomains": [
{
"name": "api.example.com",
"source": "crtsh",
"first_seen": "2025-01-15T00:00:00Z",
"verified": true,
"dns_records": {
"A": ["192.0.2.10"],
"CNAME": null
}
}
],
"wildcards": [
{
"pattern": "*.example.com",
"source": "crtsh",
"first_seen": "2024-11-20T00:00:00Z"
}
],
"summary": {
"total_found": 1,
"returned": 1,
"verified_count": 1,
"unverified_count": 0,
"sources_used": ["crtsh"],
"apex_included": false,
"wildcard_suppressed_count": 1,
"wildcard_returned_count": 1
},
"intelligence_summary": {
"data_sources": ["crtsh"],
"source_count": 1,
"cache_status": "live",
"returned_count": 1,
"total_found": 1,
"truncated": false,
"limit": 100,
"verification_requested": true,
"include_wildcards": true,
"verified_count": 1,
"verified_ratio": 1,
"live_dns_record_count": 1,
"apex_included": false,
"wildcard_suppressed_count": 1,
"wildcard_returned_count": 1,
"first_seen_oldest": "2025-01-15T00:00:00Z",
"first_seen_newest": "2025-01-15T00:00:00Z",
"warning_count": 0
},
"meta": {
"query_time_ms": 184,
"cached": false
}
}
202 수락됨
{
"status": "pending",
"code": "CACHE_MISS_REFRESH_QUEUED",
"message": "Try again in a moment",
"domain": "example.com",
"retry_after": 30,
"credits_charged": 0,
"billing_status": "not_charged",
"request_id": "m8abc12-x9y8"
}
POST
/v1/subdomains/bulk
본문 매개변수
| 매개변수 | 유형 | 필수 |
|---|---|---|
| domains | string[] | 필수 |
| verify | boolean | 선택 사항 |
| include_wildcards | boolean | 선택 사항 |
| limit | integer | 선택 사항 |
응답 필드
| 필드 | 유형 |
|---|---|
results[] |
unknown[] |
meta |
object |
meta.total |
integer |
meta.succeeded |
integer |
meta.failed |
integer |
meta.max_items |
integer |
meta.credits_per_item |
integer |
meta.duration_ms |
integer |
예제 요청
curl -X POST "https://domscan.net/v1/subdomains/bulk" \
-H "Content-Type: application/json" \
-H "X-API-Key: $DOMSCAN_API_KEY" \
-d '{
"domains": [
"example.com",
"cloudflare.com"
],
"verify": false,
"limit": 500
}'
예제 응답
{
"results": [
null
],
"meta": {
"total": 1,
"succeeded": 1,
"failed": 1,
"max_items": 10,
"credits_per_item": 1,
"duration_ms": 1
}
}