📚 네트워크 · 패킷 분석 › 06. 방화벽 · IDS 기초 — 292편
이전 글: 291. Port Scan 탐지 · 다음 글: 293. Web Attack 탐지
Brute Force 탐지는 인증 서비스에 대한 반복적인 로그인 시도를 찾아내는 것입니다. SSH 대입 공격의 흔적과 스캔과의 구분은 05 영역 232. SSH Brute Force, 233. Brute Force와 Scan 구분에서 다뤘습니다. 이 글은 탐지 로직이 무엇을 세고, 어떤 데이터에서 판단하는가를 다룹니다.
반복 로그인 시도는 두 위치에서 탐지할 수 있으며, 각각 볼 수 있는 것이 다릅니다.
| 탐지 위치 | 볼 수 있는 것 | 한계 |
|---|---|---|
| 네트워크(IDS) | 연결 시도 횟수, 평문 프로토콜의 실패 응답 코드 | SSH·HTTPS 등 암호화 프로토콜은 성공·실패 구분 불가 |
| 호스트 로그(HIDS·SIEM) | 계정 이름, 실패·성공 결과, 실패 사유 | 로그 수집이 안 되는 시스템은 확인 불가 |
암호화된 인증(SSH, HTTPS 로그인)은 네트워크에서 연결 수만 셀 수 있으므로, 성공 여부는 반드시 호스트 로그로 확인합니다.
탐지 로직이 보는 기준은 공격 패턴에 따라 다릅니다.
인증 이벤트 수집 (시간 창 내)
↓
[집계 기준 선택]
├─ 출발지 1 × 계정 1 × 실패 多 → 한 계정 대입 (Brute Force)
├─ 출발지 1 × 계정 多 × 계정당 실패 少 → 비밀번호 스프레이 (Spraying)
├─ 출발지 多 × 계정 1 × 실패 多 → 분산 대입
└─ 출발지 1 × 계정 多 × 서로 다른 조합 → 유출 계정 목록 대입 (Credential Stuffing)
↓ 임계치 초과
Alert
↓
[핵심 후속 조건] 같은 출발지·계정의 "실패 뒤 성공"이 있는가
| 패턴 | 세야 할 값 | 단순 "실패 N회" 규칙의 결과 |
|---|---|---|
| 한 계정 대입 | 출발지·계정별 실패 수 | 잘 탐지됨 |
| 스프레이 | 출발지별 고유 계정 수 | 계정당 실패가 적어 미탐 가능 |
| 분산 대입 | 계정별 실패 수(출발지 무관) | 출발지별 기준이면 미탐 |
| 계정 목록 대입 | 출발지별 고유 계정 수, 존재하지 않는 계정 비율 | 부분 탐지 |
네트워크 규칙에서 track 방향은 자주 헷갈리는 부분입니다.
530, HTTP 401)은 서버 → 클라이언트 방향 패킷입니다. 이 패킷의 목적지(dst)가 시도한 쪽이므로 track by_dst로 세야 "시도한 출발지별 실패 수"가 됩니다.track by_src를 씁니다.호스트 로그에서는 운영체제별로 기록 위치가 다릅니다.
| 환경 | 실패 기록 | 성공 기록 |
|---|---|---|
| Rocky(RHEL 계열) | /var/log/secure의 sshd "Failed password" | 같은 파일의 "Accepted password/publickey" |
| Ubuntu | /var/log/auth.log의 같은 문구 | 같은 파일 |
| Windows | 보안 이벤트 4625(로그온 실패) | 4624(로그온 성공), 계정 잠김 4740 |
평문 FTP 로그인 실패 응답을 세는 네트워크 규칙의 형식 예시입니다(Suricata·Snort 2 공통 표기, 값은 환경마다 다름).
# 형식 예시 — 서버 응답 "530"이 같은 클라이언트에게 60초 안에 5회를 넘으면 Alert
alert tcp $HOME_NET 21 -> any any (msg:"LOCAL FTP repeated login failures to one client"; flow:established,to_client; content:"530 "; depth:4; detection_filter:track by_dst, count 5, seconds 60; classtype:unsuccessful-user; sid:1001601; rev:1;)
호스트 로그에서 "실패 뒤 성공"을 확인하는 실습 예시입니다(본인 소유 실습 서버, 값은 환경마다 다름).
# Rocky
sudo grep -E "Failed password|Accepted " /var/log/secure | grep "203.0.113.70" | tail -20
# Ubuntu
sudo grep -E "Failed password|Accepted " /var/log/auth.log | grep "203.0.113.70" | tail -20
# 형식 예시 — 판단이 달라지는 로그 순서
Sep 30 03:10:01 web01 sshd[4101]: Failed password for admin from 203.0.113.70 port 51201 ssh2
Sep 30 03:10:04 web01 sshd[4101]: Failed password for admin from 203.0.113.70 port 51201 ssh2
Sep 30 03:12:40 web01 sshd[4188]: Accepted password for admin from 203.0.113.70 port 51377 ssh2
분석 방법 — 실패만 반복되면 "시도"이지만, 같은 출발지·같은 계정에 성공이 뒤따르면 계정 탈취 의심 사건으로 즉시 전환합니다. Wazuh 등 HIDS의 기본 규칙에도 sshd 실패 반복을 묶는 빈도 규칙이 있으며, 규칙 ID와 기준은 버전별로 확인합니다.
관제자가 반복 로그인 Alert를 볼 때 확인할 질문
반복 로그인 Alert
↓ 호스트 인증 로그에서 계정·결과 확인
성공 없음 → 출발지 차단 검토, 계정 잠김 여부 확인
성공 있음 → 계정 탈취 의심 → 세션 활동 확인·계정 조치 요청·에스컬레이션
↓
같은 출발지의 다른 서버 시도 검색 (방화벽·IDS)
오탐 주의: 비밀번호 변경 후 옛 비밀번호를 저장한 클라이언트(메일, 동기화 도구), 잘못 설정된 모니터링 계정은 짧은 주기의 반복 실패를 만듭니다. 출발지가 내부의 고정 장비라면 설정 오류를 먼저 확인합니다. 호스트 로그 기반 탐지 구조는 279. Host-based IDS를 참고합니다.
track by_dst, 연결 시도를 세는 규칙은 track by_src로 방향을 맞춥니다.