YARA-L 2.0 알려진 문제 및 제한사항

이 문서는 규칙 로직을 디버그하고 YARA-L 2.0 실행을 최적화하려는 감지 엔지니어를 대상으로 합니다. 필드 unnesting, 집계의 데카르트 곱 확장, 최종 일관성 보강과 같은 비표준 엔진 동작을 처리하는 방법을 설명합니다. 이러한 방법을 따르면 결과 값이 부풀려지거나 감지가 누락되는 논리 오류를 방지할 수 있습니다.

YARA-L 2.0은 평가 중에 반복 필드가 개별 이벤트 행으로 확장되는 특정 실행 모델을 사용합니다. 이 변환은 엔진 수준에서 발생하므로 반복 필드를 여러 개 참조하거나 부호 없는 UDM 유형에 산술 연산을 실행하려면 컴파일러 오류나 잘못된 결과 집합을 방지하기 위해 특정 구문 해결 방법이 필요합니다. 이 문서에서는 이러한 기술적 제약 조건과 이를 해결하는 데 필요한 논리 패턴을 설명합니다.

시작하기 전에

YARA-L 2.0 규칙을 테스트하거나 수정하기 전에 계정에 다음 기술 권한이 있는지 확인하세요.

필요한 IAM 역할

  • roles/chronicle.viewer (Security Operations 뷰어): 기존 규칙 및 감지 메타데이터를 볼 수 있습니다.
  • roles/chronicle.editor (Security Operations 편집자): 규칙 로직을 수정하고 변경사항을 저장합니다.

필수 권한

  • chronicle.rules.runTest: 이전 데이터에서 테스트 실행 기능을 실행하는 데 필요합니다.

  • chronicle.detections.get: 감지 대시보드에서 중첩되지 않은 이벤트의 출력을 검사합니다.

주요 용어

  • UDM (통합 데이터 모델): 플랫폼 전체에서 수집된 모든 보안 원격 분석을 구조화하는 데 사용되는 정규화된 스키마입니다.
  • 중첩 해제: 반복 필드 (배열)가 포함된 단일 UDM 이벤트를 여러 행으로 엔진 수준에서 확장합니다. 각 행은 배열의 고유한 요소를 나타내므로 규칙 평가 중에 행이 곱해질 수 있습니다.
  • T₀ (초기 실행): 수신되는 원격 분석에 대한 규칙의 첫 번째 실행입니다. 이 문제는 '스트리밍' 단계에서 발생하며, GeoIP 또는 ASN 수정과 같은 백그라운드 보강 프로세스가 완료되기 전에 발생하는 경우가 많습니다.

반복 필드가 중첩 해제된 결과 집계

규칙이 여러 요소가 있는 이벤트 변수의 반복 필드를 참조하면 각 요소가 별도의 이벤트 행으로 분할됩니다.

예를 들어 이벤트 $e의 반복 필드 target.ip에 있는 두 개의 IP 주소는 각각 다른 target.ip 값을 가진 $e의 두 인스턴스로 분할됩니다.

rule outbound_ip_per_app {
  meta:

  events:
    $e.principal.application = $app

  match:
    $app over 10m

  outcome:
    $outbound_ip_count = count($e.target.ip) // yields 2.

  condition:
    $e
}

이벤트 레코드: 중첩 해제 전후

이 섹션의 표는 IP 주소 배열이 포함된 단일 이벤트가 두 개의 개별 레코드로 변환되는 방식을 보여줍니다.

중첩 해제 전

다음 표에서는 반복 필드를 중첩 해제하기 전의 이벤트 레코드를 보여줍니다.

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps [192.0.2.20, 192.0.2.28]

중첩 해제 후

다음 표에서는 반복 필드를 중첩 해제한 후의 이벤트 레코드를 보여줍니다.

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps 192.0.2.20
aaaaaaaaa Google SecOps 192.0.2.28

중첩된 반복 필드 (카티전 프로덕트)

규칙이 security_results.action과 같이 다른 필드 내에 중첩된 반복 필드를 참조할 때 중첩 해제는 상위 및 하위 수준에서 동시에 발생합니다. 이렇게 하면 모든 요소의 카티전 프로덕트가 생성됩니다.

다음 예시에서 security_results에 2개의 반복되는 값이 있고 security_results.actions에 2개의 반복되는 값이 있는 이벤트 $e는 4개의 인스턴스로 중첩 해제됩니다.

rule security_action_per_app {
  meta:

  events:
    $e.principal.application = $app

  match:
    $app over 10m

  outcome:
    $security_action_count = count($e.security_results.actions) // yields 4.

  condition:
    $e
}

중첩된 중첩 해제 전의 이벤트 레코드

원래 레코드는 중첩된 배열 구조 내에 작업을 저장합니다.

metadata.id principal.application security_results
aaaaaaaaa Google SecOps [ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ]

중첩된 중첩 해제 후의 이벤트 레코드

확장 후 각 고유한 작업이 자체 행이 되므로 중복되지 않은 집계에서 예상치 못한 개수가 발생할 수 있습니다.

metadata.id principal.application security_results.actions
aaaaaaaaa Google SecOps 허용
aaaaaaaaa Google SecOps 실패
aaaaaaaaa Google SecOps CHALLENGE
aaaaaaaaa Google SecOps 차단

관련 없는 필드에 미치는 영향

규칙 평가 시 이러한 중첩 해제 동작은 규칙이 또한 반복 필드에 해당하는 상위 필드가 포함된 반복 필드를 하나 이상 참조할 때 예기치 않은 결과 집계를 생성할 수 있습니다. sum(), array(), count()와 같은 고유하지 않은 집계는 중첩 해제 동작으로 생성되는 동일 이벤트의 다른 필드에서 중복 값을 고려할 수 없습니다.

다음 예시에서 이벤트 $e에는 단일 호스트 이름 (google.com)이 있지만 결과 (hostnames)는 동일한 이벤트 $e의 중첩되지 않은 인스턴스 4개에 대해 집계되며 각 인스턴스는 중복 principal.hostname 값을 가집니다. 이 결과는 security_results.actions에서 반복되는 값의 중첩 해제로 인해 1개가 아닌 4개의 호스트 이름을 생성합니다.

rule security_action_per_app {
  meta:

  events:
    $e.principal.application = $app

  match:
    $app over 10m

  outcome:
    $hostnames = array($e.principal.hostname) // yields 4.
    $security_action_count = count($e.security_results.action) // yields 4.

  condition:
    $e
}

관련 없는 필드가 포함된 중첩 해제 전 이벤트 레코드

호스트 이름은 단일 값인데 반복되는 보안 결과와 함께 표시됩니다.

metadata.id principal.application principal.hostname security_results
aaaaaaaaa Google SecOps google.com [ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ]

관련 없는 필드로 중첩 해제 후의 이벤트 레코드

이제 호스트 이름이 4개 행에 중복되어 array() 함수가 4번 선택합니다.

metadata.id principal.application principal.hostname security_results.action
aaaaaaaaa Google SecOps google.com 허용
aaaaaaaaa Google SecOps google.com 실패
aaaaaaaaa Google SecOps google.com CHALLENGE
aaaaaaaaa Google SecOps google.com 차단

중첩 해제 동작의 해결 방법

중첩 해제가 발생할 때 결과 값이 정확하도록 선택한 집계의 고유 버전을 사용하세요. 다음 함수는 unnesting으로 생성된 중복 행을 무시합니다.

  • max()
  • min()
  • array_distinct()
  • count_distinct()

여러 이벤트 변수가 포함된 결과 집계

규칙에 여러 이벤트 변수가 포함된 경우 감지에 포함된 각 이벤트 조합에 대한 집계에 개별 항목이 존재합니다. 예를 들어 나열된 이벤트에 대해 다음 예시 규칙이 실행되는 경우

events:
  $e1.field = $e2.field
  $e2.somefield = $ph

match:
  $ph over 1h

outcome:
   $some_outcome = sum(if($e1.otherfield = "value", 1, 0))

condition:
  $e1 and $e2
event1:
  // UDM event 1
  field="a"
  somefield="d"

event2:
  // UDM event 2
  field="b"
  somefield="d"

event3:
  // UDM event 3
  field="c"
  somefield="d"

합계는 모든 이벤트 조합에 대해 계산되어, 결과 값 계산에 두 이벤트 변수를 모두 사용할 수 있습니다. 계산에 다음 요소가 사용됩니다.

1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2

이 경우 $e2가 3개의 고유 이벤트에만 해당하더라도 잠재적 최대 합계가 6이 됩니다.

이는 합계, 개수, 배열에 영향을 줍니다. 개수 및 배열의 경우에는 count_distinct 또는 array_distinct를 사용하여 문제를 해결할 수 있지만 합계에 대해서는 해결 방법이 없습니다.

표현식 시작 부분의 괄호

괄호로 시작하는 표현식은 지원되지 않으며 규칙 편집기에서 파싱 오류가 트리거됩니다.

잘못된 구문

parsing: error with token: ")"
invalid operator in events predicate

다음 예시에서는 이러한 유형의 오류가 발생합니다.

($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1

유효한 구문 변형

다음 구문 변형은 동일한 결과를 반환하지만 구문이 유효합니다.

$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
    1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
    1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600

결과의 색인 배열에는 집계가 필요함

반복 필드의 경우 outcome 섹션 내에서 배열을 직접 색인화하는 것은 허용되지 않습니다. 임시 자리표시자 변수가 필요합니다.

outcome:
  $principal_user_dept = $suspicious.principal.user.department[0]

해결 방법

events 섹션 내의 자리표시자 변수에 특정 배열 색인을 캡처한 다음 결과에서 해당 자리표시자를 참조합니다.

events:
  $principal_user_dept = $suspicious.principal.user.department[0]

outcome:
  $principal_user_department = $principal_user_dept

존재하지 않는 OR 조건

OR 조건이 두 개의 개별 이벤트 변수 사이에 적용되고, 규칙이 존재하지 않음에 일치하는 경우 규칙은 성공적으로 컴파일되지만 거짓양성 감지를 생성할 수 있습니다.

예를 들어 다음 규칙 구문은 $event_a.field = "something"이 있는 이벤트와 일치하지 않아야 하지만 일치할 수 있습니다.

events:
     not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
     $event_a and #event_b >= 0

해결 방법

논리적 무결성을 유지하기 위해 각 변수에 대해 존재하지 않음 확인을 개별 블록으로 분리합니다.

events:
  not ($event_a.field = "something")
  not ($event_b.field = "something")

condition:
  $event_a and #event_b >= 0

부호 없는 이벤트 필드가 포함된 산술

부호 없는 정수 유형인 UDM 필드를 사용하여 산술 연산에 정수 상수를 사용하려고 하면 오류가 발생합니다. 예를 들면 다음과 같습니다.

events:
  $total_bytes = $e.network.received_bytes * 2

표준 정수 상수는 부호 있는 정수로 기본 설정되며, 이는 network.received_bytes와 같이 부호 없는 정수로 정의된 UDM 필드와 호환되지 않습니다.

해결 방법

나누기 연산을 통해 정수 상수가 부동 소수점처럼 동작하도록 강제하여 이 오류를 우회할 수 있습니다.

events:
  $total_bytes = $e.network.received_bytes * (2/1)

GeoIP 보강 및 eventual consistency

시스템은 초기 보강 단계 (스트리밍 및 지연 시간에 민감함)에서 즉각적인 정확성보다 속도를 우선시하므로 데이터가 누락되고 거짓양성이 발생할 수 있습니다. 시스템은 백그라운드에서 계속 데이터를 보강하지만 규칙이 실행될 때 데이터를 사용하지 못할 수 있습니다. 이는 정상적인 최종 일관성 프로세스의 일부입니다.

강화 지연으로 인한 거짓양성을 방지하려면 값을 평가하기 전에 필드가 비어 있지 않은지 명시적으로 확인하세요.

예를 들어 다음 규칙 이벤트를 고려해 보세요.

$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

이 규칙은 이벤트에 $e.principal.ip_geo_artifact.network.asn = "16509"$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"이 있어야 한다는 사실에 기반하며, 이 두 필드는 모두 리치 필드입니다. 강화가 제때 완료되지 않으면 규칙에서 거짓양성이 발생합니다.

이를 방지하려면 이 규칙에 대한 더 나은 검사는 다음과 같습니다.

$e.principal.ip_geo_artifact.network.asn != "" AND
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

이 규칙은 ASN 16509가 있지만 영국 외부에 있는 IP에 의해 이벤트가 트리거될 가능성을 없앱니다. 이렇게 하면 규칙의 전반적인 정밀도가 향상됩니다.

강화 지연을 문제 해결하는 방법을 알아보세요.

문제 해결

이 섹션에서는 성능 기대치를 설명하고 라이브 감지 동작이 테스트 결과와 다른 일반적인 문제에 대한 셀프 서비스 수정사항을 제공합니다.

미래 날짜의 이벤트

멀티 이벤트 규칙은 수집을 기준으로 시간순으로 이벤트를 처리하도록 설계되었습니다. 멀티 이벤트 규칙을 지정하고 활성화하면 event.timestampingest.timestamp 이후의 날짜와 시간이 설정된 경우와 같이 타임스탬프가 미래인 이벤트에 대한 감지가 생성되지 않습니다.

보강 지연

Google SecOps는 초기 알림을 최대한 빨리 표시하기 위해 수집 속도를 우선시합니다. 하지만 GeoIP, ASN 또는 UDM 메타데이터 해결과 같은 백그라운드 보강 프로세스는 최종 일관성 모델을 따릅니다.

초기 실행 (T₀)

라이브 엔진은 백그라운드 보강이 완료되기 전에 규칙을 평가할 수 있습니다. 로직이 탐지 또는 제외를 위해 풍부한 필드를 사용하는지 여부에 따라 다음과 같은 일시적인 불일치가 발생할 수 있습니다.

  • 거짓음성 (감지 지연): 흔히 발생하는 결과입니다. 규칙이 트리거되기 위해 강화된 필드 (예: target.user.department == "Finance")에 의존하고 해당 필드가 null인 경우 초기 실행 중에 규칙이 일치하지 않습니다.

  • 거짓양성 (제외 누락): 규칙에서 강화된 필드를 사용하여 알려진 양호한 활동 (예: NOT target.ip_geo_country == "US")을 필터링하는 경우 '제외' 데이터가 아직 적용되지 않았기 때문에 규칙에서 거짓양성이 트리거될 수 있습니다.

추가 실행

이러한 백그라운드 실행은 지연 (예: 45분 또는 30시간) 후 데이터를 다시 평가합니다. 이렇게 하면 감지 상태가 다음과 같이 'true'로 설정됩니다.

  • 지연된 감지: T₀에서 '거짓음성'이었던 이벤트가 이제 보강이 완료되면 감지를 생성합니다.

  • 수정: T₀ 거짓양성은 시스템에 남아 있지만 완전히 풍부해진 데이터는 수동 분류를 위해 UDM 뷰어에 표시됩니다.

테스트 불일치 실행

테스트 실행 도구는 이미 조정된 과거 데이터를 기반으로 작동합니다. 수동 테스트를 실행할 때 데이터가 완전히 보강되므로 '조정' 결과를 즉시 확인할 수 있습니다. 즉, 라이브 초기 실행 중에 발생한 T₀ 거짓음성 또는 제외 기반 거짓양성은 표시되지 않습니다.

오류 해결

다음 표를 사용하여 실시간 알림과 테스트 결과 간의 불일치를 해결하세요.

문제 설명 실행 가능한 수정사항
제외 실패 초기 실행 중에 필드가 null이었기 때문에 제외 (예: != "ASN_123")에도 불구하고 규칙이 실행됩니다. 평가 전에 데이터가 보강되도록 이벤트 섹션에 null이 아닌 검사를 추가합니다. 예를 들면 다음과 같습니다.

$e.principal.ip_geo_artifact.network.asn != ""
라이브 경기와 테스트 경기 비교 실시간 규칙은 알림을 트리거하지만 동일한 데이터에 대해 테스트 실행을 하면 "No Results이 표시됩니다. 라이브 및 이전 행동을 동기화하기 위해 모든 풍부한 필드 (GeoIP, ASN, File Path)를 확인하는 $e.field != "" 추가
메타데이터 누락 GeoIP 또는 File Path 필드가 비어 있는 감지가 대시보드에 표시됩니다. 이는 T0 실행에서 예상되는 동작입니다. 이 문제를 해결하려면 field != "" 검사를 포함하거나 실행 일정에서 첫 실행 오프셋을 늘려 인제스트에 더 많은 시간을 할당하세요.

유효성 검사 및 테스트

규칙이 지연된 보강을 올바르게 처리하는지 확인하려면 다음 단계를 따르세요.

  1. 지연 시간 확인: 거짓양성이라고 생각되는 감지를 찾습니다. 감지 유형 열에서 <span class="material-icons">lightbulb</span> 아이콘을 확인합니다. 이 아이콘이 없는 알림은 보강 지연이 가장 흔한 초기 실행에서 발생한 알림입니다.

  2. 규칙 로직 업데이트: 로직에 사용되는 모든 보강된 데이터 포인트에 field != "" 검사를 추가합니다.
    예 (파일 경로):
    $e.target.process.parent_process.file.full_path != ""

  3. 테스트 및 확인:

    • 테스트 실행 기능을 사용하여 로직이 의도한 이전 데이터와 여전히 일치하는지 확인합니다.
    • 이제 보강 필드가 채워지면 규칙이 조정 실행 중에만 트리거되거나 올바르게 제외되는지 확인합니다.

자세한 내용은 규칙 실행 일정 관리규칙의 맞춤 일정 구성을 참고하세요.

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