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

이 문서에서는 YARA-L의 알려진 문제 및 제한사항에 대해 설명합니다.

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

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

예를 들어 이벤트 $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
}

반복 필드 중첩 해제 전의 이벤트 레코드

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

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 ] } ]

반복 필드 중첩 해제 후의 이벤트 레코드

다음 표에는 반복 필드의 중첩을 해제한 후의 이벤트 레코드가 나와 있습니다.

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 차단

해결 방법

중복 값을 무시하거나 중복 값을 삭제하는 집계는 이러한 중첩 해제 동작의 영향을 받지 않습니다. 중첩 해제로 인해 예기치 않은 결과 값이 발생할 경우 집계의 고유 버전을 사용합니다.

다음 집계는 앞에서 설명한 중첩 해제 동작의 영향을 받지 않습니다.

  • 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:
  $principal_user_dept = $suspicious.principal.user.department[0]

그러나 배열 색인의 출력을 자리표시자 변수에 저장하고 다음과 같이 결과 섹션에서 해당 변수를 사용할 수 있습니다.

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

udm.network.received_bytes 필드는 부호 없는 정수입니다. 부호 있는 정수로 기본 설정된 정수 상수로 인해 발생하며, 산술 연산에서 부호 없는 정수를 사용하면 작동하지 않습니다.

해결 방법은 정수 상수를 부동 소수점 수로 강제 설정하여 부호 없는 정수와 함께 사용하는 것입니다. 예를 들면 다음과 같습니다.

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로 인해 이벤트가 트리거될 가능성이 제거됩니다. 이렇게 하면 규칙의 전반적인 정확성이 향상됩니다.