웹해킹2026. 06. 09. 오후 11:13

[웹 해킹 #1] 모의해킹 정보 수집(Reconnaissance) 완벽 정리 - 서브도메인 수집부터 amass, ffuf 까지

Profile
보람줄
조회 23
0

무슨 글일까요?

해킹을 배우려고 자료를 찾다 보면 검색 결과 대부분이 "Kali에서 이 명령어를 치면 됩니다" 식의 도구 사용법으로 채워져 있습니다. 

그런데 막상 그 명령어들을 따라 친 사람들이 실제 모의 침투를 해 보면 "그래서 이걸 언제, 왜 쓰는 거지?"에서 막힙니다.

도구 이름과 옵션은 외웠는데 공격이라는 행위 전체의 그림이 없기 때문입니다.

실제 모의 침투 테스트(Penetration Testing)에서 키보드를 화려하게 두드려 방화벽을 뚫는 장면은 거의 없습니다.

업무 시간의 대부분은 지루할 만큼 꼼꼼한 정보 수집(Reconnaissance) 에 쓰입니다.

표적에 대해 더 많이 알수록 공격 표면(Attack Surface)이 넓어지고, 공격 표면이 넓어질수록 비집고 들어갈 틈이 늘어나기 때문입니다.

이번 글에서는 도구 나열을 넘어서, 한 도메인을 두고 "무엇이 어디에 노출되어 있는지"를 어떻게 그려 나가는지 그 사고 과정을 따라가 보려고 합니다.

예제 도메인은 전부 example.com을 기준으로 작성했으니, 실습할 때는 본인이 권한을 가진 타겟으로 바꿔서 사용하시기 바랍니다.

본격적으로 들어가기 전에, 정보 수집을 하면서 가장 먼저 부딪히는 질문들을 정리해 보면 이렇습니다.

  • 타겟이 가진 서브도메인을, 타겟 몰래 알아낼 수 있을까?

  • admin, vpn처럼 숨겨 둔 서브도메인은 어떻게 찾을까?

  • 웹사이트 내부의 숨은 경로(/backup, /api)는 어떻게 발견할까?

  • 관리자가 "여긴 보지 마"라고 적어 둔 곳은 어디서 확인할까?

아래에서 이 질문들을 하나씩 풀어 가겠습니다.


패시브 vs 액티브 - 흔적을 남기느냐의 문제

정보 수집은 크게 두 갈래로 나뉩니다. 이 차이를 이해하는 것이 첫걸음인데, 단순히 "도구가 다르다"가 아니라 타겟이 내 존재를 아느냐 모르느냐의 차이라서 중요합니다.

구분

패시브 (Passive)

액티브 (Active)

방식

이미 공개된 흔적을 수집

대상 서버에 직접 요청

출처

검색엔진, 인증서 로그, WHOIS

DNS 무차별 대입, HTTP 요청

탐지 위험

낮음 (타겟이 모름)

높음 (서버 로그에 남음)

대표 도구

amass, theHarvester

knockpy, gobuster

쉽게 말해 패시브는 도서관에서 이미 출판된 자료를 찾는 일이고, 액티브는 직접 그 집 문을 하나하나 두드려 보는 일입니다.

도서관에서 책을 빌리면 아무도 신경 쓰지 않지만, 남의 집 문을 수천 번 두드리면 당연히 누군가 내다봅니다.

그래서 실전에서는 흔적이 남지 않는 패시브 수집을 먼저 충분히 한 뒤, 꼭 필요한 만큼만 액티브로 넘어갑니다.


패시브 수집의 핵심은 '인증서 로그'입니다

서브도메인 수집 도구로 amasssubfinder를 많이 소개하는데, 정작 이 도구들이 어디서 데이터를 가져오는지는 잘 설명하지 않습니다.

가장 강력한 출처 중 하나가 바로 인증서 투명성 로그(Certificate Transparency, CT) 입니다.

이걸 이해하면 왜 패시브 수집만으로도 숨은 서브도메인이 우수수 나오는지 납득이 갑니다.

CT는 구글이 2013년에 도입하고 RFC 6962로 표준화한 공개 프레임워크로, 인증서 발급 기관(CA)이 발급하는 모든 SSL/TLS 인증서를 공개된 추가 전용(append-only) 로그에 기록하도록 요구합니다.

원래 목적은 보안이었습니다. CT 이전에는 CA가 탐지되지 않고 아무 도메인에나 인증서를 발급할 수 있었고,

이 프레임워크는 브라우저가 신뢰하기 전에 모든 인증서가 공개 로그에 기록되도록 만들어 인증서 오발급 문제를 해결하려 했습니다.

그런데 보안을 위해 만든 이 '투명성'이 공격자에게는 정보의 보고가 됩니다.

조직이 SSL 인증서를 받을 때마다 이 CT 로그에 기록되기 때문에, 누구나 로그를 조회해 루트 도메인에 딸린 서브도메인을 열거할 수 있습니다.

핵심은 인증서의 SAN(Subject Alternative Name) 필드입니다. 최신 인증서는 자신이 보호하는 호스트명을 전부 SAN 필드에 나열하며, 이것이 CT 로그 분석에서 서브도메인을 발견하는 1차 출처가 됩니다.

인증서 하나가 수십 개의 서브도메인을 SAN에 담을 수 있으니, 인증서 한 장만 들여다봐도 내부 도구·스테이징 서버·API 엔드포인트가 한꺼번에 드러납니다.

가장 큰 공개 CT 로그 검색 엔진인 crt.sh에 와일드카드로 질의하면 바로 확인할 수 있습니다. %는 모든 서브도메인 접두사를 의미하는 와일드카드입니다.

# %.example.com 으로 모든 서브도메인 인증서 조회
curl -s "https://crt.sh/?q=%.example.com&output=json" | \
  jq -r '.[].name_value' | \
  sed 's/\*\.//g' | \
  sort -u

이 방식이 강력한 이유는, 크롤링처럼 메인 페이지의 링크를 따라가는 전통적인 방법으로는 메인 사이트에 링크되지 않은 서브도메인을 찾지 못하는 반면,

CT 로그는 인증서가 발급된 적 있는 호스트라면 더 이상 운영되지 않거나 라이브 DNS 조회로는 보이지 않는 것까지 드러내기 때문입니다.

즉, 메인 페이지만 봐서는 알 수 없는 내부 도구·스테이징 서버·옛 자산이 인증서 로그에는 고스란히 남아 있는 셈입니다.

그런데 crt.sh가 안 열린다면? (실제로 자주 겪는 일)

여기서 짚고 넘어가야 할 현실이 있습니다. crt.sh는 생각보다 자주 죽습니다. 트래픽이 몰리거나 점검 중이면 아래처럼 502를 뱉습니다.

$ curl -s "https://crt.sh/?q=%.example.com&output=json"
<html>
<head><title>502 Bad Gateway</title></head>
...

이때 "CT 로그 방식이 안 되는구나"라고 결론 내리면 안 됩니다.

방법이 틀린 게 아니라 그 사이트 하나가 일시적으로 죽은 것뿐입니다. ( 사이트가 폐쇄됐을 경우도 배제할 순 없습니다. )

같은 목적(서브도메인 수집)을 다른 출처로 달성하면 됩니다. 

예를 들어 hackertarget의 hostsearch API는 자체 DNS 데이터베이스를 조회하므로, crt.sh가 죽어도 멀쩡히 동작합니다.

# crt.sh가 502일 때 대안: hackertarget hostsearch
curl -s "https://api.hackertarget.com/hostsearch/?q=example.com" | cut -d',' -f1 | sort -u
cloud.example.com
dashboard.example.com
mail.example.com
www.example.com

이게 바로 앞서 말한 "최고의 도구는 없고, 각 상황에 맞는 도구가 있을 뿐" 이라는 원칙의 실전판입니다. 

한 출처가 막히면 다른 출처로 돌리는 것, 이게 정보 수집의 기본기입니다.

crt.sh, hackertarget, 그리고 뒤에서 볼 amass·subfinder가 모두 조금씩 다른 데이터를 보기 때문에, 가능하면 여러 개를 함께 돌려 교차 확인하는 것이 가장 안전합니다.

CT 로그를 보는 다른 방법은?

실시간으로 발급되는 인증서를 감시하고 싶다면 certstream 같은 도구로 스트리밍을 받을 수도 있습니다. 다만 입문 단계에서는 crt.sh의 웹/JSON 조회만으로도 충분합니다.

참고로 개별 CT 로그는 수명이 다해 닫히기도 하므로(예: Let's Encrypt의 Oak 2025 로그), 특정 로그에 직접 붙기보다 crt.sh 같은 집계 서비스를 쓰는 편이 안정적입니다.


amass - 여러 출처를 엮어 그림을 완성합니다

CT 로그가 강력하긴 하지만 그것만으로는 부족합니다.

amass는 OWASP가 관리하는 도구로, OSINT(공개 출처 정보)와 능동적 정찰을 결합해 외부 자산을 발견합니다.

이 도구의 강점은 다양한 출처의 데이터를 상호 연관(correlate) 시켜 표적의 공격 표면에 대한 정확한 그림을 그리는 데 있습니다.

CT 로그, 검색엔진, DNS 데이터셋 등을 한데 모아 "이 IP가 저 서브도메인이고, 저 서브도메인은 이 ASN에 속한다"는 관계망을 만들어 줍니다.

# 설치 (Kali / Debian)
sudo apt install amass

# 또는 최신 버전을 Go로
go install -v github.com/owasp-amass/amass/v4/...@master

# 기본 열거
amass enum -d example.com

출력은 단순한 목록이 아니라 관계의 나열로 나옵니다. 이걸 읽는 눈이 핵심입니다.

example.com (FQDN) --> ns_record --> toby.ns.cloudflare.com (FQDN)
mail.example.com (FQDN) --> a_record --> 10.10.10.47 (IPAddress)
dashboard.example.com (FQDN) --> a_record --> 10.10.10.47 (IPAddress)
4766 (ASN) --> managed_by --> Example Telecom, KR (RIROrganization)

여기서 읽어 내야 할 것은 이렇습니다.

  • 네임서버가 Cloudflare입니다. 이건 실제 원본 서버 IP가 CDN 뒤에 숨어 있을 가능성이 크다는 신호입니다. 화면에 보이는 IP가 진짜 서버가 아닐 수 있다는 뜻이죠.

  • mail, dashboard, rsp가 전부 같은 IP(10.10.10.47)를 가리킵니다. 한 서버에 여러 서비스가 올라가 있다는 의미이고, 그중 하나만 뚫려도 나머지가 위험해집니다.

  • ASN과 통신사 정보로 표적이 어느 IP 대역에 속하는지까지 파악됩니다.


theHarvester - 이메일과 호스트를 빠르게 확인합니다

서브도메인뿐 아니라 이메일 주소, 호스트명을 폭넓게 모으고 싶을 때 가볍게 쓰기 좋은 도구입니다.

# 설치
sudo apt install theharvester

# 구글 기반 수집
theHarvester -d example.com -b google

# 여러 소스 동시 수집
theHarvester -d example.com -b bing,duckduckgo,crtsh

이메일 주소가 왜 중요할까요? 이메일 명명 규칙(name.surname@example.com)을 알아내면 사회공학(피싱) 공격의 재료가 되고, 로그인 페이지에서 유효한 계정을 추측하는 단서가 되기 때문입니다.

정보 수집 단계에서 모은 이메일이 나중 단계의 무기가 됩니다.


knockpy - 숨겨 둔 문은 무차별로 두드립니다

패시브 수집이 '공개된 것'만 본다면, 이제 공개되지 않은 것을 찾을 차례입니다. 여기서부터 액티브 영역입니다.

knockpy는 사전(Wordlist)을 기반으로 admin., test., vpn. 같은 수천~수만 개의 단어를 도메인 앞에 붙여 DNS 서버에 실제로 하나하나 질의합니다.

인증서를 발급받지 않아 CT 로그에 안 잡히는 내부용 서브도메인도 이 방식으로는 찾아낼 수 있습니다. 대신, 앞서 말했듯 DNS 서버에 흔적이 남습니다.

# 설치
pip install knock-subdomains

# 기본 정찰
knockpy --domain example.com --recon
dashboard.example.com ['10.10.10.47']
http  [None, None, None]
https [404, None, None]
cert  [True, '2027-06-02']

cloud.example.com ['10.10.10.47']
http  [None, None, None]
https [302, 'https://cloud.example.com/login', None]
cert  [True, '2026-09-02']

여기서 던질 질문은 "그래서 이 중 뭐가 흥미로운가?"입니다.

  • cloud가 302로 /login에 리다이렉트됩니다. 인증이 걸린 영역이라는 뜻이고, 로그인 페이지는 곧 공격 표면입니다.

  • dashboard의 인증서 만료일이 다른 것들과 다릅니다(2027 vs 2026). 서로 다른 시점에 발급·관리된 별개 서비스일 수 있다는 단서입니다.

  • HTTP는 죽어 있고 HTTPS만 응답하는 건, HTTP→HTTPS 강제 리다이렉트가 걸린 정상 구성입니다.


디렉터리 탐색 - 사이트 내부의 숨은 방 찾기

서브도메인이 '건물'이라면, 이제 각 건물 안의 '방'을 찾을 차례입니다. 디렉터리 탐색 도구는 사전 파일을 기반으로 /admin, /backup, /api 같은 경로에 실제로 요청을 보내 존재 여부를 확인합니다.

입문 자료에서는 dirb를 많이 쓰는데, 솔직히 말하면 dirb는 느립니다. 요즘 현장에서는 ffuf, gobuster, feroxbuster가 표준입니다. (이 세대교체 이야기는 시리즈 마지막 글 #5에서 자세히 다룹니다.)

# ffuf - FUZZ 위치에 단어를 대입, 가장 빠르고 유연
ffuf -w /usr/share/wordlists/dirb/common.txt \
     -u https://example.com/FUZZ \
     -mc 200,301,302,403

# gobuster - 디렉터리 모드
gobuster dir -u https://example.com -w wordlist.txt -t 50

결과는 HTTP 상태 코드로 빠르게 판단합니다.

https://example.com/login      [Status: 200]
https://example.com/dashboard  [Status: 301]
https://example.com/finance    [Status: 302]
https://example.com/admin      [Status: 403]
https://example.com/robots.txt [Status: 200]
  • 200은 그대로 노출된 페이지입니다.

  • 301/302는 다른 곳으로 보내는 리다이렉트로, 보통 로그인을 요구합니다.

  • 403은 "존재하지만 접근 금지"인데, 역설적으로 "여기 뭔가 있다"는 가장 강한 신호입니다. 없는 경로는 403이 아니라 404를 주니까요.

참고로 이렇게 찾아낸 경로에서 한발 더 나아가 서버의 임의 파일까지 읽어내는 경로 조작(Path Traversal) 공격은 PortSwigger가 무료 실습 랩과 함께 아주 잘 정리해 두었으니, 더 파고들고 싶다면 이 글을 보면 좋습니다. [PortSwigger — Path traversal] - https://portswigger.net/web-security/file-path-traversal


robots.txt - 관리자가 직접 그려 준 보물지도

마지막으로, 어쩌면 가장 손쉬우면서도 자주 간과되는 파일입니다.

robots.txt의 원래 목적은 검색엔진 크롤러에게 "이 경로는 수집하지 마세요"라고 알려 주는 것입니다.

그런데 역설적이게도, 관리자가 검색엔진에 숨기고 싶어 하는 경로 목록이 그대로 적혀 있는 파일이 되기도 합니다.

"검색엔진에 숨기고 싶다"는 건 대개 "남들이 안 봤으면 좋겠다"와 같은 말이니까요.

User-Agent: *
Disallow: /admin/
Disallow: /api/
Disallow: /webhardstorage
Disallow: /todolist
Disallow: /finance
Disallow: /reset-password

Sitemap: https://example.com/sitemap.xml

Disallow에 적힌 /admin/, /api/, /webhardstorage는 침투 테스터 입장에서 "여기 중요한 게 있으니 먼저 봐 주세요" 라고 광고하는 것이나 다름없습니다. 

그리고 맨 아래 Sitemap은 그 사이트의 전체 페이지 목록으로 가는 링크라, 이것만 따라가도 사이트 구조가 한눈에 들어옵니다.

robots.txt는 강제력이 있나요?

전혀 없습니다. robots.txt는 크롤러가 자발적으로 지키기로 한 약속(권고)일 뿐, 접근을 물리적으로 막는 보안 장치가 아닙니다. Disallow: /admin/이라고 적어 둬도 브라우저로 직접 /admin/에 들어가는 건 아무도 못 막습니다. 그래서 robots.txt에 민감한 경로를 적어 두는 것은 "여기 금고가 있는데 비밀번호는 안 알려 줄게"라고 써 붙이는 것과 같습니다.

위치만 알려 주는 셈이죠. 민감한 경로는 robots.txt가 아니라 인증·인가로 보호해야 합니다.


정리

이번 글에서 따라간 사고의 흐름을 한 장으로 요약하면 이렇습니다.

[패시브]  CT 로그(crt.sh) / amass / theHarvester
            → 타겟 몰래, 공개된 서브도메인·인프라·이메일 수집
       ↓
[액티브]  knockpy
            → 인증서 없는 숨은 서브도메인을 무차별 대입으로 발굴
       ↓
[경로탐색] ffuf / gobuster / feroxbuster
            → 각 사이트 내부의 숨은 디렉터리 발견
       ↓
[힌트수집] robots.txt
            → 관리자가 숨기려는 경로 목록 확인

정보 수집은 결국 "공격할 문이 어디에 있는지" 그리는 지도 작업입니다.

화려한 익스플로잇보다 이 지루한 지도 그리기가 침투의 성패를 가른다는 점이, 입문자가 가장 늦게 깨닫는 사실이기도 합니다.

지도를 다 그렸으니, 다음 글에서는 그 지도에서 찾아낸 문 하나를 실제로 여는 첫 번째 방법 - 파일 업로드 취약점을 다루겠습니다.


다음 글 → [웹 해킹 #2] 파일 업로드 취약점과 웹쉘

읽어보면 좋을 추천 글

[RFC 6962 — Certificate Transparency] - https://www.rfc-editor.org/rfc/rfc6962.html 인증서 투명성의 원본 명세입니다. CT 로그가 왜 만들어졌고 Merkle Tree로 어떻게 위변조를 막는지, 이 글에서 다룬 내용의 1차 출처를 직접 확인할 수 있습니다. (2.0 버전인 RFC 9162로 대체되었으니 최신 명세는 https://datatracker.ietf.org/doc/rfc9162/ 를 참고하세요.)

[OWASP Amass Project] - https://github.com/owasp-amass/amass amass의 공식 저장소입니다. 설치법부터 패시브/액티브 모드 옵션, 설정 파일로 API 키를 연동하는 방법까지 가장 정확한 사용법이 정리되어 있습니다.

[crt.sh — Certificate Transparency 로그 검색] - https://crt.sh/ 본문에서 다룬 CT 로그 조회 사이트입니다. %.도메인 형식으로 직접 검색해 보면서 SAN 필드에 어떤 서브도메인이 들어있는지 눈으로 확인해 보세요.

[HackerTarget — DNS / Host Records] - https://hackertarget.com/find-dns-host-records/ crt.sh가 죽었을 때 쓸 수 있는 대안입니다. 자체 DNS 데이터베이스 기반이라 인증서 로그와는 다른 결과를 주므로, 교차 확인용으로도 좋습니다.