AI·머신러닝 위협 탐지
- 페이지
- 3 / 5
- 강의 시간
- 90분
들어가며 — 통계과 규칙의 경계
SIEM 위에 올라가는 탐지 로직은 거의 항상 두 층 위에 산다. 한 층은 결정적 규칙(예: “특정 IP 차단리스트 매칭은 점수화 이전에 즉시 차단”), 다른 한 층은 통계적 신호(예: “이 계정의 1시간 로그인 실패 횟수가 평소 분포에서 z ≥ 2로 벗어났다”). 진짜 결정적 규칙은 점수 파이프라인을 우회해 즉시 조치한다 — 룰이 발화한 순간 점수와 무관하게 동작이 결정된다. M3에서 다루는 점수 모델은 그 우회 경로와 분리된 잔여 신호들의 가중합이다. 이 모델 안에서 룰 심각도는 하나의 가중 신호(+30) 일 뿐이고, 그 자체만으로는 자동종료(auto-close) 구간(0–40)에 머문다. M3에서는 점수 모델의 잔여 구간을 다룬다 — 진짜 결정적 규칙은 별도 경로로 이미 처리된 후다.
이 모듈의 학습 목표는 세 가지다.
- 통계 이상탐지가 무엇을 잘 잡고 무엇을 못 잡는지 — z-점수의 한계를 데이터로 체감한다.
- 가중 신호 합산으로 라우팅을 결정하는 패턴 — 임계값이 어디에 놓여야 하는지를 5가지 신호로 본다.
- LLM 트리아지가 들어가는 자리 — 점수만으로 끝내지 못하는 영역을 명확히 한다.
§A. 통계 이상탐지 — z-점수의 작동과 한계
z-점수는 “이 값이 평균에서 표준편차 몇 개 분량 떨어져 있는가”를 단일 숫자로 줄인 것이다. SIEM에서는 보통 하루 종일의 로그인 실패 횟수 같은 카운트에 적용한다. 임계값 z ≥ T로 정하면 T를 넘는 계정은 ANOMALY로 분류된다.
아래 계기판에서 슬라이더를 움직여 보라. 표본은 같은 날 8개 계정의 로그인 실패 횟수다(고정).
체감해야 할 것 — 임계값 1.5로 내리면 오탐이 늘어난다(정상 변동도 ANOMALY로 잡힘). 3.0으로 올리면 미탐이 늘어난다(명백한 침해도 정상으로 통과). 이게 정밀도-재현율 트레이드오프의 가장 단순한 형태다.
z-점수가 놓치는 것들
- 드리프트: 평균·표준편차 자체가 느리게 움직이면 기준선이 낡아진다. 오늘의 z가 2.4인 사건이 한 달 뒤엔 z = 1.2가 될 수 있다.
- 계절성: 같은 시각에 평소보다 5배 많은 실패가 발생해도 “평소 분포”가 그 시각의 분포를 포함하지 않으면 z가 낮게 나온다.
- 소수 표본: N이 작으면 단일 이상치가 평균·표준편차를 흔들어 자기 자신을 정상화한다.
이런 한계를 보완하려면 시간대별 기준선(hour-of-day baseline), 지수 가중 평균(EWMA), 또는 계정별 베이지안 사전 같은 보강이 필요하다. M3의 범위는 “z-점수가 무엇을 하는가”까지다 — 보강 기법은 후속 모듈에서 다룬다.
§B. 리스크 스코어링 — 5신호의 가중합
z-점수가 “이 계정이 이상한가”를 알려주면, 다음 단계는 “지금 무엇을 해야 하는가” 다. 실무에서는 단일 신호로 결정하지 않는다. 룰 심각도, IP 평판, z-점수 초과, 업무 외 시간, 핵심 자산 접근 — 이 다섯 신호를 가중합해서 점수화한다.
토글을 켜고 끄면서 합계와 라우트를 보라. 세 구간이 갈리는 지점이 있다.
- 0–40 자동 종료(auto-close): 노이즈 수준. 알림만 남기고 닫는다.
- 41–70 LLM 트리아지(llm-triage): 점수만으로 끝내기엔 애매한 영역. LLM이 1차 판정(
verdict·confidence·suggested_action)을 내고,verdict === "benign"이고confidence >= 0.9일 때만 사람 검토 없이 자동종료한다(판정 근거 로깅). 그 외(confidence < 0.9또는suspicious/malicious)는 사람 검토(analyst-review)로 에스컬레이션된다. - 71+ 즉시 에스컬레이션(escalate): 시간 벌 여유가 없다. 사람·SOAR가 즉시 개입한다.
경계값 40/41, 70/71은 정책적 결정이다. 이 값은 환경과 위협 모델에 따라 달라야 한다 — 40이 너무 낮으면 알림 피로가, 71이 너무 낮으면 에스컬레이션 피로가 생긴다.
경계값을 정하는 절차
- 과거 90일의 결정 로그(자동종료 vs 에스컬레이션)를 본다.
- 각 결정의 시점에 5신호 값을 되돌려 보고 점수 분포를 그린다.
- 두 분포의 교차를 가중치의 함수로 최적화한다.
- 경계값은 “0–40 / 41–70 / 71+” 같은 정수 라운딩으로 단순화하되, 교차 부근 사례는 별도 검토한다.
§C. LLM 트리아지 — 무엇을 맡기고 무엇을 안 맡기는가
§B의 “41–70” 구간은 통계만으로 답을 못 내는 영역이다. LLM은 이 구간의 1차 판정자다 — verdict(benign / suspicious / malicious) · confidence(0.0–1.0) · suggested_action을 낸다.
결정 권한은 일방적이지 않고 “공유”다 — 명백한 benign·고신뢰는 LLM 판정으로 자동종료한다.
그 외에는 사람 검토(analyst-review)로 에스컬레이션된다.
LLM에게 주는 입력은 항상 다음을 포함한다.
| 필드 | 유형 | 왜 필요한가 |
|---|---|---|
event_id | string | 판정 결과의 추적 키 |
subject | user / host / api-key | 주체의 자산 가치 평가 |
score | number (0–100) | LLM이 “이 점수가 왜 이 구간에 들어왔나”를 살피는 단서 |
signals | string[] | 어떤 신호가 켜졌는지의 라벨 목록 — 값이 아니라 의미 단위 |
context_window | number (sec) | 이 사건 전후 몇 초간의 로그 묶음 (예: ±300s) |
prior_decisions | summary[] | 같은 주체의 최근 7일 결정 — 반복 패턴 탐지 |
트리아지 출력 계약
LLM은 반드시 구조화 출력으로 답해야 한다. 자유 산문은 검토 비용을 키운다.
{
"verdict": "benign | suspicious | malicious",
"confidence": 0.0,
"rationale_bullets": ["string", "string"],
"suggested_action": "auto-close | analyst-review | escalate",
"needs_followup": ["string"]
}여기서 confidence는 LLM 자체의 확신도다. 이것은 §B의 점수와 다른 축이라는 점에 주의한다 — §B 점수는 “이 사건이 위험한가”의 양이고, confidence는 “LLM이 자기 답을 얼마나 믿는가”의 양이다. 방향(양성/악성)은 confidence가 아니라 verdict(benign / suspicious / malicious)가 정한다 — 높은 confidence는 benign 강함과 malicious 강함 양쪽을 모두 뜻할 수 있다.
구간별로 자동종료와 에스컬레이션은 다음과 같이 정해진다.
- 0–40(저위험) 구간은 LLM을 호출하지 않고 §B 점수만으로 자동종료한다. 이 구간은 통계적으로 노이즈 수준이라 LLM에 보내는 것 자체가 비용 낭비다.
confidence는 여기서 성립하지 않는다 — LLM을 부르지 않았기 때문이다. - 41–70(LLM 트리아지) 구간에서 LLM은
verdict와confidence를 낸다.verdict === "benign"이고confidence >= 0.9일 때만 사람 검토 없이 자동종료한다(판정 근거 로깅). 그 외 —confidence < 0.9이거나,verdict가suspicious/malicious인 경우 — 는 사람 검토(analyst-review)로 에스컬레이션된다. 이 임계값0.9는 교육용 예시이며, 조직의 위험 허용도에 따라 튜닝한다. - 71+(고위험) 구간은
confidence와verdict와 무관하게 항상 사람에게 에스컬레이션된다. LLM이 “이건 무해”라고 강하게 확신하더라도 점수가 71+인 사건은 자동종료로 보내지 않는다.
한 문장: “높은 confidence는 71+ 고위험 사건의 자동종료를 정당화하지 않으며, 41–70에서 자동종료가 되려면 verdict === 'benign'이 함께 성립해야 한다.”
프롬프트는 짧게 — 컨텍스트는 입력으로
LLM에게 “너는 보안 분석가다” 같은 역할 지시문을 길게 붙이는 것은 토큰 낭비다. 대신 컨텍스트를 입력 페이로드로 직접 넣고, 모델은 그 입력을 읽고 스키마대로 답만 한다. 다음은 그 골격이다.
SYSTEM
You are a security triage assistant. Read the JSON payload and respond in the exact schema below. Do not invent fields.
USER PAYLOAD
<event_id, subject, score, signals, context_window, prior_decisions>
OUTPUT SCHEMA
{
"verdict": "benign | suspicious | malicious",
"confidence": 0.0,
"rationale_bullets": ["..."],
"suggested_action": "auto-close | analyst-review | escalate",
"needs_followup": ["..."]
}실무 함정 — 다섯 가지
| 함정 | 왜 함정인가 | 회피 패턴 | 심각도 |
|---|---|---|---|
| 신호 과잉 | 모든 신호를 켜고 “이게 침해냐?“를 묻는 호출 — LLM이 아무 신호나 근거로 답하게 된다. | 점수 구간(41–70)에 들어온 사건 만 LLM으로 보낸다. | 중 |
| 컨텍스트 부재 | “이 사용자 평소 행동” 없이 단발 이벤트만 본다 — 정상 행동이 침해로 판정되거나 그 반대. | prior_decisions·context_window를 항상 채워 보낸다. | 상 |
| 신뢰도 미기록 | LLM 답의 confidence를 로그에 남기지 않으면 “왜 그 답이 나왔는가”를 사후 추적 불가. | 모든 트리아지 결정에 confidence를 저장하고, confidence >= 0.9 이면서 verdict === "benign" 일 때만 자동종료한다. 임계 미만(confidence < 0.9) 또는 suspicious/malicious는 사람 검토로 에스컬레이션된다. | 중 |
| 임계값 고착 | 한 번 정한 40/70을 연 단위로 안 건드리면 위협 환경 변화에 둔해진다. | 분기마다 분포를 다시 보고 경계값 재조정. | 중 |
| 룰과 ML 충돌 | 결정적 룰(예: “특정 IP는 무조건 차단”)과 z-점수 결과가 갈릴 때 어떤 쪽을 따른다? | 룰 우선 원칙을 명문화. ML은 “이 룰을 면제할 만한가”를 묻는 보조로만 사용. | 상 |
정리
- z-점수는 “평소 분포에서 얼마나 벗어났나”의 1차 신호. 임계값 1.5↓ 오탐↑ / 3.0↑ 미탐↑.
- 리스크 스코어는 가중 신호의 합. 0–40 자동종료 / 41–70 LLM 트리아지 / 71+ 에스컬레이션. 경계값은 정책 결정.
- LLM 트리아지는 §B의 “애매한 구간”(41–70)에서 1차 판정(
verdict·confidence·suggested_action)을 맡는다. 자동종료는verdict === "benign"이고confidence >= 0.9일 때만 적용되며, 그 외에는 사람 검토(analyst-review)로 에스컬레이션된다. 71+ 구간은 점수만으로 항상 사람 에스컬레이션이다. - 함정 다섯: 신호 과잉 · 컨텍스트 부재 · 신뢰도 미기록 · 임계값 고착 · 룰과 ML 충돌.