🎬 서론
OneTime 인프라는 현재 비용절감의 목적으로 ALB을 활용하지 않고,
인스턴스 내부에서 Nginx를 통해 라우팅하는 식으로 구성되어 있다.
그렇기 때문에 보안상 취약점이 있었고, 이를 해결하기 위해 Nginx에 Fail2Ban을 붙여서 웹 스캐닝 공격을 방지하고 있다.
이를 적용한 지 약 9개월이 되었고, 그동안 많은 악성 IP를 차단하며 공격도 어느정도 막고 깔끔한 로그를 유지할 수 있었다. 이번 글에서는 그동안 들어온 공격 정황에 대해서 정리해보며 인사이트를 뽑아보려고 한다.
📊 분석
1. 최근 공격
일별 Ban 횟수
날짜 │ 건수 │ 그래프
────────────┼──────┼─────────────────────────────────────
2025-12-28 │ 5 │ █████
2025-12-29 │ 3 │ ███
2025-12-31 │ 2 │ ██
2026-01-01 │ 2 │ ██
2026-01-02 │ 32 │ ████████████████████████████████ ← 새해 급증
2026-01-03 │ 6 │ ██████
2026-01-04 │ 21 │ █████████████████████
2026-01-05 │ 22 │ ██████████████████████
2026-01-06 │ 39 │ ███████████████████████████████████████
2026-01-07 │ 34 │ ██████████████████████████████████
2026-01-08 │ 24 │ ████████████████████████
2026-01-09 │ 20 │ ████████████████████
2026-01-10 │ 29 │ █████████████████████████████
2026-01-11 │ 25 │ █████████████████████████
2026-01-12 │ 24 │ ████████████████████████
2026-01-13 │ 33 │ █████████████████████████████████
2026-01-14 │ 24 │ ████████████████████████
2026-01-15 │ 57 │ █████████████████████████████████████████████████████████ ← 최고
2026-01-16 │ 28 │ ████████████████████████████
2026-01-17 │ 27 │ ███████████████████████████
2026-01-18 │ 19 │ ███████████████████
2026-01-19 │ 39 │ ███████████████████████████████████████
2026-01-20 │ 56 │ ████████████████████████████████████████████████████████
2026-01-21 │ 26 │ ██████████████████████████
2026-01-22 │ 4 │ ████
2026-01-23 │ 4 │ ████
2026-01-24 │ 3 │ ███
2026-01-25 │ 3 │ ███
2026-01-26 │ 2 │ ██
2026-01-27 │ 18 │ ██████████████████
2026-01-28 │ 44 │ ████████████████████████████████████████████
2026-01-29 │ 4 │ ████ (진행 중)
통계 요약
| 기간 | 일 평균 | 총 건수 | 비고 |
|---|
| 12월 말 (28-31) | 3.3건 | 10건 | 낮은 수준 |
| 01/01 ~ 01/07 | 22.3건 | 156건 | 새해 이후 급증 |
| 01/08 ~ 01/14 | 25.0건 | 175건 | 지속적 공격 |
| 01/15 ~ 01/21 | 36.0건 | 252건 | 피크 기간 |
| 01/22 ~ 01/26 | 3.2건 | 16건 | 일시적 감소 |
| 01/27 ~ 01/29 | 22.0건 | 66건 | 다시 증가 |
총 Ban 이벤트: 675건+
피크 일자
- 01/15: 57건 (최고)
- 01/20: 56건
- 01/28: 44건
- 01/06: 39건
- 01/19: 39건
증가 원인 추정
- 새해 이후 봇넷 활동 증가 (일반적 패턴)
- IP가 스캔 리스트에 등록 (한번 스캔되면 지속적 타겟)
- 인터넷 전체 무차별 스캔 (특정 타겟팅 아님)
- 01/22~26 감소: 주말/휴일 또는 봇넷 일시 중단 추정
2. 공격 패턴 분석
공격 경로 Top 30 (403 차단 기준)
| 순위 | 건수 | 경로 | 목적 |
|---|
| 1 | 95 | /.env | 환경변수/비밀키 탈취 |
| 2 | 38 | /.git/config | Git 저장소 정보 노출 |
| 3 | 34 | /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php | PHPUnit RCE |
| 4 | 31 | /vendor/phpunit/src/Util/PHP/eval-stdin.php | PHPUnit RCE |
| 5 | 31 | /vendor/phpunit/phpunit/Util/PHP/eval-stdin.php | PHPUnit RCE |
| 6 | 31 | /vendor/phpunit/phpunit/LICENSE/eval-stdin.php | PHPUnit RCE |
| 7 | 31 | /vendor/phpunit/Util/PHP/eval-stdin.php | PHPUnit RCE |
| 8 | 20 | /vendor/vendor/phpunit/... | PHPUnit RCE (변형) |
| 9 | 9 | /phpunit/phpunit/src/Util/PHP/eval-stdin.php | PHPUnit RCE |
| 10 | 8 | /test.php | PHP 테스트 파일 탐색 |
| 11 | 6 | /phpinfo.php | PHP 정보 노출 |
| 12 | 6 | /php.php | PHP 파일 탐색 |
| 13 | 6 | /alive.php | 서버 상태 체크 |
| 14 | 4 | /.git/index | Git 인덱스 노출 |
| 15 | 3 | /settings.php | 설정 파일 탐색 |
| 16 | 3 | /info.php | PHP 정보 노출 |
| 17 | 3 | /db.php | DB 설정 탐색 |
| 18 | 3 | /database.php | DB 설정 탐색 |
| 19 | 3 | /configuration.php | 설정 파일 탐색 |
| 20 | 3 | /config.php | 설정 파일 탐색 |
| 21 | 3 | /.git/HEAD | Git 정보 노출 |
| 22 | 2 | /wp-login.php | WordPress 로그인 |
| 23 | 2 | /public/vendor/phpunit/... | PHPUnit RCE (변형) |
| 24 | 2 | /public/.env | 환경변수 탈취 (변형) |
| 25 | 2 | /php_info.php | PHP 정보 노출 |
| 26 | 2 | /login/xmlrpc.php?rsd | WordPress XML-RPC |
| 27 | 2 | /login.php | 로그인 페이지 탐색 |
공격 유형별 분류
| 유형 | 건수 | 비율 | 설명 |
|---|
| PHPUnit RCE | 178+ | ~45% | CVE-2017-9841 취약점 (eval-stdin.php) |
| 환경변수 탈취 | 97+ | ~25% | .env 파일 접근 시도 |
| Git 정보 노출 | 45+ | ~12% | .git/config, .git/index, .git/HEAD |
| PHP 파일 탐색 | 40+ | ~10% | phpinfo.php, test.php, config.php 등 |
| WordPress | 6+ | ~2% | wp-login.php, xmlrpc.php |
| 기타 | 24+ | ~6% | OpenCart, 기타 CMS |
공격 샘플 로그
# .env 탈취 시도
104.238.37.253 "GET /.env HTTP/1.1" 403 "Chrome/116.0.5845.140"
# PHPUnit RCE (libredtail-http 악성봇)
161.248.162.15 "GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php" 403 "libredtail-http"
121.186.151.123 "GET /vendor/phpunit/phpunit/Util/PHP/eval-stdin.php" 403 "libredtail-http"
# Git 정보 노출 시도
93.123.109.175 "GET /.git/config HTTP/1.1" 403 "Firefox/89.0"
# OpenCart 취약점 스캔
54.207.108.112 "GET /index.php?route=checkout/cart HTTP/1.1" 403
54.207.108.112 "GET /index.php?route=account/login HTTP/1.1" 403
User-Agent 분석 (403 응답 기준)
| 건수 | User-Agent | 정체 |
|---|
| 16 | libredtail-http | RedTail Cryptominer (악성봇) |
| 5 | Chrome/91.0.4472.124 | 위장 스캐너 (구버전) |
| 3 | Chrome/116.0.5845.140 | 위장 스캐너 |
| 1 | Chrome/126.0.0.0 (CrOS) | ChromeOS 위장 |
| 1 | Firefox/89.0 | Firefox 위장 |
분석
- libredtail-http가 61% (16/26건) 차지 → PHPUnit RCE 집중 공격
- 나머지는 Chrome/Firefox로 위장한 자동화 스캐너
- 실제 브라우저가 아닌 봇이 User-Agent를 위조하여 접근
주요 악성 봇: libredtail-http
- 정체: RedTail Cryptominer 관련 악성 봇
- 목적: 암호화폐 채굴 악성코드 배포
- 타겟: PHPUnit RCE, Docker API
- C2 서버: 178.16.55.224
- 활동: 2025년 8월부터 활동 중
- 상태: nginx 403 + fail2ban으로 차단 중
3. 차단 IP 대역 분석
전체 425개 고유 IP를 대역별로 분석한 결과
| IP 대역 | 개수 | 추정 출처 |
|---|
45.78.x.x | 40+ | 특정 호스팅 업체 (집중 공격) |
101.x.x.x ~ 103.x.x.x | 50+ | 아시아 (중국, 인도, 동남아) |
34.x.x.x | 12 | Google Cloud Platform |
3.x.x.x, 13.x.x.x, 20.x.x.x | 8 | AWS |
102.x.x.x | 15+ | 아프리카 |
172.x.x.x | 10+ | 클라우드/VPS |
206.x.x.x | 5 | DigitalOcean |
주목할 패턴: 45.78.x.x 대역
45.78.194.186, 45.78.194.57, 45.78.194.63
45.78.198.194, 45.78.201.122, 45.78.204.222
45.78.205.176, 45.78.206.111, 45.78.207.13
... (40개 이상)
- 동일 /16 대역에서 40개 이상 IP가 차단됨
- 봇넷 또는 단일 공격자가 여러 IP를 돌려가며 공격하는 패턴
- 해당 대역 전체 차단 고려 가능 (선택사항)
💡 정리
- 생각보다 효과가 있다는 것을 알 수 있었다. 하지만 30일 차단이 풀린 후에 다시 공격을 하는 경우도 잦기 때문에, 여러 번 차단이 되면 영구 차단을 진행하는 방식도 고려해 봐야 할 것 같다.
- .env / config / php 관련 파일을 탈취하려는 정황이 많음을 알게 되었다. 클라우드에 서버를 띄우는 순간 표적이 될 수 있으니, 기본적인 보안은 적용하는 게 좋을 것 같다.
- AWS를 쓴다면 ALB에 WAF를 붙여서 이러한 일반적인 보안 문제는 해결할 수 있을 것이다. 하지만 늘 활용할 수는 없으니 Fail2Ban과 같은 다른 방법을 알아두는 것도 좋을 것이다.
부록: 관련 문서