SPL에서 YARA-L 2.0으로 전환

다음에서 지원:

이 가이드는 Splunk 검색 처리 언어 (SPL)에 이미 익숙한 사용자를 대상으로 합니다. Google Security Operations 내에서 검색, 대시보드, 감지 규칙을 빌드하는 핵심 언어인 YARA-L 2.0을 간략하게 소개합니다.

YARA-L 2.0 구조 이해하기

YARA-L 2.0은 Google SecOps 전반에서 사용되는 통합 쿼리 언어로, 강력한 위협 검색, 실시간 대시보드 빌드, 수집되는 모든 엔터프라이즈 로그 데이터에 대한 충실도 높은 감지 규칙을 만드는 데 사용됩니다.

이 언어는 Google SecOps 감지 엔진과 함께 작동하며 대량의 데이터에 대해 위협 요소 및 기타 이벤트를 검색할 수 있게 해줍니다.

SPL과 YARA-L의 기본 구조 차이

SPL은 파이프 (|) 문자로 연결된 일련의 명령어를 사용하는 반면 YARA-L은 섹션 기반입니다. events, outcome, condition과 같은 고유한 섹션을 사용하여 검색, 감지 또는 시각화하려는 패턴을 설명하는 쿼리를 정의합니다.

다음 표에서는 SPL과 YARA-L 간의 기본 구조를 비교합니다.

기능 SPL (절차적) YARA-L (선언적)
핵심 개념 명령어 파이프라인을 사용하여 데이터 스트림을 단계별로 변환합니다. 보안 및 운영 데이터 스트림에 조건과 변환의 멀티파트 구조를 분석하고 적용하여 위협을 식별하고 유용한 통계를 추출합니다.
Dataflow 절차적 한 명령어의 결과가 다음 명령어의 입력으로 파이프됩니다. 대규모로 패턴을 최적으로 처리하고 상관관계를 지정하는 선언적 구조 효율성을 고려할 필요가 없습니다.
이벤트 상관관계 join, transaction, stats와 같은 명시적 명령어를 사용합니다. 여러 이벤트를 정의하고 쿼리 로직 내의 공통 필드를 기반으로 이벤트를 상호 연관시켜 내장됩니다.
기간 정적 검색 창 (예: last 60m)으로 처리됩니다. 새 검색은 새 요청입니다. 쿼리 내에 정의된 연속 슬라이딩 시간 창으로 처리됩니다 (예: over 5m).
구문 명령어 기반 (예: index=web) 간결하고 논리적이어야 합니다 (예: metadata.event_type= "USER_LOGIN").

쿼리의 구체적인 구조

YARA-L은 쿼리에 특정 구조를 적용하며, 이는 SPL의 순차적 파이프 명령어와 다릅니다. SPL은 명령어를 연결하여 결과를 빌드하는 반면 YARA-L은 별도의 섹션에서 쿼리의 다양한 측면을 정의합니다.

명령어 작업 필수 | 선택사항
meta 작성자, 설명, 심각도와 같은 규칙의 설명 메타데이터를 설정합니다. 규칙에만 필요합니다.
events 이벤트를 정의하고 필터링합니다. 필수 (질문의 핵심 논리).
match 이벤트를 기준으로 그룹화하고 시간 범위 (예: by 5m)를 지정할 수 있습니다. (선택사항) 다중 이벤트 상관관계 쿼리에만 필요합니다.
outcome 주요 측정항목을 계산하고 유용한 정보를 얻습니다. (선택사항)
condition 결과가 적용되는지 확인하기 위해 쿼리 변수 기준을 평가합니다 (예: #event >5). 규칙에만 필요합니다. 검색 및 대시보드에서는 선택사항입니다.
dedup 키 변수 (예: target.user.userid, target.ip>, principal.hostname)를 기준으로 그룹화하여 중복 이벤트를 삭제합니다. (선택사항)
order 특정 필드 (예: asc)로 정의된 수집된 이벤트 결과를 정렬합니다. (선택사항)
limit 쿼리에서 반환되는 최대 이벤트를 제한합니다. (선택사항)

SPL 및 YARA-L의 일반 명령어

YARA-L 섹션 구조를 사용하면 SP에서 찾을 수 있는 동일한 일반 명령어를 사용할 수 있습니다. 이 섹션에서는 유사점과 차이점을 간략하게 설명합니다.

SPL search 명령어 = YARA-L events 섹션

SPL의 search 명령어는 YARA-L의 events 섹션과 같습니다. events 섹션에서는 이벤트와 초기 필터링 방법을 정의합니다. 다른 섹션 (예: match 또는 outcome)은 선택사항이지만 events 섹션은 모든 규칙에 필수적입니다.

예를 들면 다음과 같습니다.

metadata.event_type = "USER_LOGIN"

또는

principal.hostname != "" AND metadata.event_type = "NETWORK_CONNECTION"

규칙 (및 고급 쿼리)의 events 섹션에서 이벤트 변수를 사용하여 로직을 간소화합니다.

이벤트 변수는 특정 기준에 부합하는 특정 이벤트 또는 이벤트 그룹을 나타내는 필터의 논리적 그룹화 역할을 합니다.

예를 들어 $e와 같은 이벤트 변수를 정의하려면 쿼리의 events 섹션에서 관련 이벤트와 필터의 접두사로 사용하세요. 그런 다음 쿼리의 다른 섹션 (예: match 또는 outcome)에서 해당 변수를 사용하여 특정 이벤트 그룹과 해당 데이터 필드를 참조할 수 있습니다.

이벤트 변수의 가장 일반적인 적용은 감지 규칙 내에 있습니다. 다음 예에서는 규칙에서 이벤트 변수 ($e)를 사용하여 이벤트를 그룹화하고 하루 동안 사용자의 로그인 실패 횟수를 찾는 방법을 보여줍니다. 그런 다음 정의된 임계값을 초과하면 규칙이 트리거됩니다.

규칙 예시에서 각 이벤트는 이벤트 변수 ($e)로 정의됩니다. 또한 $e 변수는 규칙 메타데이터를 정의된 이벤트에 다시 연결하기 위해 metadata.id에서 참조됩니다.

rule DailyFailedLoginAttempts {
 meta:
   author = "Alex"
   description = "Detects a high number of failed login attempts for a single user within a day."

events:
   // Alias for each event
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $e.principal.user.userid != ""
   $userid = $e.principal.user.userid

match:
   // Group events by principal.user.userid within a 24-hour window
   $userid over 1d

outcome:
   // Count the number of unique event IDs for each user per day
   $daily_failed_login_count = count($e.metadata.id)

condition:
   // Trigger a detection if the daily failed login count exceeds a threshold
   // You should adjust this threshold based on your environment's baseline.
   #e > 0
}

규칙이 트리거되는지 확인하려면 그룹화된 이벤트 수를 확인해야 하는 경우가 많습니다. 이벤트 변수를 사용하여 condition 섹션에서 최소 개수를 지정할 수 있습니다. 예를 들어 조건 (#e > 0)은 기준과 일치하는 이벤트가 하나 이상 있는지 확인합니다.

SPL eval 명령어 = YARA-L outcome 섹션

eval 명령어는 검색 결과에서 필드 값을 조작하고 정의하는 데 사용되는 기본적인 SPL 함수입니다.

  • 목적: 새 필드 값을 계산하고 정의합니다.
  • 기능: 수학, 문자열 또는 불리언 표현식을 평가합니다.
  • 결과: 평가 결과로 새 필드가 생성되거나 기존 필드의 값이 덮어쓰여집니다.
  • 연결: 쉼표를 사용하여 여러 표현식을 연결할 수 있습니다 (예: | eval A=1, B=A+1).
  • 순차 처리: 체인의 표현식은 순차적으로 처리되므로 후속 계산에서 이전 표현식에 의해 생성되거나 수정된 필드를 참조하고 이를 기반으로 빌드할 수 있습니다.

다음 표 (및 이후)의 예에서는 이 명령어 구조를 설명합니다.

기능 설명 YARA-L 예시
부울 연산자 eventscondition에서 사용됩니다. 조건 섹션에서 사용을 참고하세요.

metadata.log_type != "" or
metadata.event_type = "NETWORK_DNS"
      
계산된 필드 outcome 섹션에서 사용됩니다.

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = cast.as_int(network.sent_bytes)
  
동적 필드 이름 생성 outcome 섹션에서 사용됩니다. SPL과 YARA-L 비교의 예시를 참고하세요.

예: 계산 결과를 포함하는 새 필드 만들기

YARA-L을 사용하여 각 이벤트에 새 필드 bytes를 만듭니다. 전송된 bytes 필드 값과 수신된 bytes 필드 값을 더하여 바이트를 계산합니다.

 metadata.event_type = "SCAN_NETWORK"
 principal.hostname != ""
 $host = principal.hostname

match:
   $host

outcome:
   $bytes = cast.as_int(sum(network.sent_bytes))

예: 두 필드의 값 연결

마침표 (.) 문자를 사용하여 first_name 필드의 값을 last_name 필드의 값과 연결합니다. 따옴표 ("")를 사용하여 두 필드 사이에 공백 문자를 삽입합니다. 연결할 때 실제 값과 관계없이 값이 문자열로 읽힙니다.

SPL에서 쿼리는 다음과 유사합니다.

| eval full_name = first_name+" "+last_name

YARA-L에서 검색어는 다음과 유사합니다.

principal.user.first_name = $first_name
principal.user.last_name = $last_name

outcome:
  $full_name = strings.concat(principal.user.first_name = $first_name
  principal.user.last_name = $last_name

outcome:
   $full_name = strings.concat($first_name, " ", $last_name))

실패한 로그인 쿼리 예시를 사용하여 다음 예시에서는 이벤트 및 자리표시자 변수를 모두 사용하여 서로 10분(10m) 이내에 로그인에 5회 이상 실패한 사용자를 찾을 수 있습니다.

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
target.user.userid = $userid

match:
  $userid by 10m

outcome:
   $login_count= count(metadata.id)

condition:
   $login_count > 5

SPL where 명령어 = YARA-L condition 섹션

SPL where 명령어는 YARA-L의 events, outcome 또는 condition 섹션의 혼합과 같습니다. events 섹션을 사용하여 이벤트를 선언하고 이벤트의 특정 속성 (예: priniciapal.hostname = "xyz")을 지정할 수 있습니다. 이벤트를 선언한 후에는 부울 연산자, 비교 연산자, 집계 함수 결과 (outcome 섹션에서)를 사용하여 쿼리가 결과를 반환하기 위해 이벤트가 충족해야 하는 매개변수를 정의할 수 있습니다.

다음 예에서는 집계된 개수에 임곗값 조건을 설정하는 방법을 보여줍니다. 이 쿼리는 사용자 ID별로 실패한 로그인 이벤트의 총수를 계산하도록 구성되어 있으며, condition 섹션을 사용하여 실패한 로그인이 5회 이상 기록된 사용자만 결과를 출력합니다.

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"

match:
  target.user.userid

outcome:
  // metadata.id counts all unique events associated with failed logins.
  $count = count(metadata.id)
  //metadata.id counts all unique events associated with blocked logins.

condition:
  $count > 5

SPL dedup 명령어 = YARA-L dedup 섹션

SPL dedup 명령어YARA-L의 dedup 섹션과 같습니다. dedup 섹션을 사용하여 events 섹션의 이벤트에 의해 지정된 중복 결과를 중복 삭제합니다.

예를 들면 다음과 같습니다.

principal.hostname = "foo"

dedup:
   target.ip

SPL stats 명령어 = YARA-L match 또는 outcome 섹션 (또는 둘 다)

SPL에서 집계는 일반적으로 집계 유형 (예: count, distinct, count, max, min)과 "group by" 필드를 지정하는 stats 명령군에 의해 처리됩니다.

YARA-L에서 matchoutcome 섹션은 공동으로 다음 기능을 제공합니다.

  • 집계 로직: match 섹션에서는 고려할 이벤트 그룹 (match: $grouping_field by time)을 정의하여 집계를 만듭니다. 그런 다음 outcome 섹션에서는 해당 그룹에 대해 계산할 특정 집계 함수 (예: count(), min(), max())를 정의합니다.

  • 기간 설정: match 섹션은 이벤트를 그룹화할 기간을 지정하는 것을 지원합니다. over 키워드 (규칙의 경우) 또는 by (검색 및 대시보드의 경우) (예: match: $userid by 1h)를 사용합니다. 이 기능은 "timechart", "streamstats", "eventstats"과 같은 SPL과 유사합니다. 자세한 내용은 시간 창을 참고하세요.

예: 주 호스트 이름과 타겟 IP로 그룹화된 바이트 합계 계산

다음 예에서는 match 섹션을 사용하여 하루 기간 동안 주 구성원 호스트 이름과 타겟 IP 주소를 기반으로 집계 그룹을 정의합니다. 전송된 바이트의 합계는 outcome 섹션 내에서 계산됩니다.

metadata.event_type = "NETWORK_CONNECTION"
network.sent_bytes > 0
principal.hostname != ""
target.ip != ""

// Define placeholder variables for grouping
$principal_hostname = principal.hostname
$target_ip = target.ip

// Group events by principal hostname, target IP, and day
match:
  $principal_hostname, $target_ip by day

// Calculate the sum of sent bytes for each group
outcome:
  $daily_bytes_sent = sum(network.sent_bytes)

SPL을 YARA-L에 매핑

SPL은 파이프된 명령어를 통해 데이터를 단계별로 처리하는 반면 YARA-L은 선언적 섹션 기반 구조를 사용하여 패턴과 작업을 정의합니다. 접근 방식에는 이러한 근본적인 차이가 있지만 YARA-L의 표현력을 사용하면 기본 필터링부터 복잡한 집계 및 상관관계에 이르기까지 SPL에서 익숙한 많은 작업을 수행할 수 있습니다.

이 섹션에서는 친숙한 SPL 기능을 YARA-L 프레임워크 내의 해당 기능에 매핑하여 차이점을 설명합니다.

SPL과 YARA-L 비교

이 표에서는 일반적인 SPL 언어의 일반적인 함수와 개념을 YARA-L 2.0의 해당 함수와 개념 또는 YARA-L 쿼리 구조 내에서 개념이 처리되는 방식과 비교합니다.

SPL 명령어 또는 개념 목적 YARA-L에 상응하는 항목 설명 및 YARA-L 매핑 YARA-L 구현 예
search 초기 데이터 필터링 events 섹션 이벤트 필드와 조건을 정의합니다. 검색 또는 대시보드에 events: 접두사가 필요하지 않습니다. 예시를 참고하세요.

events:
  metadata.event_type = "USER_LOGIN"
  security_result.action = "FAIL"

        
where 결과 추가 필터링 eventscondition 섹션 집계된 결과에 불리언 논리를 적용합니다. 예시 보기

events:
  metadata.event_type = "USER_LOGIN"
  security_result.action = "FAIL"

outcome:
  $failed_count = count(metadata.id)

condition:
  $failed_count > 5
        
eval 기존 필드, 집계, 데이터 조회에서 새 값을 계산합니다. outcome 또는 events 섹션 SPL eval 예시를 참고하세요.

metadata.event_type = "USER_LOGIN"

outcome:
  $login_count = count(metadata.id)
        
stats 집계 (count, sum, avg) match 또는 outcome match의 필드를 기준으로 그룹화합니다. outcome에서 집계를 계산합니다. 집계 및 통계 쿼리SPL stats 명령어의 예시를 참고하세요.

metadata.event_type = "USER_LOGIN"

outcome:
  $login_count = count(metadata.id)
        
dedup 하나 이상의 필드를 기반으로 중복 이벤트를 삭제합니다. dedup 섹션 중복 삭제할 필드를 지정합니다.

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid

dedup:
  $user
        
table 표 열 출력을 정의합니다. select 또는 unselect 대시보드에서 사용됩니다. 검색에서 outcome 변수를 표시합니다.

metadata.event_type = "USER_LOGIN"

select:
  principal.hostname
        
sort 결과를 오름차순 또는 내림차순으로 나열합니다. order 섹션 다음 표 셀의 예를 참고하세요.
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""

outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = uint64(network.sent_bytes)

order:
  $bytes desc
limit 반환되는 결과 수를 제한합니다. limit 섹션 다음 셀의 예를 참고하세요.

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""

outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = cast.as_int(network.sent_bytes)

order:
  $bytes desc

limit:
  3
  
다중 값 함수 mv* 함수 (mvexpand, mvfilter)로 처리됨 기본 지원 YARA-L은 이벤트 섹션에서 배열을 자동으로 중첩 해제합니다. 필요한 경우 outcome에서
배열 함수를 사용할 수 있습니다.
다중 값 함수 예시를 참고하세요.
기간 earliest=-5m, latest=now match 섹션, over, by 지속적인 감지의 경우 match: $field over 5m or by 5m를 사용합니다. 검색 UI의 대시보드의 경우 match: $field by 5m를 사용하세요. 시간 창의 예시를 참고하세요.

집계 및 통계 쿼리

YARA-L에서 집계 및 통계 함수는 일반적으로 outcome 섹션에 배치되고 집계는 match 섹션을 기반으로 합니다.

stats 명령어는 YARA-L 쿼리 내에서 데이터 집계를 구현하는 기본 메커니즘입니다. 원시 이벤트 데이터를 요약된 보안 측정항목으로 변환합니다. eval 명령어는 필드 수준, 행별 변환 (SELECT 표현식과 유사)을 처리하는 반면 stats세트 수준 집계 (SQL의 GROUP BY과 유사)를 실행합니다.

다음 표에서는 데이터 패턴과 통계적 이상치를 기반으로 정교한 보안 로직을 구현하기 위해 통계를 효과적으로 사용하는 방법을 보여주는 핵심 구문과 사용법을 제공합니다.

SPL 기능 설명 YARA-L에 상응하는 항목 YARA-L 구현 예
count 이벤트 수를 집계합니다. count()

metadata.event_type= "USER_LOGIN"
security_result.action= "FAIL"

outcome:
  $event_count = count(metadata.id)

condition:
  $event_count > 2
  
dc (count_distinct) 필드의 고유 값 수를 계산합니다. count_distinct()

metadata.event_type = "USER_LOGIN"

outcome:
  $unique_users=count_distinct(principal.user.userid)
  
sum 필드의 값 합계를 계산합니다.
sum()

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host

outcome:
  $bytes = sum(network.sent_bytes)
  
avg 필드의 평균값을 계산합니다.
avg()

$host = principal.hostname

match:
  $host by day

outcome:
  $avg_bytes_sent = avg(network.sent_bytes)
  
min/max 필드의 최솟값 또는 최댓값을 찾습니다. min() 또는 max()

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host

outcome:
  $bytes = max(network.sent_bytes)- min(network.sent_bytes)
  
median() 중앙값을 찾습니다. window.median

target.file.mime_type = "PDF"

outcome:
  $median_file_size = window.median(target.file.size, false)
  
first() and last() 검색 결과의 이벤트 순서에 따라 값을 반환합니다. window.first/window.last

metadata.event_type = "NETWORK_CONNECTION"
principal.ip != ""

match:
  principal.ip

outcome:
  $event_count = count(metadata.id)
  $first_seen = window.first(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
  $last_seen = window.last(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
  
STDDEV() 데이터 세트의 분산을 측정하는 표준 편차를 계산합니다. window.stddv

principal.hostname= $host

match:
  $host over 5m

outcome:
  $stddev = window.stddev(network.sent_bytes)

자세한 내용은 추가 함수를 참고하세요.

예를 들어 다단계 쿼리는 계층화된 집계에서 실패한 여러 로그인을 추적할 수 있습니다. 자세한 내용은 다단계 집계 예시YARA-L에서 다단계 쿼리 만들기를 참고하세요.

다단계 집계 (시간별에서 주별 평균)

이 다단계 예시에서는 먼저 데이터를 집계하여 시간당 호스트별로 전송된 바이트를 찾습니다. 그런 다음 이 집계를 사용하여 지난 7일 동안의 시간별 버킷 전체 평균을 계산합니다.

stage bytes_per_host {
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host by hour

outcome:
  $bytes = cast.as_int(sum(network.sent_bytes))
}

$host = $bytes_per_host.host

match:
  $host

outcome:
  $hour_buckets = array_distinct(timestamp.get_timestamp($bytes_per_host.window_start))
  $num_hour_buckets = count_distinct($bytes_per_host.window_start)
  $avg_hourly_bytes = avg($bytes_per_host.bytes)

다중 값 함수 (배열 읽기)

YARA-L의 문법은 필드에 여러 값이 있을 수 있음을 이해하도록 빌드됩니다. events 섹션에 다중 값 필드가 있는 이벤트를 포함하는 쿼리를 작성하면 언어에서 배열의 모든 값을 자동으로 확인합니다. 배열을 필터링하기 위해 특수 함수를 사용할 필요는 없습니다. 일치시키려는 조건을 명시하기만 하면 됩니다. 예를 들어 로그 이벤트의 principal.ip 필드에 다음이 포함된 경우 YARA-L 엔진은 principal.ip 배열의 모든 값을 자동으로 확인합니다. 값이 "10.1.1.5"이면 조건이 충족됩니다.

["10.1.1.5", "10.2.2.6", "10.3.3.7"]

다음 표에서는 로그 데이터에서 다중 값 필드를 관리하는 방법에 관해 YARA-L과 SPL을 비교합니다. IP 주소 배열이나 사용자 그룹 목록과 같은 다중 값 필드는 구조화된 로그에서 흔히 볼 수 있는 기능입니다.

SPL 기능 목적 YARA-L에 상응하는 항목 YARA-L 구현 예
mvfilter() 일치하는 값만 유지하도록 다중 값 필드를 필터링합니다. YARA-L 쿼리의 events 섹션에서 사용할 때는 일치시킬 필드를 나열합니다. YARA-L은 그룹 배열의 값이 '`admin`'과 일치하는지 자동으로 확인합니다.

principal.user.group_identifiers = "admin"
        
mvcount() 다중 값 필드의 값 수를 계산합니다. outcome 쿼리 섹션의 필드에 적용된 count() 먼저 값을 중첩 해제할 필요가 없습니다. IT 직원 그룹에 속한 사용자 수 계산 예시를 참고하세요.
mvexpand 다중 값 필드의 각 값에 대해 새 이벤트를 만듭니다. 다중 값 필드를 기본적으로 암시적으로 처리합니다. unnesting은 자동으로 실행됩니다. IT 직원 그룹에 속한 사용자 수 계산 예시를 참고하세요.
mvjoin 데이터 형식 지정을 위해 다중 값 필드의 모든 값을 단일 문자열로 결합합니다. 값은 결과에 배열로 자동 저장됩니다. YARA-L의 출력은 구조화되어 있으며 플랫 문자열이 아닙니다. 배열을 추가로 조작해야 하는 경우 필드를 배열로 표시합니다. 자세한 내용은 배열 함수를 사용하세요.

예: admin 로그인 수 계산

다음 예시에서 $metadata.event_type = "USER_LOGIN" 조건은 event_type이 "USER_LOGIN"인 이벤트를 필터링합니다.

events:
 metadata.event_type = "USER_LOGIN" // Changed to a more appropriate event type for login
 principal.user.group_identifiers = "admin"

outcome:
 // This counts each unique event ID where the principal user is in the `"admin"` group.
 $admin_login_count = count(metadata.id)

$principal.user.group_identifiers= "admin" 필드는 반복 필드 (배열)입니다.

  • 암시적 unnesting: YARA-L은 쿼리 평가 중에 이 필드를 내부적으로 자동으로 unnest합니다.
  • 조건 확인: $principal.user.group_identifiers 배열 내의 값이 "admin"와 같으면 이벤트가 조건을 충족합니다.
  • 명시적 명령어가 필요하지 않음: SPL과 달리 mvexpand와 같은 특정 unnesting 명령어가 필요하지 않습니다.

집계 (outcome) 섹션에 미치는 영향은 암시적 중첩 해제가 outcome 섹션에서 중요하다는 것을 의미합니다 (예: outcome: $admin_login_count = count(metadata.id)). 다음 영향을 참고하세요.

  • 반복 필드에 일치하는 값이 여러 개 포함된 단일 UDM 이벤트는 쿼리 평가를 위해 여러 내부 을 생성할 수 있습니다.
  • events 섹션에서 $principal.user.group_identifiers의 각 일치 값을 기반으로 이벤트를 이미 효과적으로 중첩 해제했으므로 count(metadata.id) 집계는 이러한 중첩 해제된 인스턴스를 각각 집계합니다.

예: IT 직원 그룹에 속한 사용자 수 계산

SPL:

index=<your_index_name> user_id="jsmith" 
| where match(memberOf, "Domain Admins|IT Staff|HR") 
| mvexpand memberOf 
| stats count by memberOf 
| mvexpand actions 
| table memberOf, count, actions

YARA-L (검색):

 principal.user.userid = "jsmith"
 additional.fields["memberOf"] = $group
   $group = /Domain Admins|IT Staff|HR/ nocase
 
 match:
   $group by 1h
 
 outcome:
   $group_count = count_distinct(metadata.id)
   $memberOf = array_distinct($group)
   $risk_score = max(50)

예: 특정 파일 해시가 있는 경우 알림을 보내는 규칙 만들기

SPL:

| eval file_hashes="hash12345,hash67890,hashABCDE" 
| makemv delim="," file_hashes 
| mvexpand file_hashes 
| search file_hashes="hash67890" 
| table _time, file_hashes

YARA-L (규칙):

    rule specific_file_hash_detected {
    
    meta:
      rule_name = "Specific File Hash Detected"
      description = "Detects events where a specific file hash is present."
      severity = "Medium"
    
    events:
      $e.target.file.sha256 == "hash67890"
    
    outcome:
      $time = array_distinct($e.metadata.event_timestamp)
      $file_hashes = array_distinct($e.target.file.sha256)
    
    condition:
      $e
    }

기간

YARA-L에서 시간 윈도우화는 특정 순환 기간 동안 이벤트를 상관관계 지정하는 방법입니다. 규칙에 사용되는 이 윈도우는 수신 데이터와 함께 지속적으로 이동하므로 시간이 지남에 따라 전개되는 패턴을 지속적으로 실시간으로 감지할 수 있습니다.

이 프로세스는 자동 감지 설계의 핵심 부분이며 YARA-L 사용의 이점 중 하나입니다. 시간 범위를 지정하면 감지 및 대시보드가 실시간 데이터를 지속적으로 사용합니다.

기능 SPL YARA-L
기본 목표 정적 검색, 임시 분석 지속적인 감지, 자동 상관관계
기본 기능 earliest, latest, span, transaction over, by
5분 예시 earliest=-5m (정적 검색)
또는
transaction maxspan=5m
match:
[event] over 5m (규칙의 연속 감지)
또는
[event] by 5m (검색 및 대시보드)

이 섹션의 예에서는 YARA-L에서 텀블링 시간 기간 (by 사용)과 슬라이딩 시간 기간 (over 사용)의 차이를 보여줍니다.

텀블링 기간 (by <time_unit>)

  • 개념: YARA-L 검색에 사용되는 텀블링 윈도우는 겹치지 않는 고정된 크기의 고정 시간 간격을 만듭니다. 시스템은 타임스탬프를 기반으로 각 이벤트를 정확히 하나의 특정 시간 버킷에 할당하여 처리합니다. 이러한 고정 간격은 절대적이며 일, 시간, 분과 같은 표준 시간 마커와 엄격하게 일치합니다.

  • 사용: Google SecOps 검색 쿼리 및 대시보드에서 데이터를 개별 시간 세그먼트로 집계하는 데 일반적으로 사용됩니다.

예: 사용자별 성공한 로그인 일별 수

이 검색어는 각 캘린더 날짜 내에서 각 고유 사용자별로 성공한 로그인 이벤트를 그룹화합니다. 다음 예에서는 YARA-L 검색 텀블링 창 (by day)을 보여줍니다.

events:
  //Filter for successful login events
  metadata.event_type = "USER_LOGIN"
  principal.user.userid != ""

match:
  //Group by each unique user ID, aggregated over a calendar day.
  principal.user.userid by day

outcome:
  //Count how many successful logins occurred for this user on this specific day.
  $daily_success_count = count(metadata.id)
  
  //Get the timestamp of the FIRST event within this daily group.
  $first_event_time = window.first(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
  
  //Get the timestamp of the LAST event within this daily group.
  $last_event_time = window.last(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))

작동 방식: 사용자 jdoeNov 17에서 10회, Nov 18에서 15회 로그인에 성공한 경우 이 쿼리는 jdoe에 대해 두 개의 별도 행을 생성합니다. 각 행은 날짜별로 해당 횟수를 나타냅니다. Nov 17 버킷에는 2025-11-17 00:00:00 to 23:59:59 UTC의 이벤트가 포함됩니다.

슬라이딩 시간 윈도우 (over <duration>)

  • 개념: YARA-L 규칙에 사용되는 슬라이딩 창은 지정된 기간의 이동하는 시간 창으로, 겹칠 수 있습니다. 서로 가까운 곳에서 발생하는 이벤트를 상관관계로 묶는 데 적합합니다.

  • 사용: 연속된 기간 내에서 이벤트의 패턴이나 시퀀스를 감지하기 위해 YARA-L 규칙에서 주로 사용됩니다.

예: 5분 이내에 여러 번의 로그인 실패 감지

이 YARA-L 규칙 예시에서는 단일 사용자가 연속된 5-minute 기간 내에 5 failed logins회 이상 시도하면 감지를 생성합니다.

rule TooManyFailedLogins_SlidingWindow {
 meta:
   author = "Alex"
   description = "Detects when a user has more than 5 failed logins within a 5-minute sliding window."
   severity = "Medium"

events:
   // Define an event variable $e for failed login attempts
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $e.principal.user.userid != ""
   $userid = $e.principal.user.userid

match:
   // Group events by userid over a continuous 5-minute sliding window.
   // Any events for the same $userid within 5 minutes of each other are grouped.
   $userid over 5m

outcome:
   // Count the number of failed login events within each 5-minute window for the grouped userid.
   $failed_count = count($e.metadata.id)

condition:
   // Trigger a detection if the count of failed logins in ANY 5-minute window is greater than 5.
   #e > 5
}

작동 방식: 시스템에서 로그인 실패를 지속적으로 모니터링합니다. 특정 시점에서 각 사용자의 지난 5분간의 이벤트를 고려합니다. 예를 들어 10:02:3010:07:30 사이에 사용자 jdoe가 로그인에 6번 실패하면 감지가 트리거됩니다. 이 윈도우는 지속적으로 앞으로 슬라이드되므로 캘린더 경계와 관계없이 실시간 패턴 감지가 발생합니다.

다음 단계

도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가에게 문의하여 답변을 받으세요.