일치 섹션 구문

다음에서 지원:

YARA-L 2.0에서 match 섹션은 멀티 이벤트 상관관계에 대한 메커니즘을 제공합니다. 특정 시간 경계 내에서 사용자, IP 주소 또는 파일 해시와 같은 공통 속성을 연결하여 이벤트를 단일 감지로 그룹화하는 로직을 정의합니다.

다음 사용 사례에 match 섹션을 사용합니다.

  • 규칙 내에서 두 개 이상의 개별 이벤트를 연결합니다.
  • 특정 기간 동안의 로그인 실패 시도 횟수와 같은 검색 및 대시보드의 데이터를 집계합니다.

상관관계 기준 정의

이를 사용하여 다음을 지정하여 이 상관관계의 기준을 정의합니다.

  • 그룹화 필드 (키): 일치를 트리거하려면 이벤트 (events 섹션에 정의됨) 간에 값이 동일해야 하는 변수 (예: $user 또는 $ip)입니다.

  • 시간 제약: 규칙 또는 집계를 충족하기 위해 그룹화된 이벤트가 발생해야 하는 기간 입니다. 규칙에서는 감지 기간을 정의하고, 검색 및 대시보드에서는 집계 또는 상관관계 기간을 정의합니다.

기능 요구사항 비교

다음 표에는 검색 규칙과 대시보드의 비교 내용이 자세히 나와 있습니다.

기능 규칙 요구사항 검색 및 대시보드 지원
변수 유형 events 섹션에 정의된 자리표시자를 사용해야 합니다. 자리표시자와 직접 UDM 필드를 모두 지원합니다.
기간 감지 경계를 정의합니다. 집계 또는 상관관계 버킷을 정의합니다.
구문 over <number><m/h/d> (예: 10m, 2h, 1d) over <number><m/h/d>
한도 최소: 1m / 최대: 48h 최소: 1m / 최대: 48h

지원되는 창 유형

YARA-L 2.0은 다양한 윈도우 동작을 사용하여 시간이 어떻게 슬라이스되고 이벤트가 어떻게 그룹화되는지 확인합니다. 지원되는 다음 창 중 하나를 사용하여 match 섹션의 이벤트 필드와 자리표시자를 지정된 시간 세분성으로 그룹화할 수 있습니다.

지원되는 창 유형 구문 설명 일반적인 사용 사례
$key over <duration> 시간 간격이 중복됩니다 (기본 동작). 여러 이벤트의 일반적인 상관관계입니다.
텀블링 $key by <duration> tumbling 고정 크기, 겹치지 않는 연속 시간 간격입니다. 최대 1시간 단위로 활동을 정량화합니다 (예: $user by 30m).
슬라이딩 $key over <duration> [before|after] $pivot 특정 '피벗' 이벤트에 고정된 시간 간격입니다. 엄격한 순서 지정 (예: File Download after Login)

예시 문법:

match:
  $user, $source_ip over 5m  // Groups events by user and IP within a 5-minute window

홉 기간

홉 윈도우는 다중 이벤트 규칙의 기본 동작입니다. 창 경계 근처에서 발생하는 이벤트가 누락되지 않도록 중복되는 시간 간격을 만듭니다.

  • 구문: $key over <duration> (예: $user over 30m)
  • 사용 사례: 창 간격의 시작 또는 종료 시점과 관계없이 특정 시나리오가 포착되도록 해야 하는 감지에 가장 적합합니다.
  • 지원: 검색 및 대시보드에서 집계에 지원됩니다 (예: count).

기본적으로 match 섹션이 있는 YARA-L 쿼리는 홉 기간을 사용하여 시간 경과에 따른 여러 이벤트를 연결합니다. 쿼리 실행 기간은 고정된 겹치는 홉 기간 집합으로 분할됩니다. 이러한 창의 기간은 match 섹션에 지정되지만 중복 간격과 창 정렬은 시스템 정의이며 사용자가 구성할 수 없습니다. 그런 다음 이러한 사전 정의된 각 창 내에서 이벤트에 대해 상관관계가 지정됩니다.

예: 연속 상관관계를 위한 홉 창이 겹침

다음 예에서는 [1:00, 2:00] 기간 동안 실행되는 쿼리를 보여줍니다. 이 쿼리에는 $user over 30m에 대한 match 섹션이 있으며, 생성될 수 있는 겹치는 홉 기간 집합은 [1:00, 1:30], [1:03, 1:33], [1:06, 1:36]입니다.

rule hop_window_brute_force_example {
meta:
  description = "Detects multiple failed logins within a shifting 30-minute window."
  severity = "Medium"

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.extensions.auth.auth_status = "FAILURE"
  $login.principal.user.userid = $user

match:
  // This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
  $user over 30m

condition:
  // This will trigger if 10 or more failures fall into any single 30m hop
  #login >= 10
}

예: 홉 창을 사용한 멀티 이벤트 상관관계

다음 예는 대부분의 다중 이벤트 규칙의 기본값을 나타냅니다. 일반적인 기간 내에 발생하는 이벤트를 포착합니다.

rule hop_window_example {
meta:
  description = "Detect a user with a failed login followed by a success within 30m"

events:
  $e1.metadata.event_type = "USER_LOGIN"
  $e1.extensions.auth.auth_status = "FAILURE"
  $e1.principal.user.userid = $user

  $e2.metadata.event_type = "USER_LOGIN"
  $e2.extensions.auth.auth_status = "SUCCESS"
  $e2.principal.user.userid = $user

match:
  $user over 30m  // This is a hop window

condition:
  $e1 and $e2
}

예: 홉 윈도우 비교

무차별 대입 시도를 식별하기 위해 10m 창은 모든 USER_LOGIN 실패를 그룹화합니다. 그런 다음 condition에서 해당 10분 버킷 내의 개수 (#e)가 기준점을 초과하는지 평가합니다.

rule failed_logins
{
meta:
  author = "Security Team"
  description = "Detects multiple failed user logins within 10-minute windows."
  severity = "HIGH"

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

match:
  $user over 10m

condition:
  #e >= 5
}

match 섹션은 10분 (10m) 간격으로 새 위치에서 로그인에 실패한 사용자를 찾습니다.

match:
  $user over 10m

텀블링 윈도우

텀블링 윈도우는 데이터 스트림을 고정 크기의 연속된 시간 간격으로 분할합니다. 각 데이터 이벤트는 하나의 윈도우에만 할당됩니다. 이는 시간 간격이 겹칠 수 있는 슬라이딩 또는 홉 윈도우와 대조됩니다.

  • 구문: by 연산자($key by <duration>)를 사용합니다(예: $user by 30m).
  • 사용 사례: 서로 다른 블록 (예: "How many alerts per hour?")에서 이벤트를 집계하려는 보고 및 대시보드 빌드에 가장 적합합니다.
  • 검색 및 대시보드: 이벤트 중복을 삭제하지 않고 깔끔한 막대 그래프를 만드는 데 자주 사용됩니다.

예: 텀블링 윈도우를 사용한 고정 간격 계산

다음 예에서는 30분 텀블링 윈도우를 보여줍니다. 1:00:00~1:29:59 사이에 발생한 이벤트가 함께 처리됩니다. 그런 다음 1시 30분 00초부터 1시 59분 59초까지의 다음 이벤트 세트가 별도로 처리됩니다.

rule tumbling_window_threshold_example {
meta:
  description = "Detect more than 50 failed logins from a single IP within a fixed 1-hour block."
  severity = "Medium"

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.extensions.auth.auth_status = "FAILURE"
  $login.principal.ip = $ip

match:
// This creates distinct, 1-hour blocks (e.g., 1:00-1:59, 2:00-2:59)
  $ip by 1h

condition:
  #login > 50
}

슬라이딩 기간

엄격한 상대적 순서로 발생하는 이벤트 (예: e1e2 후 최대 2분 내에 발생)를 검색해야 하는 경우 슬라이딩 윈도우를 사용합니다. 고정 윈도우와 달리 슬라이딩 윈도우는 다음 구문을 사용하여 지정된 $pivot_event의 모든 발생에 의해 트리거됩니다.

  • after: 윈도우는 피벗 이벤트의 타임스탬프에서 시작하여 앞으로 확장됩니다.
  • before: 윈도우는 피벗 이벤트의 타임스탬프에서 끝나고 뒤로 확장됩니다.

다음과 같이 쿼리의 match 섹션에 슬라이딩 기간을 지정합니다.

<match-var-1>, <match-var-2>, ... over <duration> [before|after] <pivot-event-var>

  • 구문: $key over <duration> before|after $<pivot_event>
  • 그룹화 키: 이벤트를 서로 연결하는 데 사용되는 공통 필드 (예: $user, $ip)입니다.
  • 기간: 기준 이벤트의 시간 오프셋입니다 (예: 5m, 1h).
  • 사용 사례:
    • 엄격한 순서 지정: 순서가 필요한 공격 체인을 감지합니다 (예: 사용자 생성 후 권한 에스컬레이션).
    • 상대적 타이밍: '트리거'의 특정 오프셋 내에서 발생하는 이벤트를 찾습니다(예: Process Start 이벤트 후 30초 이내에 Network Connection이 발생).
    • 부재 감지: 시작 이벤트 후 필수 '정리' 또는 '하트비트' 이벤트가 발생하지 않는 경우를 식별합니다 (예: 해당 End 이벤트 없이 Database Backup Start).

유효한 슬라이딩 구간 예시

다음 예시는 유효한 슬라이딩 기간을 보여줍니다.

$var1, $var2 over 5m after $e1 $user over 1h before $e2 $host, $ip over 1h before $e2

예: 슬라이딩 기간을 사용한 미래 지향적 상관관계 (after)

다음 예에서는 기본 '트리거' 또는 피벗 이벤트 후 특정 기간 내에 두 번째 이벤트가 발생해야 하는 이벤트 시퀀스를 감지하는 방법을 보여줍니다. 이는 빠른 측면 이동이나 자동 후속 조치를 감지하는 데 유용합니다.

rule sliding_window_after_example {
meta:
  description = "Detect a network connection occurring within 1 minute after a suspicious process launch."
  severity = "High"

events:
  $proc.metadata.event_type = "PROCESS_LAUNCH"
  $proc.principal.hostname = $host

  $net.metadata.event_type = "NETWORK_HTTP"
  $net.principal.hostname = $host

match:
  // $proc is the pivot; the 1-minute window starts at the $proc timestamp
  $host over 1m after $proc

condition:
  $proc and $net
}

예: 슬라이딩 윈도우를 사용한 과거 지향적 상관관계 (before)

"before" 슬라이딩 창을 사용하여 특정 알림이 발생하기 전의 활동을 조사합니다. 이는 심각한 탐지 직전에 발생한 상황을 파악하기 위해 근본 원인 분석에 자주 사용됩니다.

rule sliding_window_before_example {
meta:
  description = "Identify file modifications occurring in the 5 minutes before a ransomware alert."
  severity = "Critical"

events:
  $file.metadata.event_type = "FILE_MODIFICATION"
  $file.principal.hostname = $host

  $alert.metadata.event_type = "ANTIVIRUS_DETECTION"
  $alert.metadata.product_name = "Premium_AV"
  $alert.principal.hostname = $host

match:
  // $alert is the pivot; the 5-minute window ends at the $alert timestamp
  $host over 5m before $alert

condition:
  $file and $alert
}

성능 및 권장사항

슬라이딩 윈도우는 피벗 이벤트가 발생할 때마다 계산되므로 표준 (홉) 윈도우보다 더 많은 처리 능력이 필요하며 성능이 느려질 수 있습니다.

규칙, 검색, 대시보드에서 최적의 성능을 얻으려면 다음 가이드라인을 따르세요.

  • 홉 기간 우선순위 지정: 감지 로직에 특정 이벤트 시퀀스 (주문 A 후 주문 B)가 필요하지 않은 경우 기본 홉 기간을 사용합니다. 이벤트 순서가 중요하거나 누락된 이벤트를 검색하는 경우에만 슬라이딩 기간을 사용하세요.

  • 실적을 위해 타임스탬프 필터 사용: 한 이벤트가 다른 이벤트 후에 발생했는지 확인하기만 하면 되는 경우 events 또는 condition 섹션의 타임스탬프 비교가 슬라이딩 윈도우보다 효율적인 경우가 많습니다. 예를 들면 다음과 같습니다.

$e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds

  • 다중 이벤트 설계: 단일 이벤트 쿼리에 슬라이딩 윈도우를 사용하지 마세요. 슬라이딩 윈도우는 다중 이벤트 상관관계에 맞게 설계되었습니다. 단일 이벤트 로직에는 다음 가이드라인이 적용됩니다.

    • 여러 이벤트 변수를 사용하고 condition 섹션을 업데이트합니다.
    • 상관관계가 필요하지 않으면 match 섹션을 완전히 삭제합니다.
    • 필요한 경우 슬라이딩 기간을 사용하는 대신 타임스탬프 필터를 추가할 수 있습니다(예:
      $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds).

시간 경계 이해하기

match 섹션은 그룹화 키를 기반으로 이벤트를 그룹으로 파티셔닝합니다. 지정된 기간은 각 그룹의 시간 경계를 정의합니다.

  • 포함: 기간 내의 이벤트만 해당 경기에서 condition 평가에 전달됩니다.
  • 제외: 창 외부의 이벤트는 해당 특정 일치 그룹에 대해 무시되므로 관련 없는 이벤트로 인해 거짓양성이 트리거되지 않습니다.

match 섹션의 0 값

Google SecOps는 match 섹션에 사용된 모든 자리 표시자의 0 값 (문자열의 경우 "", 숫자의 경우 0, 불리언의 경우 false, 열거 유형의 경우 위치 0의 값)을 암시적으로 필터링합니다.

예: 0 값 필터링

다음 예시는 0 값을 필터링하는 쿼리를 보여줍니다.

rule ZeroValuePlaceholderExample {

events:
  // Because $host is used in the match section, the query behaves
  // as if the following predicate was added to the events section:
  // $host != ""
  $host = $e.principal.hostname

  // Because $otherPlaceholder was not used in the match,
  // there is no implicit filtering of zero values for $otherPlaceholder.
  $otherPlaceholder = $e.principal.ip

match:
  $host over 5m

condition:
  $e
}

하지만 자리표시자가 함수에 할당되면 쿼리가 match 섹션에 사용된 자리표시자의 0값을 암시적으로 필터링하지 않습니다.

0값의 암시적 필터링을 사용 중지하려면 옵션 섹션에서 allow_zero_values 옵션을 사용하면 됩니다. allow_zero_values 옵션은 규칙에서만 사용할 수 있습니다.

예: 0 값 허용

다음 예시는 match 섹션에 사용된 자리표시자의 0값을 암시적으로 필터링하지 않는 쿼리를 보여줍니다.

rule AllowZeroValuesExample {

events:
  // Because allow_zero_values is set to true, there is no implicit filtering
  // of zero values for $host.
  $host = $e.principal.hostname

  // Because $otherPlaceholder was not used in the match,
  // there is no implicit filtering of zero values for $otherPlaceholder.
  $otherPlaceholder = $e.principal.ip

match:
  $host over 5m

condition:
  $e

options:
  allow_zero_values = true
}

다음 단계

다음 리소스를 살펴보고 YARA-L 로직을 계속하거나 고급 쿼리 함수를 자세히 알아보세요.

구문 및 논리

참조 및 예

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