"공개되지 않은 서버는 안전하다"는 말은, 공개의 정의를 모르는 사람의 말입니다.
들어가며: 침묵하던 서버에 무슨 일이 일어나는가
새 서버를 하나 띄웠다고 가정해 봅시다. 클라우드 콘솔에서 인스턴스를 생성하고, 도메인을 연결하고, HTTPS 인증서를 발급받고, 애플리케이션을 배포했습니다. 아직 아무에게도 주소를 알려주지 않았습니다. 트위터에 올리지도, 검색 엔진에 등록하지도, 명함에 적지도 않았습니다. 당신과 당신의 팀 몇 명만 그 주소를 압니다.
그런데 배포 후 몇 시간이 지나 접근 로그를 열어 보면, 당신은 당황하게 됩니다. 본 적 없는 IP 주소들이 이미 당신의 서버를 두드리고 있습니다. /wp-login.php를 찾는 요청, /.env 파일을 요구하는 요청, /phpmyadmin/을 더듬는 요청, 그리고 SSH 포트로 쏟아지는 로그인 시도들. 당신은 분명 아무에게도 알리지 않았는데 말입니다.
이것은 버그가 아니고, 당신이 무언가 실수한 것도 아닙니다. 이것이 2026년 인터넷의 기본 물리 법칙입니다. 인터넷에 연결되는 순간, 당신은 발견됩니다. 그리고 발견되는 순간, 자동화된 공격이 시작됩니다. 사람의 개입 없이, 당신을 특정해서 미워하는 누군가 없이도, 순수하게 기계적으로 말입니다.
이 장에서는 그 "발견"이 어떻게 일어나는지를 해부합니다. 당신이 알리지 않았는데도 공격자가 어떻게 당신의 서버를 찾아내는지, 그 발견과 첫 공격 사이의 시간이 얼마나 짧은지, 그리고 그 첫 자동 공격이 구체적으로 무엇을 노리는지를 들여다봅니다. 이것을 이해하는 것은 단순한 호기심의 문제가 아닙니다. 적이 나를 어떻게 찾아내는지 알아야, 찾아내기 어렵게 만들거나 찾아낸 뒤에도 들어올 수 없게 만드는 방어를 설계할 수 있기 때문입니다.
1.1 "공개"의 진짜 의미 — 발견의 네 가지 경로
많은 운영자가 "주소를 알리지 않으면 안전하다"고 막연히 믿습니다. 이것을 보안 업계에서는 모호함을 통한 보안(security through obscurity) 이라고 부르며, 단독 방어 전략으로서는 거의 무가치하다고 평가합니다. 왜냐하면 인터넷에는 당신의 의도와 무관하게 당신의 존재를 세상에 광고하는 구조적 장치들이 여럿 존재하기 때문입니다.
당신의 서버가 발견되는 경로를 크게 네 가지로 나눌 수 있습니다.
경로 1: 인증서 투명성 로그 (Certificate Transparency Log)
이것이 가장 많은 운영자가 모르는, 그러나 가장 즉각적인 노출 경로입니다.
HTTPS를 쓰기 위해 당신은 TLS 인증서를 발급받습니다. Let's Encrypt든, 상용 인증 기관(CA)이든 마찬가지입니다. 그런데 2018년 이후 주요 브라우저(특히 크롬)는 인증서 투명성(CT) 로그에 기록되지 않은 인증서를 신뢰하지 않습니다. 즉, 공개적으로 신뢰받는 인증서를 발급받으려면, 그 인증서는 반드시 공개된 CT 로그에 기록되어야 합니다.
CT 로그는 누구나 열람할 수 있는 공개 장부입니다. 본래 목적은 악의적이거나 잘못 발급된 인증서를 감시 가능하게 만드는 것이었습니다. 즉, 보안을 위한 투명성 장치입니다. 그러나 이 투명성은 양날의 검입니다. 당신이 secret-admin.example.com이라는 호스트명으로 인증서를 발급받는 순간, 그 호스트명은 전 세계 누구나 검색할 수 있는 공개 기록이 됩니다.
공격자는 이 CT 로그를 실시간으로 모니터링합니다. 새 인증서가 로그에 추가되면 즉시 그 호스트명을 수집하고, 곧바로 스캔 대상 목록에 올립니다. 이 과정은 완전히 자동화되어 있으며, 새 인증서가 발급되고 나서 첫 스캔이 도착하기까지의 시간은 종종 수십 초에서 수 분에 불과합니다.
이것은 추상적인 이야기가 아닙니다. 지금 당장 crt.sh(공개 CT 로그를 검색해 주는 무료 서비스)에 접속해 검색창에 %.당신의도메인.com을 입력해 보십시오(예: %.example.com). 앞의 %는 "모든 서브도메인"을 뜻하는 와일드카드입니다. 그러면 당신이 그동안 발급받은 모든 인증서의 호스트명이 — dev, staging, old, mail 같은, 당신이 잊고 있었을 서브도메인까지 — 한 화면에 줄지어 나타납니다. 공격자가 당신의 자산 목록을 만들 때 가장 먼저 하는 일이 바로 이 한 번의 검색입니다. 내가 새 프로젝트를 인수받아 점검을 시작할 때도, 첫 5분은 거의 항상 crt.sh에서 그 도메인의 인증서 이력을 훑는 것으로 보냅니다. 운영자 본인도 모르던 옛 서브도메인이 거기서 튀어나오는 일이 잦습니다.
이것이 의미하는 바는 분명합니다. "아무도 모르는 비밀 서브도메인"이라는 것은, 적어도 HTTPS를 쓰는 한 존재하지 않습니다. 호스트명에 admin, dev, staging, test, internal, vpn, backup 같은 단어를 넣어 두면, 공격자는 그 단어만 보고도 "여기에 관리용 또는 비운영용 자산이 있다"는 것을 즉시 알아챕니다. 그리고 이런 비운영 자산은 운영 자산보다 보안이 허술한 경우가 압도적으로 많습니다.
방어의 단서: 와일드카드 인증서(*.example.com)를 사용하면 개별 호스트명이 CT 로그에 노출되지 않습니다. 또한 내부 전용 자산은 공개 DNS와 공개 인증서를 아예 사용하지 않고, 6장에서 다룰 Zero Trust 게이트웨이 뒤에 두는 것이 근본적인 해법입니다. 호스트명에 자산의 성격을 노출하는 단어를 피하는 것도 작은 도움이 됩니다.
경로 2: 패시브 DNS (Passive DNS)
DNS는 도메인 이름을 IP 주소로 바꿔 주는, 인터넷의 전화번호부입니다. 그런데 전 세계의 여러 보안 회사와 연구 기관은 DNS 질의 응답을 대규모로 수집하고 기록합니다. 이것을 패시브 DNS라고 부릅니다.
당신의 도메인이 한 번이라도 조회되어 IP로 해석되면, 그 매핑 관계(도메인 ↔ IP)는 패시브 DNS 데이터베이스에 영구히 기록될 수 있습니다. 공격자는 이 데이터베이스를 질의하여, 특정 IP에 어떤 도메인들이 연결되어 있었는지, 특정 도메인이 과거에 어떤 IP를 가리켰는지를 역추적할 수 있습니다.
이것이 왜 위험할까요? 예를 들어 당신이 Cloudflare 같은 CDN 뒤에 서버를 숨겼다고 합시다. 외부에서 도메인을 조회하면 Cloudflare의 IP만 보입니다. 그러나 만약 당신이 과거에 CDN을 적용하기 전 단 한 번이라도 도메인을 실제 서버 IP에 직접 연결한 적이 있다면, 그 기록은 패시브 DNS에 남아 있습니다. 공격자는 그 과거 기록을 찾아내 당신의 진짜 서버 IP(오리진 IP)를 알아내고, CDN을 우회하여 서버를 직접 공격할 수 있습니다.
방어의 단서: 오리진 IP는 처음부터 끝까지 노출하지 않아야 합니다. 한 번 노출된 IP는 영원히 기록에 남는다고 가정해야 합니다. 만약 오리진 IP가 노출된 정황이 있다면, 서버의 IP를 변경하고 방화벽에서 CDN의 IP 대역만 허용하도록 설정해야 합니다. 이 주제는 6장에서 자세히 다룹니다.
경로 3: 인터넷 전수 스캐너 (Internet-wide Scanners)
인터넷에서 사용 가능한 IPv4 주소는 약 43억 개입니다. 많아 보이지만, 현대의 스캐닝 도구에게는 그렇지 않습니다. ZMap이나 Masscan 같은 도구는 적절한 대역폭만 있으면 전체 IPv4 공간을 수 분에서 한 시간 이내에 한 바퀴 훑을 수 있습니다. ZMap은 미시간대 연구진이 공개한 오픈소스 도구로, "인터넷 전체를 한 번에 스캔한다"는 것이 더 이상 국가 정보기관의 전유물이 아니라 노트북 한 대로 가능한 일이 되었음을 보여 준 분기점이었습니다.
이 기술을 산업화한 것이 Shodan, Censys, 그리고 그 외 여러 인터넷 자산 검색 엔진입니다. 이들은 끊임없이 전체 인터넷을 스캔하여, 어떤 IP의 어떤 포트가 열려 있는지, 그 포트에서 어떤 서비스가 어떤 버전으로 돌아가는지, 어떤 배너(서비스가 접속자에게 처음 내보내는 자기소개 문자열 — 대개 소프트웨어 이름과 버전이 그대로 담깁니다)를 응답하는지를 기록하고 색인합니다. 마치 구글이 웹 페이지를 색인하듯, 이들은 인터넷에 연결된 모든 장치를 색인합니다. 둘 다 무료로 가입해 검색해 볼 수 있으니, 자신의 서버 IP를 한번 넣어 보십시오. "외부에서 내가 어떻게 보이는가"를 공격자와 똑같은 도구로 확인하는 가장 빠른 방법입니다.
그 결과, 누구나 이런 검색 엔진에서 "특정 버전의 특정 소프트웨어를 돌리는 모든 서버"를 단번에 찾을 수 있습니다. 새로운 취약점(CVE — 공개적으로 번호가 매겨진 알려진 보안 결함. 자세히는 4장에서 다룹니다)이 공개되면, 공격자는 굳이 인터넷을 직접 스캔할 필요조차 없습니다. 검색 엔진에 취약한 버전의 배너를 질의하기만 하면, 전 세계의 취약한 서버 목록을 즉시 손에 넣습니다. 당신의 서버가 그 버전을 돌리고 있다면, 당신은 그 목록에 들어 있습니다.
2021년 말 Log4Shell(CVE-2021-44228)이 터졌을 때가 이 메커니즘의 교과서적 사례입니다. 자바 로깅 라이브러리 Log4j의 치명적 결함이 공개되자, 단 몇 시간 만에 전 세계를 향한 대량 스캔이 시작됐습니다. 공격자들은 취약한 서버를 한 대씩 찾아다닐 필요가 없었습니다 — 이미 색인된 자산 목록을 질의하고, 거기에 익스플로잇을 살포했을 뿐입니다. 패치가 나온 뒤로도 이 공격은 수년간 이어졌습니다. 2026년 현재도, 새 고위험 CVE가 공개되면 똑같은 일이 반복됩니다. "공개 → 대량 스캔 → 무차별 익스플로잇"의 사이클은 이제 시간 단위로 돌아갑니다.
이것이 "발견과 공격 사이의 시간이 짧다"의 핵심 메커니즘입니다. 발견은 이미 끝나 있습니다. 검색 엔진이 상시 색인을 해 두었기 때문에, 공격자에게 남은 일은 색인을 질의하고 익스플로잇을 던지는 것뿐입니다.
방어의 단서: 서비스 배너에서 버전 정보를 숨기고, 꼭 필요하지 않은 포트는 전부 닫으며, 무엇보다 인터넷에 직접 노출되는 서비스의 수 자체를 최소화해야 합니다. 5장(공격면 지도화)과 6장(포트 닫기)의 핵심 주제입니다.
경로 4: 능동적 정찰과 평판 데이터
표적이 정해진 공격, 즉 APT(2장에서 다룹니다)의 경우에는 위의 수동적 발견을 넘어, 공격자가 능동적으로 당신을 조사합니다. 당신 회사의 도메인을 기점으로 서브도메인을 열거하고, 직원들의 이메일 주소와 SNS를 수집하고, 코드 저장소에 실수로 올라간 비밀 정보를 검색하고, 과거에 유출된 자격 증명 데이터베이스에서 당신 조직의 계정을 찾습니다.
이 단계에서 공격자가 사용하는 정보는 대부분 합법적으로 공개된 것들입니다. 이것을 OSINT(공개 출처 정보, Open Source Intelligence) 라고 부릅니다. 회사 채용 공고에 적힌 기술 스택, 개발자가 깃 저장소에 남긴 커밋 기록, 컨퍼런스 발표 자료에 담긴 아키텍처 다이어그램 — 이 모든 것이 공격자에게는 지도가 됩니다.
방어의 단서: 외부에 노출되는 정보를 의식적으로 관리해야 합니다. 코드 저장소에 비밀 정보가 올라가지 않도록 사전 검사를 두고, 채용 공고나 발표 자료에 인프라의 구체적 약점을 노출하지 않으며, 유출된 자격 증명을 상시 모니터링하는 것이 필요합니다. 14장(사람과 물리)에서 더 다룹니다.
1.2 발견에서 공격까지: 타임라인의 해부
이제 시간 축을 따라가 보겠습니다. 새 서버가 인터넷에 노출된 순간(T=0)부터 무슨 일이 순서대로 벌어지는지를, 실제 신규 서버에서 관찰되는 패턴에 기반해 재구성하면 다음과 같습니다.
T+0초 ~ 수 분: 첫 접촉. CT 로그 모니터링과 상시 스캐너에 의해 호스트가 색인됩니다. 가장 먼저 도착하는 것은 대개 단순한 연결 시도와 포트 스캔입니다. "이 IP의 어떤 포트가 열려 있나"를 확인하는, 인사조차 아닌 노크입니다.
수 분 ~ 수 시간: 자동화된 지문 채취와 1차 공격. 열린 포트가 확인되면, 그 포트에서 돌아가는 서비스의 종류와 버전을 식별하는 지문 채취(fingerprinting)가 이루어집니다. 그리고 거의 동시에, 가장 흔한 취약점과 잘못된 설정을 노리는 1차 자동 공격이 쏟아지기 시작합니다. 이 단계의 공격은 당신을 특정한 것이 아니라, "인터넷의 모든 웹 서버"를 상대로 무차별 살포되는 것입니다. 그 구체적인 내용은 1.3에서 다룹니다.
수 시간 ~ 수일: 공격의 누적과 다양화. 시간이 지날수록 서로 다른 공격 봇넷과 스캐너가 차례로 당신의 서버를 발견하고 목록에 추가합니다. 공격의 종류는 점점 다양해지고, 빈도는 누적됩니다. 며칠이 지나면 로그에는 수십에서 수백 종류의 자동 공격 흔적이 쌓입니다. SSH 무차별 대입, 알려진 웹 취약점 탐색, 노출된 설정 파일 요구, 백도어 설치 시도 등이 뒤섞입니다.
그 이후: 상시 배경 소음. 이 시점부터 자동 공격은 멈추지 않는 배경 소음이 됩니다. 인터넷에 연결된 모든 공개 서버는 매일, 매시간, 끊임없이 두드림을 당합니다. 이것은 당신의 서버가 특별히 미움받아서가 아니라, 공개 인터넷의 상수입니다.
여기서 반드시 짚어야 할 점이 있습니다. 이 모든 과정에 사람의 판단은 거의 개입하지 않습니다. 당신을 노린 누군가가 밤새워 키보드를 두드리는 것이 아닙니다. 전부 자동화된 기계의 작동입니다. 그렇기 때문에 "우리는 작고 알려지지 않았으니 표적이 될 리 없다"는 생각은 처음부터 성립하지 않습니다. 자동화는 크고 작음을 구별하지 않습니다. 그저 열려 있는 모든 문을 차례로 밀어 볼 뿐입니다.
1.3 첫 자동 공격의 해부: 그들은 무엇을 노리는가
그렇다면 그 1차 자동 공격은 구체적으로 무엇을 두드릴까요? 신규 서버의 접근 로그에서 반복적으로 관찰되는 요청들을 유형별로 분류하면, 공격자가 "가장 효율이 좋다고 학습한" 표적들이 무엇인지가 드러납니다. 이것을 아는 것은 매우 실용적입니다. 가장 흔히 노려지는 것이 곧 당신이 가장 먼저 막아야 할 것이기 때문입니다.
유형 1: 노출된 설정 파일과 비밀 정보
가장 먼저, 그리고 가장 끈질기게 시도되는 것이 환경 설정 파일을 요구하는 요청입니다. 대표적으로 .env 파일이 있습니다. 이 파일에는 데이터베이스 비밀번호, API 키, 암호화 키 등 애플리케이션의 가장 민감한 비밀이 담깁니다. 많은 프레임워크가 이 파일을 프로젝트 루트에 두는데, 웹 서버 설정이 잘못되어 이 파일이 외부에서 직접 다운로드 가능하게 노출되는 사고가 놀랄 만큼 자주 발생합니다.
공격자는 이것을 압니다. 그래서 새 서버를 발견하면 가장 먼저 /.env, /.git/config, /config.php.bak, /wp-config.php.save 같은 경로를 줄줄이 요구해 봅니다. 단 한 번의 성공이면 데이터베이스 전체와 클라우드 계정을 통째로 손에 넣을 수 있으니, 비용 대비 효율이 압도적입니다.
유형 2: 버전 관리 시스템의 노출
.git 디렉터리의 노출은 그 자체로 한 권의 책을 쓸 수 있을 만큼 흔하고 치명적인 문제입니다. 개발자가 프로젝트를 배포할 때 .git 디렉터리를 함께 올려 버리고, 웹 서버가 이 디렉터리에 대한 접근을 막지 않으면, 공격자는 이 디렉터리를 통째로 내려받아 소스 코드 전체와 모든 커밋 이력을 복원할 수 있습니다. 커밋 이력에는 과거에 실수로 커밋했다가 지운 비밀번호나 키가 그대로 남아 있는 경우가 많습니다.
그래서 자동 공격에는 /.git/HEAD, /.git/config, /.svn/entries 같은 경로 탐색이 거의 항상 포함됩니다. 11장에서 이 문제를 펜테스트 관점에서 다시 다룹니다.
유형 3: 콘텐츠 관리 시스템(CMS)과 관리 패널
워드프레스로 대표되는 CMS는 전 세계 웹사이트의 상당 부분을 차지하기 때문에, 공격자에게는 가장 수익성 높은 표적입니다. /wp-login.php, /wp-admin/, /xmlrpc.php 같은 워드프레스 경로에 대한 요청은 거의 모든 신규 서버의 로그에서 발견됩니다. 당신이 워드프레스를 쓰지 않더라도 이 요청은 옵니다. 공격자는 일일이 확인하지 않고 그냥 모두에게 던지기 때문입니다.
이와 함께 /phpmyadmin/, /adminer.php, /manager/html(톰캣), 각종 관리자 로그인 페이지에 대한 탐색도 쏟아집니다. 관리 패널은 일단 접근만 되면 시스템 전체를 장악할 수 있는 통로이므로, 공격자가 집요하게 노립니다.
유형 4: SSH와 원격 접속 무차별 대입
22번 포트가 열려 있다면, SSH 로그인 무차별 대입 공격은 사실상 100% 도착합니다. 공격자는 root, admin, ubuntu, test, oracle, postgres 같은 흔한 사용자명과, 유출된 비밀번호 목록을 조합하여 끊임없이 로그인을 시도합니다. 약한 비밀번호를 쓰는 계정이 하나라도 있으면 뚫립니다.
신규 서버의 인증 로그(/var/log/auth.log)를 배포 후 하루만 지켜봐도, 실패한 로그인 시도가 수백에서 수천 건 쌓이는 것을 직접 확인할 수 있습니다. 이것이 6장과 7장에서 SSH를 인터넷에서 아예 제거하거나 철저히 하드닝하는 것을 최우선 과제로 다루는 이유입니다.
유형 5: 알려진 취약점(CVE)을 노린 정밀 타격
마지막으로, 특정 소프트웨어의 특정 취약점을 정확히 겨냥한 익스플로잇 시도가 있습니다. 새로운 고위험 CVE가 공개되면, 며칠 안에 그 취약점을 노리는 자동화된 대량 스캔이 인터넷 전역에 퍼집니다. 공격자는 취약한 버전을 돌리는 모든 서버를 찾아 익스플로잇을 던집니다.
이 유형이 특히 무서운 이유는, 비밀번호의 강도나 관리자 패널의 보호 여부와 무관하게, 소프트웨어 자체의 결함을 통해 인증을 건너뛰고 시스템에 침입할 수 있기 때문입니다. 패치되지 않은 단 하나의 취약한 구성 요소가 모든 다른 방어를 무력화합니다. 이 위협의 본질은 4장(CVE의 홍수)에서 본격적으로 다룹니다.
1.4 흔한 오해들: 왜 "우리는 괜찮다"가 위험한가
지금까지의 내용을 접한 운영자들이 흔히 보이는 반응과, 그 반응이 왜 위험한지를 정리하겠습니다.
오해 1: "우리 사이트는 작아서 해커가 관심 없다." 앞서 설명했듯, 1차 자동 공격에는 사람의 관심이 개입하지 않습니다. 크기와 무관하게 모든 공개 서버가 동일하게 두드림을 당합니다. 게다가 작은 서버는 그 자체가 목표가 아니라, 더 큰 공격을 위한 도약대(예: 봇넷의 일부, 다른 공격의 경유지)로서 가치가 있습니다. 당신의 데이터에 관심이 없어도 당신의 컴퓨팅 자원과 IP 평판에는 관심이 있습니다.
오해 2: "우리는 가져갈 만한 중요한 데이터가 없다." 이 책의 서문에서 강조한 핵심입니다. 당신이 아직 털리지 않은 것은 가져갈 데이터가 없어서일 수 있습니다. 그러나 데이터가 없다는 것이 침입당하지 않는다는 뜻은 아닙니다. 침입자는 당신의 서버를 랜섬웨어로 암호화해 몸값을 요구하거나, 암호화폐 채굴에 쓰거나, 다른 곳을 공격하는 발판으로 삼거나, 스팸 발송 기지로 사용할 수 있습니다. 데이터의 가치와 무관하게, 장악당한 서버는 그 자체로 악용됩니다.
오해 3: "방화벽과 백신을 깔았으니 됐다." 방화벽은 닫아야 할 포트를 닫는 도구이지, 열어 둔 포트로 들어오는 공격을 막는 도구가 아닙니다. 80번과 443번 포트를 통해 들어오는 웹 애플리케이션 공격은 방화벽을 그대로 통과합니다. 백신 또한 알려진 악성코드의 패턴을 잡을 뿐, 잘못된 설정이나 애플리케이션 취약점을 막지 못합니다. 단일 도구로 끝나는 보안은 없습니다(원칙 3: 깊이로 방어하라).
오해 4: "주소를 안 알렸으니 못 찾는다." 1.1에서 네 가지 발견 경로를 통해 충분히 반박했습니다. CT 로그, 패시브 DNS, 상시 스캐너는 당신의 협조 없이 당신을 찾아냅니다. 모호함은 방어가 아닙니다. 그것은 방어를 보조하는 작은 요소일 뿐, 그 자체로 의지할 수 있는 것이 아닙니다.
1.5 직접 확인해 보기: 내 서버는 지금 무엇을 겪고 있는가
이 장의 내용은 추상적인 주장이 아닙니다. 당신이 직접, 그리고 합법적으로(자신의 서버에 대해서만) 확인할 수 있습니다. 다음은 자신의 서버에서 실제 공격 시도를 관찰하는 가장 기본적인 방법들입니다.
인증 로그에서 SSH 공격 관찰하기
리눅스 서버에서 다음 명령으로 실패한 SSH 로그인 시도를 셀 수 있습니다.
# 데비안/우분투 계열
sudo grep "Failed password" /var/log/auth.log | wc -l
# 어떤 사용자명이 시도되었는지 상위 목록
sudo grep "Failed password" /var/log/auth.log \
| grep -oE "for (invalid user )?[a-zA-Z0-9_-]+" \
| sort | uniq -c | sort -rn | head -20
# 어떤 IP에서 가장 많이 시도했는지 상위 목록
sudo grep "Failed password" /var/log/auth.log \
| grep -oE "from [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" \
| sort | uniq -c | sort -rn | head -20
배포한 지 하루만 지난 서버에서도, 이 명령은 수백에서 수천 줄의 결과를 보여 줄 것입니다. root, admin, test 같은 사용자명이 상위를 차지하는 것을 직접 보게 됩니다.
웹 서버 로그에서 자동 공격 관찰하기
Nginx나 Apache의 접근 로그에서, 1.3에서 설명한 표적들에 대한 요청을 찾아볼 수 있습니다.
# Nginx 기준, 흔한 공격 표적 경로에 대한 요청 집계
sudo grep -hE "\.env|\.git|wp-login|wp-admin|phpmyadmin|xmlrpc" \
/var/log/nginx/access.log \
| awk '{print $7}' | sort | uniq -c | sort -rn | head -30
# 404를 가장 많이 유발한 요청 경로 (탐색 시도의 흔적)
sudo awk '$9 == 404 {print $7}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -30
존재하지도 않는 /.env, /wp-login.php, /.git/config 같은 경로에 대한 요청이 줄지어 나타나는 것을 확인할 수 있습니다. 당신이 그런 파일을 둔 적이 없는데도 말입니다. 이것이 바로 무차별 자동 탐색의 증거입니다.
외부에서 내 서버가 어떻게 보이는지 확인하기
내 서버의 어떤 포트가 외부에 열려 있는지, 공격자의 시선에서 점검하는 것은 매우 중요합니다. 자기 자신의 서버에 대한 포트 스캔은 합법적이며 권장됩니다.
# 자신의 서버에 대한 포트 스캔 (예: nmap)
# 반드시 자신이 소유하거나 명시적 허가를 받은 대상에만 사용하십시오.
nmap -sV -p- your-server-ip
이 결과에서, 당신이 열려 있는 줄 몰랐던 포트나 서비스가 발견된다면, 그것이 바로 당신의 공격면입니다. 이 주제는 5장과 10장에서 체계적으로 확장하며, 포트 스캔뿐 아니라 TLS 설정, 보안 헤더, 알려진 취약점까지 직접 점검하는 도구와 방법도 10장에서 다룹니다.
정찰 검색 엔진에서 내 자산이 어떻게 보이는지 확인하기
명령어를 설치할 필요도 없이, 웹 브라우저만으로 공격자의 시선을 그대로 따라가 볼 수 있습니다. 다음 세 가지는 지금 5분이면 끝납니다.
- crt.sh에서 내 인증서 이력 보기. 검색창에
%.내도메인.com을 입력하십시오. 그동안 발급된 모든 호스트명이 나옵니다. 여기서 처음 보는, 또는 이미 폐기했어야 할 서브도메인이 나온다면 그것부터 정리해야 합니다. - Shodan에서 내 IP 검색하기. 검색창에 서버의 공인 IP를 넣으면, 열린 포트와 서비스 배너, 추정 소프트웨어 버전이 보입니다. 운영체제나 웹 서버 버전이 그대로 노출되어 있다면 정찰 난이도를 낮춰 주는 셈입니다.
- Censys에서 교차 확인하기. Shodan과 수집 시점·관점이 달라, 한쪽에 없던 정보가 다른 쪽에 잡히기도 합니다. 두 곳을 함께 보면 사각지대가 줄어듭니다.
이들 검색 엔진은 이미 수집해 둔 과거 데이터를 보여 주는 것이라, 방금 닫은 포트가 한동안 "열림"으로 남아 있을 수 있습니다. 실시간 상태는 위의
nmap으로, 노출 이력은 이 검색 엔진으로 — 두 가지를 함께 쓰는 것이 정확합니다.
중요한 경고: 포트 스캔과 취약점 스캔은 반드시 자신이 소유하거나 서면으로 명시적 허가를 받은 시스템에 대해서만 수행해야 합니다. 타인의 시스템을 허가 없이 스캔하는 것은 많은 국가에서 불법이며, 한국에서도 정보통신망법 위반으로 처벌받을 수 있습니다. 이 책의 모든 공격적 기법은 오직 방어와 자가 점검을 위한 것입니다.
1.6 이 장이 남기는 교훈
이 장에서 우리가 확인한 것을 압축하면 다음과 같습니다.
첫째, 인터넷에 연결되는 순간 발견은 끝납니다. CT 로그, 패시브 DNS, 상시 스캐너라는 구조적 장치들이 당신의 협조 없이 당신을 색인합니다. 모호함은 방어가 아닙니다.
둘째, 발견과 공격 사이의 시간은 매우 짧습니다. 사람이 개입하지 않는 완전 자동화된 공격이 분 단위로 도착하며, 시간이 지날수록 누적되어 멈추지 않는 배경 소음이 됩니다.
셋째, 첫 공격이 노리는 표적은 정해져 있습니다. 노출된 설정 파일과 비밀 정보, 버전 관리 시스템, CMS와 관리 패널, SSH 무차별 대입, 그리고 알려진 CVE. 가장 흔히 노려지는 이 다섯 가지가 당신이 가장 먼저 막아야 할 것입니다.
넷째, "우리는 괜찮다"는 생각이 가장 위험합니다. 크기, 데이터의 가치, 단일 보안 도구의 존재 — 그 무엇도 당신을 자동화된 공격의 대상에서 제외시켜 주지 않습니다.
다섯째, 이 모든 것은 직접 확인 가능합니다. 자신의 서버 로그를 들여다보면, 지금 이 순간에도 진행 중인 공격을 두 눈으로 볼 수 있습니다.
그렇다면 우리는 무엇을 해야 할까요? 발견을 피할 수 없다면, 발견되어도 들어올 수 없게 만들어야 합니다. 그러기 위해서는 먼저 누가 우리를 공격하는지, 그들의 동기와 역량은 무엇인지를 이해해야 합니다. 자동화된 봇과 표적을 정한 APT는 전혀 다른 상대이며, 다른 방어를 요구합니다. 다음 장에서는 이 공격자들을 분류하고, 각각이 어떻게 다른 위협을 가하는지를 살펴보겠습니다.
이 장의 실행 항목
지금 바로 할 수 있는 것들입니다. 자세한 방법은 괄호 안의 장에서 다룹니다.
- 자신의 서버 인증 로그를 확인하십시오. 지금 이 순간 얼마나 많은 SSH 공격이 도착하고 있는지 두 눈으로 보십시오. (이 장 1.5)
- 자신의 서버 웹 로그를 확인하십시오.
/.env,/.git,/wp-login.php탐색 요청이 있는지 보십시오. (이 장 1.5) - 자신의 서버를 외부에서 포트 스캔하십시오. 열려 있는 줄 몰랐던 포트를 찾으십시오. (5장, 10장)
- crt.sh에서
%.내도메인.com을 검색하십시오. 잊고 있던 서브도메인과,admin·dev·staging처럼 자산 성격을 노출하는 호스트명이 있는지 두 눈으로 확인하십시오. (이 장 1.1, 1.5) - 오리진 IP가 과거에 노출된 적이 있는지 점검하십시오. 패시브 DNS 기록을 의식하십시오. (6장)
다음 장: 2장 — 공격자의 분류학. 당신을 두드리는 그들은 누구인가.