IRQL 그래프 함수 – 쿼리 결과를 시각화로
IRQL 그래프 함수 제품군을 테이블 형식 결과에 적용합니다. KQL 또는 IRQL 쿼리와 사용자의 그래프 설명이 주어지면 Lift_To_Graph 매핑을 생성하고 Kusto Explorer에서 그래프를 시각화, 접기, 추출 또는 보강하는 데 필요한 저장된 그래프 함수만 구성합니다. 원본 쿼리는 IRQL을 사용할 필요가 없습니다.
범위 및 라우팅
| 요청 | 사용 |
|---|---|
| 제공된 KQL/IRQL 행을 아이콘으로 장식된 시각적 그래프로 변환 | 이 스킬: Lift_To_Graph + Graph_Render_View |
노드 접기 또는 Extract_Node_*, Enrich_Node_*, Enrich_Graph_* 적용 | 이 스킬 |
make-graph, graph-match, 최단 경로, 연결된 구성 요소, 그래프 모델 또는 스냅샷 사용 | azure-kusto-graph |
| 자연어로 논리적인 KQL/IRQL 분석 작성 | Kusto 또는 IRQL 쿼리 생성 스킬, 그 다음 이 스킬 |
요청이 시각화와 네이티브 그래프 분석을 혼합하는 경우, 리프트/렌더 부분에는 이 스킬을 사용하고 연산자 의미에는 azure-kusto-graph를 사용하십시오. 사용자가 네이티브 그래프 연산자를 요청하지 않는 한, 그래프 리프트 함수를 수동으로 구성된 엣지 우선 그래프로 대체하지 마십시오.
입력 계약
- 권장 입력: 테이블 형식 결과를 생성하는 작동하는 KQL/IRQL 쿼리와 원하는 노드, 엣지, 레이블, 아이콘, 추출, 보강 또는 접기에 대한 자연어 설명.
- 이 스킬은 자연어-투-KQL 또는 NL-투-IRQL 변환기가 아닙니다. 기존 쿼리 결과를 그래프 시각화로 변환합니다. 일반 NL-투-KQL 또는 NL-투-IRQL 변환은 전용 쿼리 생성 스킬(별도 제공)을 사용하십시오.
- 제공된 쿼리의 검색, 조인, 필터 및 집계를 유지하십시오. 그래프 매핑에 필요한 프로젝션이나 합성 ID만 추가하십시오.
- 기본 자연어 소스 요청은 하나의 알려진 테이블이나 IRQL
Get_*선택기에 명확한 열과 간단한 필터가 있는 경우에만 지원됩니다. 가정된 소스를 명시하고 조인, 스키마 또는 분석 논리를 임의로 만들지 마십시오. - 논리적인 쿼리 구성의 경우 먼저 별도의 Kusto/IRQL 쿼리 생성 스킬을 사용한 다음 이 스킬을 출력에 적용하십시오.
- 쿼리나 출력 스키마를 사용할 수 없고 소스가 간단하지 않은 경우, 매핑을 생성하기 전에 KQL 쿼리 또는 결과 열을 요청하십시오.
활성화 트리거
사용자가 다음과 같은 경우 이 스킬을 사용하십시오:
- KQL/IRQL 결과를 제공하고 IRQL 그래프 시각화 또는 매핑을 요청하는 경우
Lift_To_Graph,Graph_Render_View또는Graph_Fold_By_Property를 언급하는 경우- Kusto Explorer에서 아이콘으로 장식된 노드/엣지 매핑을 요청하는 경우
- 공유 속성별로 노드를 접거나 축소하려는 경우
Extract_Node_*,Enrich_Node_*또는Enrich_Graph_*를 통해 그래프 추출 또는 보강을 요청하는 경우
graph-match, 그래프 경로/구성 요소, 영구 그래프 또는 일반 make-graph 구성만을 위해서는 이 스킬을 활성화하지 마십시오. 이러한 작업은 azure-kusto-graph에 속합니다.
자연어-투-KQL/IRQL 변환기가 아닙니다. 입력은 일반적으로 그래프 시각화가 필요한 결과를 생성하는 작동하는 KQL 또는 IRQL 쿼리여야 합니다. 기본 NL 소스 요청은 간단한 단일 테이블/선택기 경우에만 작동합니다. 일반 NL-투-KQL 또는 NL-투-IRQL의 경우 전용 쿼리 생성 스킬(별도 제공)을 사용하십시오.
환경
- 클러스터:
https://kc7001.eastus.kusto.windows.net - 데이터베이스:
ValdyTimes,JoJosHospital(그래프 함수 사전 배포됨) - 렌더링: Kusto Explorer 데스크탑 앱 (make-graph 시각화 창)
- 도구:
kusto_query(Azure MCP 서버 통해)
함수 사전 점검
Lift_To_Graph 및 Graph_Render_View는 저장된 함수로, 내장 Kusto 연산자가 아닙니다. 대상 데이터베이스에 대해 리프트 파이프라인을 생성하거나 실행하기 전에 배포된 항목을 확인하십시오:
.show functions
| where Name in~ ("Lift_To_Graph", "Graph_Render_View", "Graph_Fold_By_Property")
| project Name
Lift_To_Graph및Graph_Render_View는 필수입니다.Graph_Fold_By_Property는 접기가 요청된 경우에만 필요합니다.Extract_Node_*,Enrich_Node_*또는Enrich_Graph_*함수를 사용하기 전에 확인하십시오. 사용자가 배포를 원하지 않는 한, 사용할 수 없는 경우 선택적 보강은 생략하십시오.- 필수 함수가 누락되었고 데이터베이스를 변경할 권한이 있는 경우, 배포 전에 사용자에게 확인을 요청하십시오. 그런 다음 references/DEPLOY_IRQL_FUNCTIONS.md의
.create-or-alter function정의를 사용하십시오. 관련.create-or-alter블록을 실행한 다음 사전 점검을 다시 실행하여 확인하십시오. - 변경 권한이 없는 경우, 누락된 함수를 사용자에게 알리고 수동 배포를 위해
references/DEPLOY_IRQL_FUNCTIONS.md를 참조하도록 안내하십시오.
IRQL 그래프 함수 제품군
Lift_To_Graph(T, mappingJson)
모든 테이블 형식 KQL 결과를 통합된 노드 + 엣지 테이블로 변환합니다.
입력: 모든 테이블 T + JSON 매핑 문자열.
출력: EntityType = "node" 또는 "edge"인 행, make-graph에 사용할 준비가 됨.
Graph_Render_View(T)
Lift_To_Graph 출력을 가져와 노드/엣지를 분할하고 make-graph를 호출하여 Kusto Explorer의 그래프 창을 엽니다.
Graph_Fold_By_Property(T, NodeType, PropertyName)
속성 값을 공유하는 주어진 유형의 노드를 단일 노드로 축소합니다. 엣지를 자동으로 다시 연결합니다.
그래프 추출 및 보강 함수
이것들은 대상 데이터베이스에 이미 배포되어 있어야 하는 추가 저장 함수입니다. references/DEPLOY_IRQL_FUNCTIONS.md에 번들로 포함되어 있지 않습니다. 파이프라인에 포함하기 전에 .show functions를 사용하여 가용성을 확인하십시오.
| 함수 | 연산 | 키 속성 |
|---|---|---|
Extract_Node_Email_Sender_Domain(T, displayName) | 노드 props에 Domain 추가 | EmailSender |
Extract_Node_Employee_Firstname(T, displayName) | 노드 props에 Firstname 추가 | Name |
Extract_Node_Event_Network_Domain(T, displayName) | 노드 props에 DomainName 추가 | Url |
Enrich_Node_Ip_Employee(T, displayName) | IP 노드에 직원 정보 추가 | ClientIp |
Enrich_Node_Username_Employee(T, displayName) | 사용자 노드에 직원 정보 추가 | Username |
Enrich_Node_Event_Authentication_Username(T, displayName) | 인증 컨텍스트 추가 | Username |
Enrich_Node_Ip_Domain(T, displayName) | DNS 도메인 추가 | ClientIp |
Enrich_Node_Ip_Event_NetworkOutbound(T, displayName) | 아웃바운드 이벤트 추가 | ClientIp |
Enrich_Graph_Ip_Employee(T, mappingJson) | 직원 노드로 그래프 확장 | ClientIp |
Enrich_Graph_Username_Employee(T, mappingJson) | 직원 노드로 그래프 확장 | Username |
Enrich_Graph_Event_Authentication_Username(T, mappingJson) | 인증 노드로 확장 | Username |
매핑 JSON 스키마
JSON 매핑에는 두 개의 배열이 있습니다: node_types 및 edges.
node_types[]
| 필드 | 필수 | 설명 |
|---|---|---|
type | 예 | 노드 유형 레이블 (예: "User", "Host", "IP") |
id | 예 | 노드 ID의 접두사; 일반적으로 유형과 동일 |
key | 예 | 값이 노드의 식별자가 되는 열 이름 |
props | 예 | 노드 속성으로 전달할 열 배열 |
defaults | 아니요 | null/빈 속성에 대한 대체 값 개체 |
defIcon | 아니요 | 이 노드 유형의 기본 아이콘 URL |
displayName | 아니요 | 표시 레이블에 사용할 열 (기본값: id) |
color | 아니요 | 색상을 가져올 열 |
size | 아니요 | 크기를 가져올 열 |
edges[]
| 필드 | 필수 | 설명 |
|---|---|---|
type | 예 | 엣지 유형 레이블 (예: "AuthenticatesTo", "SentEmail") |
source | 예 | {"id": "<prefix>", "type": "<NodeType>"} |
target | 예 | {"id": "<prefix>", "type": "<NodeType>"} |
props | 아니요 | 엣지 속성으로 전달할 열 배열 |
displayName | 아니요 | 엣지 레이블용 열 |
color | 아니요 | 엣지 색상용 열 |
아이콘 저장소
https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/에서 아이콘 사용:
- IP:
Public-IP-Addresses-(Classic).svg - 호스트/VM:
Virtual-Machine.svg - 사용자:
Users.svg - 이메일:
Mailbox.svg(또는azure-cds/command-1070-Mail.svg) - 프로세스:
App-Services.svg - 파일:
Storage-Accounts.svg - 알림:
Activity-Log.svg - 도메인:
DNS-Zones.svg
매핑 생성 규칙
제공된 쿼리 열과 사용자의 그래프 설명이 주어지면 다음을 수행하여 매핑 JSON을 생성하십시오:
- 엔터티 식별 -> 각각의 고유 명사가
node_type이 됩니다. - 관계 식별 -> 각 동사/전치사가
edge가 됩니다. - 열에 매핑 -> 제공된 쿼리에서 생성된 실제 열을 사용하고, 사용할 수 없는 열을 가정하지 마십시오.
- 방향 설정 -> 소스는 행위자, 대상은 행위의 대상입니다.
- 속성 추가 -> 조사와 관련된 열(타임스탬프, 결과, 해시)을 포함하십시오.
- 아이콘 할당 -> 엔터티 유형에 따라 위의 아이콘 세트에서 선택하십시오.
열 참조 (IRQL 통합 스키마)
| 엔터티 | 키 열 | 사용 가능한 Props |
|---|---|---|
| 사용자 | Username | Username, Name, Role, Email |
| 호스트 | Hostname | Hostname |
| IP | ClientIp | ClientIp |
| 이메일 메시지 | Subject | EnvTime, Subject, Verdict, Url |
| 발신자 | EmailSender | EmailSender, Domain |
| 수신자 | EmailRecipient | EmailRecipient |
| 프로세스 | ProcessName | EnvTime, ProcessName, ProcessCommandLine, ProcessHash |
| 파일 | Filename | EnvTime, Filename, Path, Sha256 |
| 도메인 | DomainName | DomainName |
| 인증 이벤트 | (합성 ID) | EnvTime, UserAgent, Result, Description |
함수 선택
- 제공된 KQL/IRQL 테이블 형식 파이프라인으로 시작합니다.
Lift_To_Graph(mapping)을 사용하여 그래프 엔터티를 만듭니다.- 요청되고 매핑된 키와 호환되는 경우에만
Extract_Node_*,Enrich_Node_*또는Enrich_Graph_*를 추가합니다. - 그룹화/축소가 요청된 경우에만
Graph_Fold_By_Property()를 추가합니다. - 시각적 출력을
Graph_Render_View()로 종료합니다. - 파이프라인에 대해 선택된 정확한 저장 함수를 사전 점검합니다.
파이프라인 패턴
// 1. 제공된 KQL 또는 IRQL 쿼리 유지
<input query>
// 2. 그래프로 리프트
| invoke Lift_To_Graph(<mapping_json>)
// 3. 선택적으로 그래프 엔터티 추출 또는 보강
| invoke <Extract_Node_* | Enrich_Node_* | Enrich_Graph_*>()
// 4. 요청 시 선택적으로 노드 접기
| invoke Graph_Fold_By_Property("<NodeType>", "<PropertyName>")
// 5. 렌더링
| invoke Graph_Render_View()
예제
추가 프롬프트 및 작업 예제는 references/EXAMPLES.md를 참조하십시오.
인증 그래프: IP -> AuthEvent -> User -> Host
입력 쿼리: Get_Event_Authentication_All | where Result == "Failed Login" | take 200
그래프 요청: "IP, 인증 이벤트, 사용자 및 호스트 표시; 결과별로 이벤트 접기."
let auth_mapping = '{"node_types":[{"type":"SrcIp","id":"SrcIp","key":"ClientIp","props":["ClientIp"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Public-IP-Addresses-(Classic).svg"},{"type":"Host","id":"Host","key":"Hostname","props":["Hostname"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Virtual-Machine.svg"},{"type":"User","id":"User","key":"Username","props":["Username"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Users.svg"},{"type":"AuthEvent","id":"AuthEvent","key":"AuthEventId","props":["AuthEventId","EnvTime","UserAgent","Result","Description"],"defaults":{"Result":"unknown"},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Activity-Log.svg"}],"edges":[{"type":"RequestsAuth","source":{"id":"SrcIp","type":"SrcIp"},"target":{"id":"AuthEvent","type":"AuthEvent"},"props":["EnvTime"]},{"type":"TargetsUser","source":{"id":"AuthEvent","type":"AuthEvent"},"target":{"id":"User","type":"User"},"props":["EnvTime"]},{"type":"AgainstHost","source":{"id":"AuthEvent","type":"AuthEvent"},"target":{"id":"Host","type":"Host"},"props":["EnvTime"]}]}';
Get_Event_Authentication_All
| extend AuthEventId = strcat(Username, "_", Hostname, "_", EnvTime)
| where Result == "Failed Login"
| take 200
| invoke Lift_To_Graph(auth_mapping)
| invoke Graph_Fold_By_Property("AuthEvent", "Result")
| invoke Graph_Render_View()
이메일 그래프: Sender -> Message -> Recipient
입력 쿼리: Get_Email_All | take 400
그래프 요청: "발신자-메시지-수신자 흐름을 시각화하고 평결별로 메시지 접기."
let mail_mapping = '{"node_types":[{"type":"EmailMessage","id":"Message","key":"Subject","props":["EnvTime","Subject","Verdict"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Media-File.svg"},{"type":"Sender","id":"Email","key":"EmailSender","props":["EmailSender"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-cds/command-1070-Mail.svg"},{"type":"Recipient","id":"Email","key":"EmailRecipient","props":["EmailRecipient"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-cds/command-1070-Mail.svg"}],"edges":[{"type":"SentBy","source":{"id":"Message","type":"EmailMessage"},"target":{"id":"Email","type":"Sender"},"props":["EnvTime","Verdict"]},{"type":"DeliveredTo","source":{"id":"Message","type":"EmailMessage"},"target":{"id":"Email","type":"Recipient"},"props":["EnvTime","Verdict"]}]}';
Get_Email_All
| take 400
| invoke Lift_To_Graph(mail_mapping)
| invoke Graph_Fold_By_Property("EmailMessage", "Verdict")
| invoke Graph_Render_View()
의심스러운 도메인 조사 (종단 간)
기본 소스 요청: "의심스러운 도메인에 대한 아웃바운드 네트워크 이벤트를 사용하고 직원 이름으로 보강된 IP-도메인 연결을 그래프로 표시하십시오."
이것은 제한된 폴백입니다: 하나의 알려진 선택기, 하나의 추출기 및 하나의 직접 필터.
let suspicious_domain_mapping = '{"node_types":[{"type":"IP","id":"IP","key":"ClientIp","props":["ClientIp"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/Public-IP-Addresses-(Classic).svg"},{"type":"Domain","id":"Domain","key":"Fqdn","props":["Fqdn"],"defaults":{},"defIcon":"https://raw.githubusercontent.com/benc-uk/icon-collection/master/azure-icons/DNS-Zones.svg"}],"edges":[{"type":"ConnectsTo","source":{"id":"IP","type":"IP"},"target":{"id":"Domain","type":"Domain"},"props":["EnvTime"]}]}';
let suspiciousDomains = dynamic(["evil.com", "phish.biz"]);
Get_Event_Network_Outbound_All
| where Fqdn has_any (suspiciousDomains)
| take 100
| invoke Lift_To_Graph(suspicious_domain_mapping)
// 사용 가능한 경우 Enrich_Node_Ip_Employee로 IP 노드 보강
| invoke Graph_Render_View()
배포된 함수 및 사용 가능한 열에 대한 자세한 내용은 references/DEPLOY_IRQL_FUNCTIONS.md 및 references/EXAMPLES.md를 참조하십시오.