워드프레스 보안
웹 루트에 남긴 .bak, DB 덤프, phpinfo가 위험한 이유와 uploads PHP 차단
사이트 22개와 워드프레스 8개 점검에서 나온 노출 파일(.bak 소스, DB 덤프, phpinfo, Duplicator 설치기)과, 찾는 명령, uploads PHP 실행·xmlrpc 차단 규칙과 응답 확인 결과입니다.
NAS에 있는 웹사이트 22개와 워드프레스 8개를 한꺼번에 점검하면서, 해킹 흔적보다 더 많이 나온 게 있습니다. 제가 직접 올려 두고 잊어버린 파일들입니다. DB 덤프, 설정 파일 백업, phpinfo.php, .bak 파일. 악성 코드는 아니지만, 공격자가 제일 먼저 찾는 것들입니다.
실제로 나온 것
| 파일 | 어디서 | 왜 위험한가 |
|---|---|---|
Duplicator dup-installer/ 안의 DB 덤프 8.7MB, wp-config 사본 | 리뷰 블로그 | 회원 비밀번호 해시와 DB 접속 정보가 통째로 다운로드됨 |
사이트 주소를 바꿀 때 뜬 .sql 백업 2개 | 워드프레스 1곳 | DB 전체 내용 |
phpinfo.php | 3곳 | PHP 버전, 확장 모듈, 서버 경로, 환경 변수 노출 |
index.php.bak-* 20개 | 일반 PHP 사이트 | PHP 소스가 실행되지 않고 텍스트로 내려감 |
날씨 API를 시험하던 test-weather.php | 같은 사이트 | API 키가 코드에 적혀 있음 |
debug.log, 옛 버전 폴더 | 단어 퀴즈 사이트 | 오류 메시지와 DB 접속 정보 |
제일 위험했던 건 .bak입니다. index.php는 요청하면 PHP가 실행돼서 결과만 나가지만, index.php.bak은 웹 서버가 PHP 파일로 인식하지 않아 소스 코드를 그대로 내려보냅니다. 소스 안에 DB 비밀번호나 API 키가 있으면 그대로 넘어갑니다. 실제로 이 사이트의 .bak 파일이 브라우저에서 200으로 다운로드되는 걸 확인했습니다.
Duplicator 설치기는 특히 조심해야 합니다
Duplicator는 사이트를 통째로 옮길 때 쓰는 플러그인입니다. 새 서버에 installer.php와 압축 파일을 올려 설치하는데, 설치가 끝나면 이 파일들을 지우라고 안내합니다. 이 리뷰 블로그에는 2022년 7월 15일 날짜의 설치기가 그대로 남아 있었습니다.
남아 있던 설치기의 PHP 오류 로그에는 2026년에만 3월 31일부터 7월 25일까지 7번 실행된 기록이 있었습니다. 저는 실행한 적이 없습니다. 이런 설치기 경로는 자동 스캐너가 흔하게 두드리는 대상이라, 남겨 두면 결국 누군가 찾아옵니다.
찾는 명령
제가 쓴 점검 스크립트는 파일 이름 패턴과 악성 코드 시그니처를 같이 봤는데, 노출 파일은 이름만으로도 대부분 찾을 수 있습니다.
find /volume2/web -type f \( \
-name "*.sql" -o -name "*.sql.gz" -o -name "*.bak" -o -name "*.bak-*" \
-o -name "*.old" -o -name "*.orig" -o -name "*.log" -o -name "*.zip" \
-o -name "*.tgz" -o -name "phpinfo.php" -o -name "installer.php" \
-o -name "dup-*" \) -not -path "*/#recycle/*" 2>/dev/null
찾은 파일은 삭제하기 전에 웹 루트 밖으로 옮겨 두고, 필요 없으면 그다음에 지웠습니다. 시놀로지는 공유 폴더마다 #recycle 휴지통이 있는데 여기 들어간 파일은 웹에서 보이지 않아 검색에서 뺐습니다.
그래도 뭔가 올라올 때를 대비한 규칙
파일을 치우는 것과 별개로, 워드프레스 8곳의 wp-content/uploads/.htaccess 맨 위에 PHP 실행을 막는 규칙을 넣었습니다. 가족 블로그에서 나온 업로더와 웹셸 상당수가 uploads 안에 있었기 때문입니다.
<FilesMatch "\.(php|phtml|php[0-9]|phar|suspected)$">
Require all denied
</FilesMatch>
xmlrpc.php도 6곳에서 막았습니다. 외부 앱으로 글을 올리는 기능인데 쓰는 곳이 없고, 비밀번호 대입 공격에 자주 쓰입니다.
<Files "xmlrpc.php">
Require all denied
</Files>
9월 27일에 공개 주소로 다시 요청해 봤습니다. 존재하지 않는 파일 이름으로 요청한 거라 실제로 실행될 파일은 없습니다.
| 요청 경로 | 응답 |
|---|---|
/wp-content/uploads/probe.php | 403 |
/wp-content/uploads/probe.phtml, probe.phar | 403 |
/wp-content/uploads/2026/probe.php | 403 |
/wp-content/uploads/probe.php.suspected | 403 |
/wp-content/uploads/없는폴더/probe.php | 404 |
/xmlrpc.php | 403 |
/phpinfo.php, /dup-installer/main.installer.php | 404 |
폴더가 있으면 파일이 없어도 403이 나옵니다. 규칙이 파일 이름만 보고 막기 때문입니다. 폴더 자체가 없으면 Apache가 거기까지 가지 않고 404를 냅니다. 어느 쪽이든 실행은 안 됩니다.
.suspected까지 넣은 건 보안 플러그인이 악성 파일 이름 뒤에 .suspected를 붙여 "무력화"해 두는 경우가 있어서입니다. 이 파일들이 여러 사이트에 그대로 남아 있었습니다.
지금 지키는 규칙
- 웹 루트에
.sql,.bak,.log,.zip,phpinfo.php를 두지 않습니다. 잠깐 필요하면 확인하고 바로 지웁니다. - 백업은 처음부터 웹 루트 밖 폴더에 만듭니다.
- 이전 설치기(Duplicator 등)는 설치가 끝나자마자 지웁니다.
- 테스트용 PHP 파일에 키를 적지 않습니다.
확인한 공식 자료
구현 과정에서 판단 기준을 교차 확인한 공식 문서입니다. 글의 사례와 결론은 운영자가 직접 겪은 작업을 바탕으로 작성했습니다.