arrow_back필드 노트로 돌아가기
BLUE TEAM 게시됨 10 Jul 2026

모든 SOC 분석가가 알아야 할 KQL 기초

Microsoft Sentinel과 Defender에서 SOC 분석가들이 매일 사용하는 핵심 KQL 문법과 쿼리 패턴을 배우고 위협 사냥을 더 빠르게 수행하세요.

Kusto Query Language (KQL)는 Microsoft Sentinel과 Microsoft Defender에서 위협 사냥과 경고 분류의 근간입니다. SOC에서 일하고 있다면 KQL에 능숙한 분석가와 그렇지 않은 분석가의 차이는 "여기서 무슨 일이 있었나?"라는 질문에 빠르게 답할 수 있는지 여부입니다. 이것은 완전한 언어 레퍼런스가 아니라 근무 중에 지속적으로 사용되는 실제적인 부분들입니다.

SOC에서 KQL이 중요한 이유

KQL은 읽기 전용이며 대규모 로그 데이터셋을 빠르게 쿼리하도록 최적화되어 있습니다. Sentinel, Defender for Endpoint, Azure Monitor, Log Analytics 모두 KQL을 사용합니다. 한 번 배우면 같은 사고 모델로 제품 간에 이동할 수 있습니다: 테이블을 선택하고, 필터링하고, 출력을 정형화합니다. 모든 조사 — 피싱 분류, 횡적 이동 사냥, 거짓 양성 튜닝 — 쿼리로 시작됩니다.

파이프가 전부다

KQL 쿼리는 파이프라인으로 구성됩니다. 테이블로 시작해서 일련의 연산자를 통해 데이터를 전달하고, 각 연산자는 이전 결과를 필터링, 변환 또는 요약합니다:

SecurityEvent
| where EventID == 4625
| where TimeGenerated > ago(24h)
| summarize FailedLogons = count() by Account, Computer
| sort by FailedLogons desc

위에서 아래로 문장처럼 읽으세요: SecurityEvent 로그로 시작하고, 실패한 로그온만 유지하고 (4625), 지난 날로 제한하고, 계정/컴퓨터별 실패 횟수를 계산한 후 정렬합니다. 이러한 선형적 가독성이 SQL에 비해 KQL의 임시 사냥에서의 가장 큰 장점입니다.

외워야 할 핵심 연산자들

  • where — 주요 필터입니다. 비용이 많이 드는 작업 전에 데이터 량을 줄이기 위해 자주 사용하세요.
  • project — 특정 열을 선택하고 이름을 바꾸며, 출력에서 불필요한 데이터를 제거합니다.
  • extend — 기존 열을 버리지 않고 계산된 열을 추가하며, 문자열 파싱이나 조건 플래깅에 유용합니다.
  • summarizecount(), sum(), dcount() 또는 make_set()으로 데이터를 집계하며, 거의 항상 by와 함께 사용됩니다.
  • join — 테이블 간 상관관계를 만들며, 예를 들어 로그인 로그와 장치 인벤토리를 연결하여 관리되지 않는 장치 로그온을 찾습니다.
  • render — 쿼리 편집기에서 결과를 timechart 또는 barchart로 시각화하며, 급증을 발견하는 데 유용합니다.

시간 필터링을 제대로 하기

항상 파이프라인의 최대한 초반에 TimeGenerated (또는 테이블의 동등한 타임스탐프 열)로 필터링하세요. KQL 엔진은 시간 범위 필터 주변에서 크게 최적화되며, | where TimeGenerated > ago(7d)를 아래쪽이 아닌 위쪽에 배치하면 몇 초 안에 반환되는 쿼리와 바쁜 테넌트에서 시간 초과되는 쿼리의 차이가 날 수 있습니다.```kql SigninLogs | where TimeGenerated > ago(1h) | where ResultType != "0" | where UserPrincipalName has "@yourdomain.com"


## 문자열 매칭: has vs contains vs ==

흔한 실수는 모든 것에 `contains`를 기본으로 사용하는 것입니다. `has`는 전체 용어를 매칭하고 용어 인덱스를 사용하므로 대규모 테이블에서 훨씬 빠릅니다. `contains`는 단어 내 부분 도메인 조각처럼 부분 문자열 매칭이 필요할 때만 사용하고, EventID나 IPAddress처럼 구조화된 필드의 정확한 매칭에는 `==`를 사용하세요. 이 습관 하나가 `DeviceNetworkEvents`나 `CommonSecurityLog`처럼 높은 볼륨의 테이블에서 사냥을 눈에 띄게 빠르게 합니다.```kql
DeviceProcessEvents
| where ProcessCommandLine has "powershell"
| where ProcessCommandLine has_any ("-enc", "-EncodedCommand")

재사용 가능한 탐지 로직 구축하기

쿼리가 유용함을 증명하면 let으로 함수로 감싸거나 예약된 실행과 함께 Sentinel Analytics Rule로 저장하세요. 임계값 (예: 실패한 로그온 수)을 매개변수화하면 같은 로직이 테넌트 간에 확장되거나 처음부터 다시 작성할 필요 없이 튜닝됩니다. 이것이 일회성 사냥 쿼리가 SOC에 자동으로 페이지를 보내는 지속적인 탐지로 발전하는 방법입니다.

흔한 함정들

  • TimeGenerated 필터를 잊어서 느리고 비용이 많이 드는 전체 테이블 스캔을 야기합니다.
  • where보다 summarize를 사용하여 필터링되지 않은 데이터를 집계하도록 엔진을 강제합니다.
  • 테이블 조인 시 불일치하는 열 이름 — 항상 먼저 getschema로 스키마를 확인하세요.
  • contains를 과다하게 사용하여 인덱싱 이점을 건너뛰고 대규모 사냥을 느리게 합니다.

KQL은 중첩된 부쿼리보다 파이프라인으로 생각하는 분석가들에게 보상합니다. 모든 조사를 좁은 시간 범위와 특정 테이블로 시작하고 필요한 경우에만 확장하세요.

이것이 견고한 기초를 제공했다면 Korra Studio의 Blue Team과 Digital Forensics 섹션을 탐색하여 더 많은 실습 SOC 쿼리 설명과 탐지 구축 연습을 하세요.

AI 도움을 받아 작성했으며, Michal Pilch(CISSP), Korra Studio에서 검토 및 게시했어요.

더 나아가고 싶으신가요?

이것은 Korra Studio 나레지베이스의 한 노트예요. 플랫폼은 모든 주제를 1-to-1 멘토링과 함께 제공해요.

무료로 시작하기arrow_forward