워드프레스 보안
진짜 플러그인 이름을 한 가짜 폴더 6개와 숨긴 .ico PHP 242개
akismet, wordpress-seo 같은 이름의 빈 플러그인 폴더에 숨김 .ico 확장자로 심어진 PHP 파일이 4년 동안 발견되지 않은 이유와 찾는 명령, 함께 나온 Duplicator 설치기 흔적입니다.
워드프레스 8개를 wordpress.org 체크섬으로 전부 대조하다가, 리뷰 블로그에서 이상한 플러그인 폴더 6개를 찾았습니다. 이름은 akismet, tinymce-advanced, use-google-libraries, wordpress-seo, wp-optimize, wp-smushit. 전부 유명한 진짜 플러그인 이름입니다.
근데 안에 진짜 플러그인 파일이 하나도 없었습니다. 대신 .7010c72f.ico 같은 점으로 시작하는 숨김 .ico 파일만 잔뜩 있었고, 열어 보니 첫 바이트가 <?php였습니다. 아이콘 파일 이름을 한 PHP 코드입니다.
숫자로 보면 이렇습니다
| 폴더 | 파일 수 | 숨긴 .ico | .php |
|---|---|---|---|
plugins/akismet | 40 | 36 | 2 |
plugins/tinymce-advanced | 38 | 38 | 0 |
plugins/use-google-libraries | 37 | 37 | 0 |
plugins/wordpress-seo | 31 | 31 | 0 |
plugins/wp-optimize | 31 | 31 | 0 |
plugins/wp-smushit | 31 | 31 | 0 |
uploads/ 곳곳 | - | 38 | - |
| 합계 | 242 |
akismet 안의 PHP 2개는 검색엔진용 스팸 페이지를 뿌리는 도어웨이였습니다. 나머지는 전부 .xxxxxxxx.ico 형태입니다. 열어 본 파일 하나는 9,600바이트였습니다.
왜 4년 동안 아무도 몰랐나
이 흔적은 2022년 7월 15일 감염에서 나온 것으로, 정리한 날이 2026년 9월 22일이니 4년 넘게 그대로 있었습니다. 못 알아챈 이유는 세 가지였습니다.
- 관리자 화면에 안 보입니다. 워드프레스는 폴더 안에
Plugin Name:헤더가 있는 PHP 파일이 있어야 플러그인으로 인식합니다. 헤더 파일이 없으니 플러그인 목록에 아예 안 나옵니다. 활성화된 적도 없어서 사이트 동작에도 영향이 없었습니다. - 이름이 너무 정상입니다. 서버에서
ls wp-content/plugins를 해도akismet,wordpress-seo가 보이면 그냥 넘어가게 됩니다. - 숨김 파일입니다. 점으로 시작하는 파일은
ls에-a를 붙이지 않으면 안 보이고, 확장자가.ico라 PHP 파일만 찾는 검색에도 안 걸립니다.
.ico가 어떻게 PHP로 돌 수 있냐면, 다른 PHP 파일이 include로 불러오면 확장자와 상관없이 PHP로 실행됩니다. 이런 파일은 보통 그렇게 쓰입니다. 이번 파일을 어느 코드가 불렀는지까지는 확인하지 못했습니다.
찾는 명령
제가 찾은 방법은 체크섬 대조였지만, 가볍게 확인할 때는 이 정도로도 걸립니다.
# 1) PHP 코드로 시작하는 .ico 파일
find wp-content -name "*.ico" -exec grep -l "<?php" {} +
# 2) 점으로 시작하는 숨김 파일 전체
find wp-content -name ".*" -type f
# 3) Plugin Name 헤더가 없는 플러그인 폴더
for d in wp-content/plugins/*/; do
grep -lqs "Plugin Name:" "$d"*.php || echo "헤더 없음: $d"
done
3번에 걸린 폴더는 비어 있거나(워드프레스 기본 hello 폴더가 이런 경우가 있습니다) 가짜입니다. 이번에는 6개 전부 가짜였습니다.
같이 나온 것: 외부에서 계속 두드린 설치기
같은 사이트 루트에 Duplicator 플러그인의 설치기 폴더 dup-installer/가 남아 있었습니다. 파일 날짜가 2022년 7월 15일로, 감염 흔적과 같은 날입니다. 두 일이 관련이 있는지는 확인하지 못했습니다. 확실한 문제는 이 안에 DB 전체 덤프(8.7MB)와 wp-config.php 사본이 들어 있었고, 웹에서 그대로 접근할 수 있었다는 겁니다.
설치기의 PHP 오류 로그를 보니 2026년에만 7번 설치기 코드가 실행된 기록이 있었습니다. 3월 31일, 4월 7일 두 번, 5월 3일, 5월 25일, 6월 12일, 그리고 7월 25일 18시 44분(한국 시각). 제가 실행한 적은 없으니 외부에서 누군가 부른 겁니다. 이게 설치기를 다시 돌려 사이트를 덮어쓰려는 시도였는지까지는 로그만으로 알 수 없었습니다.
정리한 방법
- 가짜 플러그인 폴더 6개,
uploads의 숨긴.ico38개,wp-includes안의 웹셸 5개(oxqtyjed.php,ucxmapdb.php,auriqqbm.php,yllhycej.php,bxcohyns.php), 도어웨이 폴더sodium_compat/src/PHP52/social-class-vtoqagz/, 보안 플러그인이 이름만 바꿔 둔.suspected잔해를 모두 격리 폴더로 옮겼습니다. dup-installer/와 설치 로그·설정 사본도 웹 루트 밖으로 옮겼습니다.- 진짜 플러그인은 폴더 이름이 겹치지 않아 영향이 없었습니다. 가짜 폴더가 비활성이었던 덕분입니다.
uploads에 PHP 실행 차단 규칙을 넣었습니다.
"플러그인 목록에 안 보이면 없는 것"이라는 가정이 4년을 버티게 해 준 셈입니다. 플러그인 폴더는 관리자 화면이 아니라 파일 시스템에서, 숨김 파일까지 봐야 합니다.
확인한 공식 자료
구현 과정에서 판단 기준을 교차 확인한 공식 문서입니다. 글의 사례와 결론은 운영자가 직접 겪은 작업을 바탕으로 작성했습니다.