시리즈AI를 보안 분석에 붙여 본 기록3편 · 공개 5편
세션을 하나씩 보던 탐지기를 65개 전체로 넓혔더니 다른 답이 나왔다
K-Means와 DBSCAN으로 공격 세션을 묶어 개별 판정을 통과한 저속 세션 15개를 한 캠페인으로 드러내고, 실루엣 점수 1등 설정이 65개 중 49개를 노이즈로 버리는 과정을 확인한 뒤, 5분 시간 창의 단계 판정과 MITRE ATT&CK 매핑에서 무엇을 정정했는지 정리한 실습 기록.
목차 12
IP 하나씩 보던 탐지기를 세션 전체로 넓히면
앞 단계의 탐지기는 IP를 하나씩 평가했다. 그래서 각 세션이 충분히 느리고 작으면 초저속극소량 전략이 정상으로 분류됐다(단일 모델의 정상 판정이 뜻하는 것). 사건 하나에 점수를 매기는 방법으로는 사건 여러 개가 서로 닮았다는 사실을 볼 수 없기 때문이다.
관찰 단위를 65개 세션 전체로 넓히고 여섯 개 행동 특징을 DBSCAN으로 비교하자, 개별 판정을 통과한 유사 세션 15개가 하나의 합성 캠페인으로 묶였다. 이상 점수를 계산하는 대신 세션끼리의 거리를 계산했으니 판정 방법 자체가 바뀐 것이고, 그래서 같은 데이터에서 다른 답이 나왔다.
클러스터링이 공격을 확정한 것은 아니다. 단일 사건의 이상 점수와 여러 사건 사이의 유사성은 서로 다른 증거이고, 두 관점을 연결했을 때 저속·분산 행동의 조사 우선순위가 올라간 것이다.
군집화와 이상 탐지는 다른 질문에 답한다
| 관점 | 군집화 | 이상 탐지 |
|---|---|---|
| 주된 질문 | 어떤 세션들이 서로 비슷한가? | 어떤 세션이 기준 분포와 다른가? |
| 대표 출력 | 군집 레이블과 군집 프로파일 | 이상 점수와 정상·이상 판정 |
| 보안 활용 | 캠페인·행동 유형 발견 | 조사 후보의 우선순위 결정 |
| 주의점 | 군집 번호 자체에는 의미가 없음 | 이상이 곧 공격은 아님 |
클러스터링은 정답 라벨 없이 비슷한 세션을 묶는 비지도 학습이라, 같은 군집에 속한다는 것은 선택한 특징과 거리 기준에서 가깝다는 뜻까지다. 의미는 분석가가 원본 로그와 자산 맥락을 보고 붙인다.
DBSCAN이 붙이는 노이즈 레이블 -1도 판정이 아니다. 밀도 조건을 만족하는 군집에 들어가지 못했다는 뜻이고, 여기에는 단발성 공격과 희귀한 정상 활동이 함께 들어간다. 버리지 않고 별도 조사 대상으로 남긴다.
K-Means는 중심을 옮기고 DBSCAN은 밀도를 잇는다
K-Means는 K개의 중심점을 초기화하고, 각 표본을 가장 가까운 중심점에 할당하고, 할당된 표본의 평균으로 중심점을 갱신하는 과정을 반복해 군집 내 제곱거리 합인 Inertia를 줄인다. 빠르고 중심점으로 결과를 설명하기 쉽지만 K를 미리 정해야 하고 모든 표본을 어느 군집엔가 배정한다. 유클리드 거리와 평균 중심을 쓰므로 크기와 분산이 비슷한 볼록한 군집에 맞고, 길쭉한 모양이나 노이즈가 많은 데이터에서는 중심이 끌려간다. 초기화에 따라 결과가 달라지므로 random_state와 n_init을 함께 기록한다.
DBSCAN은 밀도가 높은 영역을 연결해 군집을 만들고 밀도 조건에서 벗어난 표본을 노이즈로 분리한다.
| 요소 | 의미 | 값을 바꿀 때의 경향 |
|---|---|---|
eps |
한 표본의 이웃으로 볼 최대 거리 | 커지면 군집이 합쳐지고 노이즈가 줄기 쉬움 |
min_samples |
핵심점이 되기 위한 eps 반경 내 최소 표본 수 |
커지면 밀도 기준이 엄격해져 노이즈가 늘기 쉬움 |
| Core | 자기 자신을 포함해 min_samples 조건을 만족하는 점 |
군집의 밀도 중심 |
| Border | 핵심점의 이웃이지만 스스로 핵심점은 아닌 점 | 군집 경계 |
| Noise | 어느 군집에도 연결되지 않은 점 | 레이블 -1, 별도 검토 필요 |
군집 개수를 입력하지 않아도 되고 비볼록한 모양과 노이즈를 다룰 수 있는 대신, 군집마다 밀도가 크게 다르면 하나의 eps로 모두 담기 어렵고 차원이 높아질수록 거리의 구분력이 약해진다. 운영에 붙일 때 걸리는 지점이 하나 더 있다. scikit-learn의 DBSCAN은 새 표본에 대한 일반적인 predict를 제공하지 않는 전이적 군집화라, 배치마다 다시 학습하면 군집 번호와 구성이 바뀐다. 어제의 군집 2와 오늘의 군집 2는 같은 것이 아니다.
Scaling 기준을 고르는 것도 결과를 고르는 일이다
이 실습은 세션 하나를 여섯 개 특징으로 표현했다.
req_per_min: 분당 요청 수payload_count: 페이로드 개수avg_gap_sec: 평균 요청 간격special_ratio: 특수문자 비율unique_paths: 고유 경로 수status4xx_ratio: 4xx 응답 비율
두 알고리즘 모두 거리를 계산하므로 단위가 큰 특징이 결과를 지배하지 않게 Scaling 기준을 정해야 한다. 실습은 StandardScaler로 각 특징을 평균 0, 표준편차 1에 맞췄다. 다만 StandardScaler의 평균과 표준편차는 이상치에 끌려가므로, 운영 로그에서는 분포를 먼저 확인하고 RobustScaler나 로그 변환, 도메인 기반 가중치를 비교한다. 기준 모델을 새 데이터에 적용할 때는 참조 데이터에 맞춘 변환기를 저장해 두고 같은 기준으로 transform한다. 새 배치에서 다시 fit하면 기준선 자체가 데이터를 따라 움직인다.
실루엣 점수 1등이 65개 중 49개를 노이즈로 버렸다
파라미터를 고르는 방법마다 답하는 질문이 다르다.
| 방법 | 용도 | 한계 |
|---|---|---|
| Elbow | K-Means의 Inertia 감소가 완만해지는 K 후보 확인 |
꺾이는 지점이 모호할 수 있음 |
| Silhouette | 군집 내부 응집도와 군집 간 분리도 확인 | 보안 의미와 노이즈 보존 여부를 평가하지 않음 |
| k-distance | DBSCAN의 eps 후보 탐색 |
눈에 띄는 굴곡이 없거나 밀도가 다르면 불안정 |
| ARI | 정답 라벨과 군집 결과의 일치 정도 비교 | 신뢰할 수 있는 정답 라벨이 있어야 함 |
실루엣은 -1에서 1 사이이고 높을수록 조밀하고 잘 분리된 군집을 뜻한다. 파라미터 탐색에서 실루엣이 가장 높았던 설정은 0.871이었는데, 그 설정은 세션 65개 가운데 49개를 노이즈로 처리했다. 실루엣을 노이즈를 뺀 표본만으로 계산하면 애매한 표본을 많이 버릴수록 점수가 올라간다. 전체의 4분의 3을 군집 밖으로 밀어낸 설정이 채점표에서 1등이 된 셈이다.
그래서 점수 하나로 고르지 않고 군집 수, 노이즈 수, 중요 캠페인이 살아남았는지, 분석가가 각 군집을 설명할 수 있는지를 같이 본다.
PCA도 같은 자리에서 조심할 도구다. 고차원 특징을 2차원으로 투영해 그림으로 보여 주지만, 설명된 분산 비율이 높아도 원래 거리와 보안 의미를 그대로 보존한다는 보장은 없다. 실습에서도 군집화 자체는 원래 6차원 특징으로 했고 PCA는 결과를 보기 위해서만 썼다. 군집 이름은 평균 프로파일과 z-score로 튀는 특징을 확인한 뒤 사람이 근거와 함께 붙인다.
세션 평균 하나로 합치면 시간에 따라 바뀐 행동이 사라진다
세션 전체를 평균 하나로 접으면 정찰에서 익스플로잇 시도로 넘어가는 과정이 평탄해진다. 시계열 흐름 분석은 로그를 시간 창으로 나누고 각 창의 요청량, 경로 다양성, 내용 특징과 응답 변화를 비교해 정찰 의심 -> 익스플로잇 시도 의심 -> 후속 침해 의심 같은 진행 상태를 만든다. 이 상태 이름은 조사 편의를 위한 내부 판정이고, 하나의 웹 로그 신호만으로 실제 공격 단계나 침해 성공을 확정하지 않는다.
실습은 IP별 로그를 5분 고정 구간으로 나누고 네 특징을 계산했다.
| 특징 | 관찰 목적 | 주의점 |
|---|---|---|
req_count |
구간 내 활동량 | 저속 공격은 짧은 창에서 희석될 수 있음 |
unique_paths |
탐색 범위 | 정상 크롤러·모니터링도 값이 클 수 있음 |
special_mean |
입력 내용의 특수문자 비율 | 일반 쿼리와 인코딩 데이터도 영향을 줌 |
error_rate |
4xx 이상 응답 비율 | 응답 성공 여부와 공격 성공 여부는 다름 |
고정 창은 구현이 단순한 대신 경계 양쪽으로 나뉜 행동을 두 창 모두에서 작아 보이게 만든다. 운영에서는 sliding·rolling window, 세션 경계, 사용자·계정·디바이스 식별자를 함께 보고 창 크기에 따라 판정이 어떻게 달라지는지 기록한다.
오류율이 내려갔다고 침해 성공은 아니다
실습 코드는 특수문자 비율이 높은 상태에서 오류율이 0.25 아래로 내려가면 성공으로 분류한다. 합성 데이터의 라벨을 재현하기 위한 휴리스틱이고, HTTP 200 응답이나 오류율 감소만으로 취약점 악용 성공을 확정할 수는 없다. 공격자가 존재하는 경로를 정확히 찍어 요청해도 오류율은 내려간다.
운영에서는 이 상태를 성공 의심 또는 후속 침해 의심으로 적고 다음 증거로 확증한다.
- 웹 서버·애플리케이션 프로세스에서 비정상 자식 프로세스가 생성됐는가?
- 파일 생성·변조, 계정 변경 또는 권한 변화가 있었는가?
- 평소 없던 외부 연결이나 데이터 전송이 발생했는가?
- 애플리케이션·WAF·EDR·인증 로그의 시간 관계가 일치하는가?
- 동일 요청을 허가된 테스트 환경에서 재현했는가?
조치 우선순위도 휴리스틱 하나로 자동 확정하지 않고 신뢰도, 자산 중요도, 영향과 증거 수준을 함께 넣어 정한다.
ATT&CK ID를 붙이기 전에 공식 전술을 확인해야 했다
MITRE ATT&CK은 관측한 행위를 공통 언어로 적기 위한 분류다.
| 구분 | 질문 | ID 예시 |
|---|---|---|
| Tactic | 공격자가 왜 이 행동을 하는가? | TA0043 Reconnaissance |
| Technique | 목적을 어떻게 달성하는가? | T1595 Active Scanning |
| Sub-technique | 기법을 어떤 세부 방식으로 수행하는가? | T1595.001 Scanning IP Blocks |
실습 코드의 매핑을 공식 Technique 페이지와 대조하면서 네 곳을 정정했다.
| 관측 또는 코드 매핑 | 검증된 해석 |
|---|---|
T1190을 TA0002 Execution으로 연결 |
T1190 Exploit Public-Facing Application의 공식 전술은 TA0001 Initial Access |
T1595를 TA0007 Discovery로 연결 |
T1595 Active Scanning과 하위 기법의 공식 전술은 TA0043 Reconnaissance |
낮은 오류율을 TA0001 성공으로 자동 연결 |
응답 코드만으로 Initial Access 성공을 확정할 수 없으므로 판정 보류 후 후속 증거 확인 |
| 전략 이름을 프로파일 임계값으로 ATT&CK에 자동 매핑 | 교육용 번역 규칙이며 실제 매핑은 원본 행위와 대상·단계를 검토해야 함 |
두 번째 줄이 특히 헷갈리기 쉬운 자리다. 외부 대상의 IP 대역 탐색은 T1595.001, 취약점 탐색은 T1595.002 후보이고, 이름이 비슷한 TA0007 Discovery는 침투 후 내부 시스템과 계정을 조사하는 단계라 외부 Active Scanning과 구분한다. T1190은 페이로드가 실제 공개 애플리케이션 취약점을 악용했다는 근거가 있을 때 붙인다.
ATT&CK 자체는 위험도나 침해 확률을 부여하지 않는다. 리포트에 CRITICAL이나 HIGH를 적으려면 조직의 별도 심각도 정책과 그 근거를 함께 밝혀야 한다.
커버리지 차트가 보여 주는 것은 사전의 내용이다
실습이 그리는 커버리지 차트는 하드코딩된 전략-기법 사전에 어떤 전술 ID가 들어 있는지를 센 것이다. 사전에 항목을 추가하면 차트는 채워지지만 탐지 능력은 그대로다. 실제 커버리지는 다음을 하나씩 확인해야 나온다.
- 해당 기법을 관측할 데이터 소스가 수집되고 있는가?
- 탐지 규칙이나 분석 모델이 활성화되어 있는가?
- 알려진 테스트 사례를 탐지하고 증거를 보존하는가?
- 우회·저속·분산 조건에서도 탐지되는가?
- 경보가 분석가에게 전달되고 대응 절차로 연결되는가?
재현 결과
| 실험 | 결과 | 해석 |
|---|---|---|
| K-Means K 실험 | K=3, Silhouette 0.891 |
생성된 3개 덩어리와 일치 |
| DBSCAN 공격 세션 | eps=0.8, min_samples=3, 군집 4개, 노이즈 5개 |
4개 합성 전략과 5개 단발성 표본을 분리 |
| DBSCAN 기본 실험 | 군집 3개, Core 54개, Border 5개, Noise 4개 | 밀도 기반 점 유형 확인 |
| K-Means vs DBSCAN | 초승달 ARI 0.446 대 0.952, 노이즈 데이터 0.453 대 0.978 |
특정 합성 구조에서 DBSCAN이 유리 |
| 파라미터 탐색 | 최고 Silhouette 0.871 설정이 65개 중 49개를 노이즈로 처리 |
점수 1등이 보안상 최적은 아님 |
시계열 쪽은 다음과 같다.
| 항목 | 결과 |
|---|---|
| 입력 | 합성 요청 1,487건, IP 4개 |
| 시간 창 | 5분 고정 구간 36개 |
| 판정 대상 | 표본 부족으로 보류한 2개를 제외한 34개 |
| 내부 라벨 정확도 | 합성 규칙과 동일한 데이터 생성 조건에서 100% |
| 통합 분석 | 세션 65개, 캠페인 4개, 노이즈 5개, Silhouette 0.753 |
| 전체 코드 검증 | 비대화형 그래프 환경에서 16개 단계 모두 정상 종료 |
정확도 100%는 데이터를 만든 규칙과 판정 임계값이 맞물려 나온 값이다. 판정 임계값을 그 생성 규칙에 맞춰 두었으니 높게 나오는 쪽이 당연하다. 독립적인 실제 로그나 외부 검증 세트의 성능으로 옮겨 읽지 않는다. ARI 비교도 초승달·노이즈 같은 특정 합성 구조에서 얻은 결과라 DBSCAN이 일반적으로 낫다는 근거로는 쓸 수 없다.
다음에 돌릴 때 확인할 것
- 군집 레이블 숫자를 공격 유형으로 고정하지 않고 실행할 때마다 프로파일을 다시 확인한다.
- 노이즈를 삭제하지 않고 단발성 고위험 사건과 희귀 정상 활동을 분리해 조사한다.
eps,min_samples, Scaling 방식, 특징 목록과 데이터 기간을 결과와 함께 기록한다.- 내부 단계 이름과 ATT&CK Tactic을 일대일로 자동 치환하지 않는다.
- 창 크기, 임계값, 보류 조건과 단계 전환 근거를 리포트에 남긴다.
직접 돌려서 확인한 범위는 합성 데이터에 대한 클러스터링·시계열 실습 16개 단계와 ATT&CK 매핑 대조까지다. 시간대·자산·서비스별 정상 변동이나 데이터 드리프트가 있는 실제 트래픽에서는 재 보지 않았고, sliding window로 바꿨을 때 단계 판정이 어떻게 달라지는지도 확인하지 않았다. RobustScaler와 로그 변환을 비교해 보자고 적어 두었지만 실제로 바꿔 돌린 것은 StandardScaler 하나다.