보안 가이드
내 웹사이트나 서버가 해킹됐는지 확인하는 법: 공유 호스팅, WordPress, VPS별 점검 순서와 발견했을 때 먼저 할 일
내 웹사이트나 서버가 침입당했는지 환경별로 확인하는 방법: 공유 호스팅, WordPress, Linux VPS, Google Search Console. 관리자 사용자, wp core verify-checksums, 로그인 기록, authorized_keys, cron, 리스닝 포트, 그리고 무언가 발견했을 때 대응하는 순서를 정리했다.
대상: 공유 호스팅, WordPress, VPS에서 사이트를 운영하는 개인이나 소규모 사업자로, 지금 "해킹당한 걸까?" 하고 걱정하는 사람. 이 가이드는 내 사이트와 서버를 스스로 확인하는 순서를 다룬다. WordPress.org, WP-CLI, Google 검색 센터의 공식 문서, 각 명령의 매뉴얼 페이지, 일본 IPA와 JPCERT/CC, GDPR을 바탕으로 했다. 공격 기법은 다루지 않는다.
지금 무언가 이상하다면 이것만 먼저 하라
사이트 파일을 삭제하거나 덮어쓰기 전에 로그와 사이트 전체(파일과 데이터베이스)를 복사해 둔다. 사라지고 나면 공격자가 어떻게 들어왔는지 더 이상 알아낼 수 없다. 비밀번호는 백신 소프트웨어로 검사한 다른 깨끗한 기기에서 바꾼다.
침입을 의심해야 할 징후
다음 중 하나라도 해당하면 아래의 환경별 점검으로 넘어간다. WordPress.org의 "FAQ My site was hacked"도 검색 엔진의 차단 목록에 오르는 것, 호스팅 업체가 사이트를 정지하는 것, 새 사용자가 생성되는 등의 무단 동작을 해킹의 분명한 징후로 든다.
| 징후 | 알아채는 곳 |
|---|---|
| Search Console에 보안 문제가 표시되거나 Google에서 이메일이 온다 | Google Search Console |
| 검색 결과에 "이 사이트는 해킹되었을 수 있습니다"가 표시된다 | Google 검색 |
| 브라우저가 위험한 사이트라고 경고하거나 방문자의 백신이 탐지한다 | 방문자의 연락 |
| 호스팅 업체가 변조, 스팸, 과부하를 경고하거나 사이트를 정지한다 | 호스팅 업체의 이메일 |
| 만든 적 없는 관리자 사용자 | WordPress 대시보드 |
| 만든 적 없는 페이지(의약품, 명품, 대량의 일본어 페이지)가 검색에 나온다 | site: 검색 |
| 휴대폰에서만, 또는 검색에서 들어올 때만 다른 사이트로 리디렉션된다 | 휴대폰으로 확인 |
| 서버가 스팸을 보내거나 발송 한도에 걸린다 | 호스팅 업체 알림, 반송 메일 |
| 이유 없이 CPU나 트래픽이 급증한다 | 서버 모니터링 |
"내 컴퓨터에서는 정상으로 보인다"는 아무것도 증명하지 않는다
Google(web.dev)은 해킹된 사이트 중 일부가 사용자 유형에 따라 다른 내용을 보여 준다(클로킹)고 설명한다. 내가 열면 빈 페이지로 보여도, Google에는 스팸성 단어와 링크가 보일 수 있다. Google 검색 센터 블로그 글도 해킹된 사이트가 모바일 사용자만 스팸 도메인으로 리디렉션할 수 있다고 지적하며, 스마트폰으로 Google 검색 결과에서 내 사이트를 열어 확인하라고 권한다.
환경별 점검
내 환경에 맞는 행을 확인한다. 공유 호스팅에서 WordPress를 운영한다면 처음 두 행이 모두 해당한다.
| 환경 | 볼 곳 | 찾을 것 |
|---|---|---|
| 공유 호스팅 | 제어판의 액세스 로그와 오류 로그, 파일 관리자, 메일 발송 기록 | 모르는 URL로의 요청이나 대량의 POST, 최근 수정된 파일, 모르는 .htaccess나 PHP 파일, 발송 메일 급증 |
| WordPress | 대시보드의 All Users(모든 사용자)와 Installed Plugins(설치된 플러그인), WP-CLI | 모르는 관리자, 설치하지 않은 플러그인이나 테마, 변조된 코어 파일 |
| VPS(Linux) | SSH 로그, authorized_keys, cron, 사용자 목록, 리스닝 포트, 패키지 검증 | 모르는 출처의 로그인, 모르는 공개 키, 모르는 예약 작업, 새 사용자, 모르는 프로그램의 리스닝 |
| Google Search Console | 보안 문제, URL 검사 도구, site: 검색 | Google이 찾은 문제와 샘플 URL, Google이 페이지에서 보는 내용 |
공유 호스팅
SSH가 없어도 제어판에서 대개 다음 세 가지는 확인할 수 있다(이름은 업체마다 다르다).
- 파일 관리자에서 공개 폴더를 열고 수정 날짜순으로 정렬한다. 손대지 않은 날에 바뀐 파일, 의미 없는 이름의 PHP 파일,
uploads같은 이미지 폴더 안의 PHP 파일에 주의한다 - 액세스 로그와 오류 로그를 내려받아 관리 화면 요청(WordPress라면
/wp-login.php와/wp-admin/)이 어디서 언제 왔는지, 모르는 URL로의 요청이 없는지 확인한다 - 메일 발송 건수나 기록을 볼 수 있다면 내가 보내지 않은 대량 발송이 없는지 본다
.htaccess도 확인한다. WordPress.org는 감염 유형과 관계없이 가장 자주 변조·악용되는 파일 중 하나로 .htaccess를 꼽으며, index.php, header.php, footer.php는 모든 페이지 요청에 영향을 주므로 가치가 높은 표적이라고 설명한다.
WordPress
대시보드에서 두 곳을 확인한다.
- Users > All Users(사용자 > 모든 사용자): 만든 적 없는 Administrator(관리자) 역할의 사용자가 있는가?
- Plugins > Installed Plugins(플러그인 > 설치된 플러그인): 설치하지 않은 플러그인이 있는가? Appearance > Themes(외모 > 테마)도 같은 방식으로 확인한다
서버에서 WP-CLI(WordPress 공식 명령줄 도구)를 쓸 수 있다면, 파일을 공식 릴리스와 자동으로 대조할 수 있다.
# Check WordPress core files against WordPress.org checksums
wp core verify-checksums
# Also warn about non-WordPress files in the WordPress root directory
wp core verify-checksums --include-root
# Verify plugins distributed on WordPress.org
wp plugin verify-checksums --all
# List administrator accounts with their registration dates
wp user list --role=administrator문제가 없으면 Success: WordPress installation verifies against checksums.가 출력된다. 일치하지 않는 파일이 있으면 Warning: File doesn't verify against checksum: 뒤에 파일 이름이 출력된다. 플러그인 검증은 WordPress.org의 체크섬과 대조하므로 유료 플러그인이나 직접 만든 테마는 이 방법으로 확인할 수 없다. 이런 것은 같은 버전을 공급처에서 다시 내려받아 비교한다.
VPS(Linux)
VPS에서는 침입자가 다시 들어오려고 남겨 두는 것을 찾는다. 공개 키, 예약 작업, 새 사용자, 접속을 기다리는 프로그램이다. 모두 내 서버에서 관리자로 실행한다.
# SSH login records (the unit is ssh on Debian/Ubuntu, sshd on RHEL-family)
sudo journalctl -u ssh --since "2026-10-01"
# Recent logins (on Debian 13, use wtmpdb last instead; install the wtmpdb and libpam-wtmpdb packages)
last -a
# Each user's last login (on Debian 13, use lastlog2 instead; install the lastlog2 and libpam-lastlog2 packages)
lastlog
# SSH public keys: the current user's (other users: /home/*/.ssh/authorized_keys) and root's
cat ~/.ssh/authorized_keys
sudo cat /root/.ssh/authorized_keys
# Scheduled jobs (per user and system-wide)
crontab -l
sudo crontab -l -u root
sudo cat /etc/crontab
sudo ls -la /etc/cron.d
# Users, and the group with admin rights (wheel on RHEL-family)
getent passwd
getent group sudo
# Listening TCP ports and the programs behind them
sudo ss -tlnp
# Files in the web root whose contents changed in the last 7 days
sudo find /var/www -type f -mtime -7
# Have package files changed since they were installed?
sudo debsums -s # Debian/Ubuntu (needs the debsums package)
sudo rpm -Va # RHEL-family결과를 읽는 법:
journalctl출력에서 성공한 로그인(Accepted)의 출발지 IP가 내 것이 아닌 주소인지 확인한다. 아무것도 나오지 않으면 유닛 이름이 다를 수 있으니systemctl list-units --type=service로 SSH 서비스 이름을 확인한다authorized_keys에서 추가한 적 없는 공개 키를 찾는다. 서버에 접근할 수 있는 키의 관리는 SSH 키 최소 권한에서 다룬다- cron에서 모르는 URL에서 무언가를 내려받아 실행하는 줄을 찾는다
ss목록에서 내가 실행하지 않은 프로그램이 리스닝하고 있지 않은지 본다debsums -s는 문제가 있는 파일만 보고한다.rpm -Va는 변경된 파일에 크기(S), 다이제스트(5), 수정 시각(T) 같은 코드를 붙인다
로그와 명령 출력에 너무 기대지 마라
find -mtime은 파일의 수정 시각을 보는데, 이 시각은 바꿀 수 있다. debsums 매뉴얼도 보안 도구로서는 쓰임새가 제한적이라고 밝힌다. 로그는 보존 기간이 끝나면 사라진다. 그리고 Debian 13에서는 2038년 문제 때문에 last, lastb, lastlog가 더 이상 제공되지 않는다. 어떤 점검이든 침입의 증거는 줄 수 있지만, 아무것도 찾지 못했다고 깨끗하다는 증거는 아니다.
Google Search Console
사이트가 아직 Search Console에 등록되어 있지 않다면, 먼저 추가하고 소유권을 확인한다.
- 보안 문제 보고서에서 문제가 표시되어 있는지 본다. 문제는 크게 해킹된 콘텐츠, 멀웨어 및 원치 않는 소프트웨어, 소셜 엔지니어링의 세 범주로 나뉘며, 보통 샘플 URL이 함께 나온다. 샘플 URL 없이 나오는 문제도 있는데, Google은 이것이 영향을 받은 페이지가 없다는 뜻은 아니라고 설명한다
- Google에서
site:내도메인으로 검색해 만든 적 없는 페이지를 찾는다. Google은 이 검색이 해커가 추가했을 수 있는 페이지를 포함해 내 사이트의 페이지를 보여 준다고 설명한다 - 의심스러운 페이지를 URL 검사 도구에 넣어 Google이 어떻게 보는지 확인한다
용어를 정리하면, 위와 같이 이미 일어난 침해의 흔적을 IOC(침해 지표)라고 한다. IOC란?을 참고하고, 진행 중인 공격을 행동으로 알아채는 방법은 IOA란?을 참고한다.
무언가 발견했을 때 먼저 할 일
순서를 틀리면 증거를 없애 버리거나, 공격자의 침입 경로가 열린 채로 사이트를 복구하게 된다. 위에서부터 진행한다.
1 — 차단
사이트를 내리거나 점검 중 페이지를 띄운다
2 — 증거 보존
로그, 파일, 데이터베이스를 서버 밖으로 복사한다
3 — 모든 자격 증명 교체
대시보드, FTP, SSH 키, 데이터베이스, API 키(깨끗한 기기에서)
4 — 깨끗한 상태로 되돌리기
침입 이전 백업으로 복원하거나 다시 구축한다
5 — 침입 경로 막기
업데이트, 쓰지 않는 플러그인 삭제, 원인 파악
6 — 검토 요청과 보고
Search Console 검토 요청, 필요하면 데이터 유출 보고
차단: 일단 사이트를 내린다
방문자에게 멀웨어나 사기 페이지가 전달되지 않도록 사이트를 내리거나 점검 중 페이지를 보여 준다. VPS라면 조사에 필요한 접속은 남기고 외부 트래픽을 제한한다. 공유 호스팅이라면 호스팅 업체 지원팀에 연락해, 사이트를 어떻게 내릴지와 업체 쪽에서 무엇을 할지 정한다. WordPress.org도 공유 호스팅에서는 해킹이 내 사이트 밖까지 영향을 줄 수 있으므로 호스팅 업체에 확인하라고 권한다.
증거 보존: 정리하기 전에 복사한다
WordPress.org는 감염된 상태라도 정리를 시작하기 전에 환경의 스냅숏을 한 번 더 남기라고 권한다. Google도 정리하기 전에 사이트 전체와 데이터베이스를 서버 밖의 장소에 백업하라고 안내한다. 액세스 로그, 오류 로그, SSH 로그는 일정에 따라 사라지므로 먼저 저장한다. 백업의 기본의 방식을 그대로 적용할 수 있다.
깨끗한 기기에서 모든 자격 증명을 교체한다
WordPress.org는 FTP/SFTP, WordPress 대시보드, 호스팅 제어판, MySQL 등 모든 접근 경로의 비밀번호를 바꾸고, 나뿐 아니라 환경에 접근할 수 있는 모든 사용자를 포함하라고 요구한다. wp-config.php의 비밀 키(솔트)를 다시 생성하면 아직 로그인해 있는 사람도 로그아웃된다. VPS라면 새 SSH 키를 만들고 authorized_keys에는 내 키만 남긴다. .env 같은 파일에 저장된 외부 서비스의 API 키는 다시 발급한다.
WordPress.org는 공격이 소유자 자신의 컴퓨터에서 시작되는 경우가 많다며 그 컴퓨터도 검사하라고 권한다. 변경은 검사를 마친 깨끗한 기기에서 하고, 다중 인증을 켠다.
깨끗한 상태로 되돌리기: 침입 이전 백업, 또는 재구축
침입 이전의 것이라고 확신할 수 있는 백업이 있다면 그것으로 복원한다. 공격자가 언제 들어왔는지 모른다면, 백업이 새로울수록 오염되어 있을 가능성이 크다. WordPress라면 wp-admin과 wp-includes를 공식 다운로드의 같은 버전으로 교체하고, wp-content의 테마와 플러그인은 공급처에서 다시 받는다. root가 침해됐을 수 있는 VPS라면, 정리하는 것보다 새 서버를 만들고 확인한 데이터만 옮기는 편이 더 확실하다.
같은 방법으로 다시 들어오지 못하게 침입 경로를 막는다
WordPress 코어, 플러그인, 테마를 업데이트하고 쓰지 않는 것은 삭제한다. 흔한 원인은 오래된 플러그인의 취약점, 재사용한 비밀번호, 공개 폴더에서 유출된 설정 파일이다. Google은 감염을 허용한 취약점을 고치지 않으면 사이트가 다시 감염될 수 있다고 경고한다. WordPress 강화는 WordPress 보안에서, 설정 파일을 둘 곳은 공개 디렉터리에 비밀 파일을 두지 않았는가?에서 다룬다. WordPress.org는 사이트가 깨끗해진 뒤 비밀번호를 한 번 더 바꾸라고도 권한다.
검토 요청과 보고: Search Console, 그리고 유출된 개인정보
Search Console에 문제가 표시됐다면 사이트 전체에서 모든 문제를 고친 뒤, 보안 문제 보고서에서 검토 요청을 선택한다. 요청에는 문제, 수정한 내용, 그 결과를 적는다. Google은 검토에 며칠에서 몇 주가 걸리며, 요청이 접수됐을 때와 완료됐을 때 이메일을 받는다고 설명한다. 결정이 나기 전에 다시 제출하면 검토가 길어질 수 있다.
문의 양식 제출 내용이나 회원 기록 같은 개인정보가 유출됐을 수 있다면, 아래의 "개인정보가 유출됐을 수 있다면"을 참고한다.
본 사이트의 견해: 점검의 목적은 깨끗하다고 선언하는 것이 아니라, 얼마나 믿을 수 있는지 정하는 것이다
소규모 사이트에서 흔한 실수는 의심스러운 파일 하나를 찾아 지우고 끝났다고 여기는 것이다. 하지만 찾은 파일은 침입의 결과일 뿐 침입 경로가 아니다. 침입 경로와 공격자가 남긴 재진입 수단(공개 키, 관리자 사용자, 예약 작업)을 막지 않으면 같은 일이 다시 일어난다.
그래서 발견한 내용을 "아직 얼마나 믿을 수 있는가"로 판단하기를 권한다. WordPress 코어 파일만 변조됐다면 코어 교체와 자격 증명 교체로 되돌릴 수 있을 가능성이 크다. 서버의 root가 탈취됐을 수 있다면 그 로그도 명령 출력도 믿을 수 없으므로 다시 구축한다. 이 선을 일찍 그으면, 며칠 동안 정리하다 결국 다시 구축하는 일을 피할 수 있다.
개인정보가 유출됐을 수 있다면
사업으로 개인정보를 다루고 있고 문의 양식 제출 내용이나 회원 기록이 유출됐을 수 있다면, 운영하는 곳의 규칙을 확인한다.
- EU와 영국(GDPR 제33조): 개인정보 침해를 알게 된 뒤 지체 없이, 가능한 경우 72시간 이내에 감독기관에 통지한다. 다만 사람들의 권리와 자유에 위험이 생길 가능성이 낮으면 예외다. 제34조는 당사자에게도 알려야 하는 경우를 다룬다
- 일본: 개인정보보호위원회(PPC)는 보고 대상을 네 가지로 든다. 민감 정보, 재산상 피해의 우려, 부정한 목적의 의심, 1,000명 초과다. 무단 접속으로 인한 유출은 부정한 목적 범주의 예로 들고 있다. 속보는 발견 후 3~5일 이내, 확정 보고는 30일 이내(부정한 목적 범주는 60일 이내)에 제출하며, 당사자에게도 알려야 한다
- 그 밖의 지역: 자국의 개인정보 보호 감독기관을 확인한다
도움을 받을 수 있는 곳
| 연락처 | 할 수 있는 일 |
|---|---|
| 호스팅 업체나 VPS 업체 | 사이트 정지, 업체 쪽 로그 확인, 같은 서버의 영향 조사 |
| JPCERT/CC 인시던트 대응 의뢰(일본) | 일반인의 사고 보고를 받는다. 변조된 웹사이트의 경우 사이트 관리자에게 연락해 수정을 요청한다. 웹 양식이나 이메일로 보고 |
| IPA 컴퓨터 바이러스·무단 접속 신고(일본) | 실제 피해가 없는 시도를 포함해 무단 접속 피해 신고를 받는다 |
| 자국의 CERT나 개인정보 보호 감독기관 | 일본 밖에서의 사고 보고와 데이터 유출 통지 |
| WordPress.org 지원 포럼 | 증상을 자세히 적으면 커뮤니티의 도움을 받을 수 있다 |
출처(공식)
- WordPress.org: FAQ My site was hacked — wordpress.org
- WordPress.org: Administration Screens — wordpress.org
- WP-CLI: wp core verify-checksums — developer.wordpress.org
- WP-CLI: wp plugin verify-checksums — developer.wordpress.org
- WP-CLI: wp user list — developer.wordpress.org
- Google: 보안 문제 보고서(Search Console 고객센터) — support.google.com
- Google: How do I know if my site was hacked? (web.dev) — web.dev
- Google: Fix the cloaked keywords and links hack (web.dev) — web.dev
- Google 검색 센터 블로그: Detect and get rid of unwanted sneaky mobile redirects(2015년 10월) — developers.google.com
- Google 검색 고객센터: Report a problem with Google Search("이 사이트는 해킹되었을 수 있습니다" 표시 관련) — support.google.com
- Debian 매뉴얼 페이지: journalctl(1), last(1), lastlog(8), sshd(8), crontab(1), cron(8), ss(8), find(1), debsums(1) — manpages.debian.org
- RPM: rpm(8)(--verify 출력 읽는 법) — rpm.org
- Debian 13(trixie) 릴리스 노트: last, lastb, lastlog 명령의 대체 — debian.org
- GDPR(규칙 (EU) 2016/679) 제33조와 제34조 — eur-lex.europa.eu
- 일본 개인정보보호위원회: 유출 등 보고와 본인 통지의 의무화(일본어) — ppc.go.jp
- 일본 개인정보보호위원회: 유출 등 사안이 발생한 경우의 대응(일본어) — ppc.go.jp
- JPCERT/CC: 인시던트 대응 의뢰(일본어) — jpcert.or.jp
- IPA: 컴퓨터 바이러스·무단 접속 신고(일본어) — ipa.go.jp
다음으로 읽기
- 개인 계정이라면: 누군가 내 계정에 접속했는지 확인하는 법
- 호스팅 업체 자체가 침해됐을 때: 웹 호스팅 업체가 침해됐을 때 고객이 할 일(내 설정으로는 막을 수 없는 일에 대비)
- 파일 위치 점검: 공개 디렉터리에 비밀 파일을 두지 않았는가? / 공유 호스팅에서 .env를 공개되지 않게 지키기
- WordPress: WordPress 보안 — 운영 환경 강화 레퍼런스 / 흔한 침입 경로: 파일 업로드 취약점
- 용어: IOC란? / IOA란? / 백도어란? / 멀웨어란?
- 복구: 백업의 기본
FAQ
Q내 웹사이트가 해킹됐는지 어떻게 확인하나요?
먼저 Google Search Console의 보안 문제 보고서에서 문제가 표시되어 있는지 봅니다. 그다음 Google에서 site:내도메인 으로 검색해 만든 적 없는 페이지가 없는지 봅니다. 마지막으로 스마트폰으로 Google 검색 결과에서 내 사이트를 열어 다른 곳으로 리디렉션되지 않는지 확인합니다. 해킹된 콘텐츠는 소유자가 사이트에 직접 접속할 때는 보이지 않도록 만들어지는 경우가 있습니다.
QWordPress 사이트가 탈취됐는지 어떻게 확인하나요?
대시보드에서 Users > All Users(사용자 > 모든 사용자)를 열어 만든 적 없는 관리자가 없는지, Plugins > Installed Plugins(플러그인 > 설치된 플러그인)에서 설치하지 않은 플러그인이 없는지 봅니다. WP-CLI가 있다면 wp core verify-checksums 로 WordPress 코어 파일을 공식 릴리스와 대조할 수 있습니다. WordPress.org에서 배포되는 플러그인은 wp plugin verify-checksums --all 로 확인할 수 있습니다.
Q사이트를 열면 정상인데 검색 결과에는 해킹되었을 수 있다고 나옵니다.
클로킹(방문자에 따라 다른 내용을 보여 주는 것)이 쓰이고 있을 수 있습니다. 해킹된 페이지는 검색 엔진에만, 또는 검색 결과에서 휴대폰으로 들어온 사람에게만 스팸이나 리디렉션을 보여 주기도 합니다. Google은 소유자가 Search Console에서 보안 문제를 해결하고 검토를 요청할 때까지 이 표시가 유지된다고 설명합니다. 보안 문제 보고서의 샘플 URL을 확인하고 URL 검사 도구로 Google이 보는 내용을 확인하세요.
QSSH가 없는 공유 호스팅입니다. 어떻게 확인하나요?
제어판의 파일 관리자에서 파일을 수정 날짜순으로 정렬하고, 액세스 로그와 오류 로그를 내려받아 모르는 URL로의 요청이나 관리 화면 로그인을 찾습니다. WordPress라면 대시보드에서 사용자와 플러그인을 확인합니다. 확신이 없으면 호스팅 업체 지원팀에 문의하세요. 공유 호스팅에서는 업체가 다른 고객을 포함한 서버 전체의 영향을 확인할 수 있는 경우가 있습니다.
Q아무것도 찾지 못하면 안전한가요?
아닙니다. 파일의 시각은 바꿀 수 있고, 로그는 보존 기간이 지나면 사라지며, 공격자가 root를 얻은 서버에서는 그 서버 자체의 명령 출력을 더 이상 믿을 수 없습니다. Search Console 경고나 호스팅 업체의 알림 같은 외부 증거가 있다면, 아무것도 찾지 못했더라도 침해된 것으로 보고 자격 증명 교체와 재구축을 계획하세요.
Q사이트에서 개인정보가 유출됐을 수 있습니다. 어디에 보고하나요?
운영하는 곳에 따라 다릅니다. 일본에서는 개인정보보호위원회가 무단 접속으로 인한 유출을 보고 대상 사례로 들며, 발견 후 3~5일 이내에 속보를, 30일 이내(부정한 목적이 의심되는 경우 60일 이내)에 확정 보고를 제출해야 합니다. EU와 영국에서는 GDPR에 따라, 사람들에게 위험이 생길 가능성이 낮은 경우가 아니면 가능한 한 72시간 이내에 감독기관에 통지해야 합니다. 자국의 개인정보 보호 감독기관을 확인하세요.