일치 섹션 구문
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> |
고정 크기, 겹치지 않는 연속 시간 간격 | 최대 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
텀블링 윈도우
텀블링 윈도우는 데이터 스트림을 고정 크기이며 겹치지 않는 연속 시간 간격으로 분할합니다. 각 이벤트의 타임스탬프는 정확히 하나의 윈도우에 속합니다. 텀블링 윈도우 간에는 겹치는 부분이 없습니다. 이는 시간 간격이 겹칠 수 있는 슬라이딩 또는 홉 윈도우와 대조됩니다.
텀블링 윈도우를 구현하려면 match 섹션에서 by 연산자를 사용합니다.
텀블링 윈도우는 시간을 연속적인 블록으로 나눕니다. 예를 들면 다음과 같습니다.
by 1h: 시간별 윈도우를 만듭니다 (예: [00:00:00~00:59:59], [01:00:00~01:59:59] 등).by 10m: 각 10분 간격에 대한 윈도우를 만듭니다 (예: [00:00:00~00:09:59], [00:10:00~00:19:59] 등).
사용 사례
다음과 같은 경우 텀블링 기간을 사용하세요.
- 중복되지 않는 별도의 시간 블록에서 이벤트를 분석합니다.
- 이벤트 발생 횟수와 관계없이 각 고정 시간 간격 내에서 지정된 항목 (일치 변수로 정의됨)에 대해 하나의 감지만 생성되도록 합니다.
- 고정된 기간 동안 고유한 항목을 집계합니다.
중복 삭제 동작
텀블링 윈도우의 주요 특징은 동일한 일치 변수 집합에 대해 각 윈도우 내에서 발견 항목이 처리되는 방식입니다.
- 기간당 하나의 감지: 일치 변수 (예: 특정
$userid)의 특정 값 집합에 대해 단일 텀블링 기간에 최대 하나의 감지가 생성됩니다. - 먼저 도착한 이벤트가 우선: 특정 기간 내에 해당 일치 변수 집합의 규칙 조건을 충족하는 첫 번째로 수집된 이벤트가 감지를 트리거합니다.
- 중복 삭제: 동일한 기간 인스턴스 내에서 기준과 일치하는 후속 이벤트는 추가 감지를 생성하지 않습니다.
구문
match 섹션의 구문은 다음과 같습니다.
match:
$variable by <duration>
각 항목의 의미는 다음과 같습니다.
$variable은(는) 일치시키는 자리표시자 변수입니다.<duration>는 숫자 뒤에 시간 단위가 옵니다.m: 분h: 시간d: 일
최소 1분, 최대 72시간 또는 3일을 지정합니다.
예
다음 규칙은 1시간의 중복되지 않는 기간 내에서 $userid별로 로그인을 그룹화합니다 (예: [00:00:00~00:59:59], [01:00:00~01:59:59] 등).
rule TumblingWindowExample {
meta:
description = "Example using a 1-hour tumbling window"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $userid
match:
$userid by 1h
condition:
$e
}
다음은 user = "alex"의 감지 동작 예시입니다.
이벤트 1: Alex가 00:30에 로그인합니다. 이 시간은 [00:00:00~00:59:59] 범위에 속합니다. 이 기간에 대해 Alex에 대한 감지가 생성됩니다.
이벤트 2: 다른 사용자
"taylor"이 00시 45분에 로그인합니다. 이 경우도 [00:00:00~00:59:59]에 해당하지만$userid가 다르므로 이 시간대에 Taylor에 대한 별도의 감지가 생성됩니다.이벤트 3: Alex가 00시 40분에 다시 로그인합니다. 여전히 [00:00:00~00:59:59] 범위 내에 있습니다. 이 기간에 대해 Alex의 감지가 이미 있으므로 이 이벤트는 중복 제거됩니다. 새로운 감지가 생성되지 않습니다.
이벤트 4: Alex가 01:20에 로그인합니다. 이 시간은 다음 시간대인 [01:00:00~01:59:59]에 해당합니다. 이 새 창에 대해 Alex의 새로운 감지가 생성됩니다.
앨리스의 이벤트 1과 이벤트 4는 1시간 미만의 간격으로 발생했지만 이벤트 4가 고정 기간 경계를 넘기기 때문에 별도의 감지로 분류됩니다.
슬라이딩 기간
엄격한 상대적 순서로 발생하는 이벤트 (예: e1이 e2 후 최대 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 전문가에게 문의하여 답변을 받으세요.