YARA-L 2.0 언어 구문

이 섹션에서는 YARA-L 문법의 주요 요소들에 대해 설명합니다. YARA-L 2.0 언어 개요도 참조하세요.

규칙 구조

YARA-L 2.0의 경우 변수 선언, 정의, 사용을 다음 순서로 지정해야 합니다.

  1. meta
  2. events
  3. match(선택사항)
  4. outcome(선택사항)
  5. condition
  6. options(선택사항)

다음은 규칙의 일반적인 구조를 보여줍니다.

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

메타 섹션 문법

메타 섹션은 각 줄이 키-값 쌍을 정의하는 여러 줄로 구성됩니다. 키 부분은 인용 부호가 없는 문자열이어야 하고 값 부분은 인용 부호가 있는 문자열이어야 합니다.

<key> = "<value>"

다음은 올바른 meta 섹션 줄의 예시입니다.

meta:
    author = "Google"
    severity = "HIGH"

이벤트 섹션 문법

events 섹션에서 조건자를 나열하여 다음을 지정합니다.

  • 변수 선언
  • 이벤트 변수 필터
  • 이벤트 변수 조인

변수 선언

변수 선언의 경우 다음 문법을 사용합니다.

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

다음 예시에 표시된 것처럼 두 항목은 서로 동일합니다.

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

이 선언에서 이 변수는 이벤트 변수에 대해 지정된 필드를 나타냅니다. 이벤트 필드가 반복되는 필드이면 일치 변수가 해당 배열의 임의 값을 나타낼 수 있습니다. 또한 단일 일치 또는 자리표시자 변수에 여러 이벤트 필드를 지정할 수 있습니다. 이것은 전이적 조인 조건입니다.

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

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

위 문법은 아래 문법과 동일합니다.

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

변수가 사용된 경우 변수 선언을 통해 변수를 선언해야 합니다. 선언 없이 변수가 사용된 경우 컴파일 오류로 간주됩니다.

이벤트 변수 필터

단일 이벤트 변수에서 작동하는 불리언 표현식은 필터로 간주됩니다.

이벤트 변수 조인

규칙에서 사용되는 모든 이벤트 변수는 다음 방법 중 하나로 다른 모든 이벤트 변수와 조인해야 합니다.

  • 조인된 두 이벤트 변수(예: $e1.field = $e2.field)의 이벤트 필드 간에 동등 비교를 통해 직접 조인해야 합니다. 표현식에 산술이 포함되면 안 됩니다.

  • 이벤트 필드만 포함된 전이적 조인을 통해 간접적으로 조인해야 합니다('전이적 조인'의 정의는 변수 선언 참조). 표현식에 산술이 포함되면 안 됩니다.

예를 들어 $e1, $e2 및 $e3이 규칙에 사용된다고 가정하면 다음 events 섹션이 유효합니다.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

하지만 다음은 잘못된 events 섹션의 예시입니다.

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

일치 섹션 문법

match 섹션에서 일치 조건을 확인하기 전 그룹 이벤트에 대해 일치 변수를 나열합니다. 이러한 필드는 각 일치 항목과 함께 반환됩니다.

  • 각 일치 변수가 events 섹션에서 나타내는 대상을 지정하세요.
  • over 키워드 다음에 이벤트와 연결하기 위해 사용할 기간을 지정합니다. 기간 외의 이벤트는 무시됩니다.
  • 기간을 지정하려면 <number><m/h/d> 문법을 사용합니다.

    여기서 m/h/d는 각각 분, 시간, 일을 나타냅니다.

  • 지정할 수 있는 최소 시간은 1분입니다.

  • 지정할 수 있는 최대 시간은 48시간입니다.

다음은 올바른 match 예시입니다.

$var1, $var2 over 5m

이 문은 규칙으로 일치 항목이 발견될 때 $var1$var2(events 섹션에 정의됨)를 반환합니다. 지정된 시간은 5분입니다. 서로 5분 이상 떨어진 이벤트는 상관되지 않으며, 따라서 규칙에서 무시됩니다.

올바른 match 섹션의 예시는 다음과 같습니다.

$user over 1h

이 문은 규칙으로 일치 항목이 발견되었을 때 $user를 반환합니다. 지정된 시간은 1시간입니다. 서로 1시간 이상 떨어진 이벤트는 상관되지 않습니다. 이러한 이벤트는 규칙에서 발견 항목으로 고려되지 않습니다.

올바른 match 섹션의 예시는 다음과 같습니다.

$source_ip, $target_ip, $hostname over 2m

이 문은 규칙으로 일치 항목이 발견될 때 $source_ip, $target_ip, $hostname을 반환합니다. 지정된 시간은 2분입니다. 서로 2시간 이상 떨어진 이벤트는 상관되지 않습니다. 이러한 이벤트는 규칙에서 발견 항목으로 고려되지 않습니다.

다음 예시에서는 잘못된 match 섹션을 보여줍니다.

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

일치 섹션에서 0 값 처리

규칙 엔진은 일치 섹션에서 사용되는 모든 자리 표시자의 0 값(문자열의 경우 "", 숫자의 경우 0, 불리언의 경우 false, 열거 유형의 경우 위치 0의 값)을 암시적으로 필터링합니다. 다음 예시는 0 값을 필터링하는 규칙을 보여줍니다.

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule 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 section,
    // there is no implicit filtering of zero values for $otherPlaceholder.
    $otherPlaceholder = $e.principal.ip

  match:
    $host over 5m

  condition:
    $e
}

하지만 자리표시자가 함수에 할당되면 규칙은 일치 섹션에 사용되는 자리표시자의 0 값을 암시적으로 필터링하지 않습니다. 다음 예시는 0 값을 필터링하는 규칙을 보여줍니다.

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

0 값의 암시적 필터링을 사용 중지하려면 옵션 섹션에서 allow_zero_values 옵션을 사용하면 됩니다.

홉 기간

기본적으로 일치 섹션이 있는 YARA-L 2.0 규칙은 홉 기간을 사용하여 평가됩니다. 규칙 실행 기간은 겹치는 홉 기간 집합으로 분할됩니다. 각각의 홉 기간 집합은 match 섹션에 지정된 기간을 사용합니다. 그런 후 각 홉 창 내의 이벤트에 대해 상관관계가 지정됩니다.

예를 들어 [1:00, 2:00] 기간 동안 실행되는 규칙의 경우 30m 동안 match 섹션을 사용하면 [1:00, 1:30], [1:03, 1:33], [1:06, 1:36]과 같이 겹치는 홉 기간 집합이 생성될 수 있습니다. 이러한 기간은 여러 이벤트를 연결하는 데 사용됩니다.

슬라이딩 기간

홉 기간을 사용하면 특정 순서(예: e2로부터 최대 2분 후 e1 발생)로 발생하는 이벤트를 효과적으로 검색할 수 없습니다. e1 이벤트 발생과 e2 이벤트 발생은 생성된 동일한 홉 기간에 속하는 경우에만 상관관계가 지정됩니다.

이러한 이벤트 시퀀스를 검색하는 더 효과적인 방법은 슬라이딩 기간을 사용하는 것입니다. 지정된 피벗 이벤트 변수로 시작하거나 종료될 때 match 섹션에 지정된 기간의 슬라이딩 기간이 생성됩니다. 그런 후 각 슬라이딩 창 내에서 이벤트에 대해 상관관계가 지정됩니다. 이렇게 하면 e1e2에서 최대 2분 후에 발생하는 등 특정 순서로 발생하는 이벤트를 검색하는 것이 가능하게 됩니다. e1 이벤트 발생과 e2 이벤트 발생은 e2 이벤트 후 슬라이딩 기간 내에 e1 이벤트가 발생할 때 상관관계가 지정됩니다.

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

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

피벗 이벤트 변수는 슬라이딩 기간의 기반이 되는 이벤트 변수입니다. before 키워드를 사용하는 경우 슬라이딩 창이 생성되고 각 피벗 이벤트가 발생하는 것으로 종료됩니다. after 키워드가 사용된 경우 각 피벗 이벤트가 발생하는 것을 시작으로 슬라이딩 기간이 생성됩니다.

다음은 슬라이딩 기간의 올바른 사용 예시입니다.

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

슬라이딩 기간 규칙 예시를 참조하세요.

슬라이딩 기간은 여러 이벤트를 감지하도록 설계되었기 때문에 단일 이벤트 규칙에 슬라이딩 기간을 사용하지 않는 것이 좋습니다. 규칙 중 하나가 이 카테고리에 속하면 다음 해결 방법 중 하나를 사용하는 것이 좋습니다.

  • 여러 이벤트 변수를 사용하도록 규칙을 변환하고 규칙에 두 번 이상의 이벤트 발생이 필요한 경우 조건 섹션을 업데이트합니다.
    • 필요한 경우 슬라이딩 기간을 사용하는 대신 타임스탬프 필터를 추가할 수 있습니다. 예를 들면 $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds입니다.
  • 슬라이딩 기간을 삭제합니다.

결과 섹션 문법

outcome 섹션에서는 최대 20개의 결과 변수를 임의의 이름으로 정의할 수 있습니다. 이러한 결과는 규칙에서 생성한 발견 항목에 저장됩니다. 각 발견 항목은 결과 값이 다를 수 있습니다.

결과 이름 $risk_score는 특수합니다. 원하는 경우 이 이름으로 결과를 정의할 수 있으며, 만들 경우 이는 정수 또는 부동 소수점 유형이어야 합니다. 채워지면 규칙 발견 항목에서 발생하는 알림의 risk_score엔터프라이즈 통계 뷰에 표시됩니다.

규칙의 결과 섹션에 $risk_score 변수를 포함하지 않으면 다음 기본값 중 하나가 설정됩니다.

  • 규칙이 알림을 생성하도록 구성된 경우 $risk_score가 40으로 설정됩니다.
  • 규칙이 알림을 생성하도록 구성되지 않은 경우 $risk_score가 15로 설정됩니다.

$risk_score 값은 security_result.risk_score UDM 필드에 저장됩니다.

결과 변수 데이터 유형

각 결과 변수의 데이터 유형은 다를 수 있으며, 해당 데이터 유형은 이를 계산하는 데 사용되는 표현식으로 결정됩니다. Google에서 지원하는 결과 데이터 유형은 다음과 같습니다.

  • 정수
  • 부동 소수점 수
  • 문자열
  • 정수 목록
  • 부동 소수점 목록
  • 문자열 목록

조건부 로직

조건부 로직을 사용하여 결과 값을 계산할 수 있습니다. 조건부는 다음 문법 패턴을 사용하여 지정됩니다.

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

'if BOOL_CLAUSE가 true이면 THEN_CLAUSE 반환, 그렇지 않으면 ELSE_CLAUSE 반환'과 같은 조건부 표현식을 읽을 수 있습니다.

BOOL_CLAUSE는 부울 값으로 평가되어야 합니다. BOOL_CLAUSE 표현식은 events 섹션의 표현식과 비슷한 형식입니다. 예를 들어 다음을 포함할 수 있습니다.

  • 비교 연산자가 있는 UDM 필드 이름입니다. 예를 들면 다음과 같습니다.

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • events 섹션에서 정의된 자리표시자 변수입니다. 예를 들면 다음과 같습니다.

    if($severity = "HIGH", 100, 0)

  • outcome 섹션에 정의된 또 다른 결과 변수입니다. 예를 들면 다음과 같습니다.

    if($risk_score > 20, "HIGH", "LOW")

  • 부울을 반환하는 함수입니다. 예를 들면 다음과 같습니다.

    if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)

  • 참조 목록을 찾습니다. 예를 들면 다음과 같습니다.

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

  • 집계 비교입니다. 예를 들면 다음과 같습니다.

    if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)

THEN_CLAUSE 및 ELSE_CLAUSE는 같은 데이터 유형이어야 합니다. 정수, 부동 소수점, 문자열을 지원합니다.

데이터 유형이 정수 또는 부동 소수점인 경우 ELSE_CLAUSE를 생략할 수 있습니다. ELSE_CLAUSE가 생략되면 0으로 평가됩니다. 예를 들면 다음과 같습니다.

`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`

데이터 유형이 문자열이거나 THEN_CLAUSE가 자리표시자 변수 또는 결과 변수인 경우 ELSE_CLAUSE를 제공해야 합니다.

수학적 연산

수학적 연산을 사용하여 규칙의 outcomeevents 섹션에서 정수 또는 부동 소수점 데이터 유형을 계산할 수 있습니다. Google Security Operations는 계산의 최상위 연산자로 덧셈, 뺄셈, 곱셈, 나눗셈, 계수를 지원합니다.

다음 스니펫은 outcome 섹션의 계산 예시입니다.

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

각 피연산자 및 전체 산술 표현식이 적절하게 집계되는 한, 다음 유형의 피연산자에 대한 수학 연산이 허용됩니다(집계 참조).

  • 숫자 이벤트 필드
  • events 섹션에 정의된 숫자 자리표시자 변수
  • outcome 섹션에 정의된 숫자 결과 변수
  • 정수 또는 부동 소수점을 반환하는 함수
  • 정수 또는 부동 소수점을 반환하는 집계

계수는 부동 소수점 수에서 허용되지 않습니다.

결과의 자리표시자 변수

결과 변수를 계산할 때 규칙의 이벤트 섹션에 정의된 자리표시자 변수를 사용할 수 있습니다. 이 예시에서는 규칙의 이벤트 섹션에 $email_sent_bytes가 정의되어 있다고 가정합니다.

단일 이벤트 예시:

// No match section, so this is a single-event rule.

outcome:
  // Use placeholder directly as an outcome value.
  $my_outcome = $email_sent_bytes

  // Use placeholder in a conditional.
  $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE")

condition:
  $e

멀티 이벤트 예시:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

결과 할당 표현식의 결과 변수

결과 변수는 events 섹션에 정의된 자리표시자 변수와 비슷한 다른 결과 변수를 파생하는 데 사용될 수 있습니다. $ 토큰 다음에 변수 이름을 사용하여 다른 결과 변수를 할당할 때 결과 변수를 참조할 수 있습니다. 규칙 텍스트에서 결과 변수를 참조하려면 먼저 결과 변수를 정의해야 합니다. 할당 표현식에 사용되는 경우 결과 변수가 집계되지 않아야 합니다(집계 참조).

다음 예시에서 결과 변수 $risk_score는 결과 변수 $event_count에서 값을 파생합니다.

멀티 이벤트 예시:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Aggregates all timestamp on login events in the 5 minute match window.
  $event_count = count($login.metadata.event_timestamp.seconds)
  
  // $event_count cannot be aggregated again.
  $risk_score = if($event_count > 5, "SEVERE", "MODERATE")

  // This is the equivalent of the 2 outcomes above combined.
  $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE")

condition:
  $e

결과 변수는 다음 표현식을 제외하고 결과 할당의 오른쪽에 있는 모든 유형의 표현식에 사용할 수 있습니다.

  • 집계
  • Arrays.length() 함수 호출
  • any 또는 all 수정자 사용

집계

반복 이벤트 필드는 비스칼라 값입니다. 즉, 단일 변수가 여러 값을 가리킵니다. 예를 들어 이벤트 필드 변수 $e.target.ip는 반복되는 필드이며 0개, 1개 또는 여러 개의 IP 값을 가질 수 있습니다. 비스칼라 값입니다. 하지만 이벤트 필드 변수 $e.principal.hostname는 반복되는 필드가 아니며 1개의 값(스칼라 값)만 있게 됩니다.

마찬가지로 일치 기간이 있는 규칙의 결과 섹션에 사용되는 반복되지 않은 이벤트 필드와 반복 이벤트 필드는 모두 비스칼라 값입니다. 예를 들어 다음 규칙은 일치 섹션을 사용하여 이벤트를 그룹화하고 결과 섹션에서 반복되지 않는 이벤트 필드를 참조합니다.

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

규칙이 실행되는 5분 기간에는 이벤트가 0개, 1개 또는 여러 개 포함될 수 있습니다. 결과 섹션은 일치 기간의 모든 이벤트에서 작동합니다. 결과 섹션 내에서 참조되는 모든 이벤트 필드 변수는 일치 기간의 각 이벤트에 대한 0개, 1개 또는 여러 개의 필드 값을 가리킬 수 있습니다. 앞의 규칙에서 5분 기간에 $e 이벤트 5개가 포함된 경우 결과 섹션의 $e.principal.hostname은 5개의 서로 다른 호스트 이름을 가리킵니다. 따라서 이벤트 필드 변수 $e.principal.hostname은 이 규칙의 결과 섹션에 있는 비스칼라 값입니다.

결과 변수는 항상 단일 스칼라 값을 생성해야 하므로 결과 할당이 종속되는 모든 비스칼라 값을 집계하여 단일 스칼라 값을 생성해야 합니다. 결과 섹션에서 다음은 비스칼라 값이며 집계되어야 합니다.

  • 규칙으로 일치 섹션이 사용되는 경우 이벤트 필드(반복 또는 반복되지 않음)
  • 규칙에서 일치 섹션을 사용할 때 이벤트 자리 표시자(반복 또는 반복되지 않음)
  • 규칙에서 일치 섹션을 사용하지 않을 때 반복되는 이벤트 필드
  • 규칙에서 일치 섹션을 사용하지 않을 때 반복되는 이벤트 자리표시자

스칼라 이벤트 필드, 스칼라 이벤트 자리표시자 및 상수는 일치 섹션을 사용하지 않는 규칙의 집계로 래핑될 수 있습니다. 그러나 대부분의 집계는 래핑된 값을 생성하므로 필요하지 않습니다. 단, 스칼라 값을 배열로 변환하는 데 사용할 수 있는 array() 집계는 예외입니다.

결과 변수는 집계처럼 취급됩니다. 즉, 다른 결과 할당에서 참조할 때 다시 집계되면 안 됩니다.

다음 집계 함수를 사용할 수 있습니다.

  • max(): 가능한 모든 값의 최댓값을 반환합니다. 정수 및 부동 소수점으로만 작동합니다.
  • min(): 가능한 모든 값의 최솟값을 반환합니다. 정수 및 부동 소수점으로만 작동합니다.
  • sum(): 가능한 모든 값의 합계를 반환합니다. 정수 및 부동 소수점으로만 작동합니다.
  • count_distinct(): 가능한 모든 값을 수집한 후 가능한 값의 고유한 개수를 반환합니다.
  • count(): count_distinct()와 동일하게 동작하지만 가능한 값의 고유하지 않은 개수를 반환합니다.
  • array_distinct(): 가능한 모든 고유 값을 수집한 후 이러한 값의 목록을 출력합니다. 고유 값 목록은 임의 요소 25개로 잘립니다. 고유 목록을 가져오기 위한 중복 삭제가 먼저 적용된 후 자르기가 적용됩니다.
  • array(): array_distinct()와 동일하게 작동하지만 고유하지 않은 값의 목록을 반환합니다. 또한 값 목록은 25개의 임의 요소로 잘립니다.

집계 함수는 여러 이벤트가 존재해야 함을 지정하는 condition 섹션이 규칙에 포함된 경우에 중요합니다. 집계 함수는 발견 항목을 생성한 모든 이벤트에서 작동하기 때문입니다.

예를 들어 outcomecondition 섹션에 다음이 포함되어 있다고 가정해 보겠습니다.

outcome:
  $asset_id_count = count($event.principal.asset_id)
  $asset_id_distinct_count = count_distinct($event.principal.asset_id)

  $asset_id_list = array($event.principal.asset_id)
  $asset_id_distinct_list = array_distinct($event.principal.asset_id)

condition:
  #event > 1

조건 섹션에서는 발견 항목마다 event가 2개 이상 있어야 하므로 집계 함수는 여러 이벤트에서 작동합니다. 다음 이벤트가 하나의 발견 항목을 생성했다고 가정해 보겠습니다.

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

그러면 다음과 같은 결과가 반환됩니다.

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

결과 섹션 사용 시 주의 사항:

기타 참고사항 및 제한사항:

  • outcome 섹션은 events 섹션 또는 outcome 섹션에 아직 정의되지 않은 새 자리표시자 변수를 참조할 수 없습니다.
  • outcome 섹션은 events 섹션에 정의되지 않은 이벤트 변수를 사용할 수 없습니다.
  • 이벤트 필드가 속한 이벤트 변수가 events 섹션에 이미 정의되어 있으므로 outcome 섹션은 events 섹션에 사용되지 않은 이벤트 필드를 사용할 수 있습니다.
  • outcome 섹션은 events 섹션에서 이미 상관관계가 있는 이벤트 변수만 연결할 수 있습니다. 상관관계는 서로 다른 이벤트 변수의 두 이벤트 필드가 동일할 때 발생합니다.

YARA-L 2.0 개요의 결과 섹션을 사용하여 예시를 찾을 수 있습니다. 결과 섹션에서 발견 항목 중복 제거에 대한 자세한 내용은 컨텍스트 인식 분석 만들기를 참조하세요.

조건 섹션 문법

  • events 섹션에 정의된 이벤트 및 자리표시자에 대해 일치 조건을 지정합니다. 자세한 내용은 다음 섹션인 이벤트 및 자리표시자 조건을 참조하세요.
  • (선택사항) and 키워드를 사용하여 outcome 섹션에서 정의된 결과 변수를 사용하는 일치 조건을 지정합니다. 자세한 내용은 다음 섹션인 결과 조건을 참조하세요.

카운트 문자

# 문자는 condition 섹션에 사용되는 특수문자입니다. 이벤트 또는 자리표시자 변수 이름 앞에 사용될 경우 모든 events 섹션 조건을 충족시키는 고유 이벤트 또는 값 수를 나타냅니다.

예를 들어 #c > 1c 변수가 2회 이상 발생해야 함을 의미합니다.

값 문자

$ 문자는 condition 섹션에 사용되는 특수문자입니다. 결과 변수 이름 앞에 사용될 경우 해당 결과 값을 나타냅니다.

이벤트 또는 자리표시자 변수 이름 앞에 사용될 경우(예: $event) #event > 0을 나타냅니다.

이벤트 및 자리표시자 조건

여기에 andor 키워드와 결합된 이벤트 및 자리표시자 변수의 조건 조건자를 나열합니다. 모든 조건 간에 and 키워드를 사용할 수 있지만 규칙에 단일 이벤트 변수만 있는 경우에만 or 키워드를 사용할 수 있습니다.

다음은 동일한 이벤트의 두 자리표시자 간에 or를 사용하는 유효한 예시입니다.

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

서로 다른 이벤트의 두 조건 간에 or를 사용하는 잘못된 예시는 다음과 같습니다.

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

제한된 조건과 제한되지 않은 조건

다음 조건은 제한된 조건입니다. 이 조건은 연결된 이벤트 변수를 강제로 존재하게 만듭니다. 즉, 어떤 감지 항목에서든 이벤트가 하나 이상 표시되어야 합니다.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

다음 조건은 제한되지 않은 조건입니다. 여기에서는 연결된 이벤트 변수가 존재하지 않아도 됩니다. 즉, 이벤트가 감지에 표시되지 않고 이벤트 변수의 필드에 대한 모든 참조가 0 값이 될 수 있습니다. 제한되지 않은 조건을 사용하여 일정 기간 동안 이벤트의 부재를 감지할 수 있습니다. 예를 들어 10분 이내에 완화 이벤트가 없는 위협 이벤트입니다. 제한되지 않은 조건을 사용하는 규칙을 존재하지 않는 규칙이라고 합니다.

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

존재하지 않는 조건 요구사항

존재하지 않는 조건이 있는 규칙을 컴파일할 경우 다음 요구사항을 충족해야 합니다.

  1. 최소 하나 이상의 UDM 이벤트에 제한된 조건이 있어야 합니다(즉, 하나 이상의 UDM 이벤트가 있어야 함).
  2. 자리표시자에 제한되지 않은 조건이 있는 경우 하나 이상의 제한된 UDM 이벤트와 연결되어야 합니다.
  3. 항목에 제한되지 않은 조건이 있는 경우 하나 이상의 제한된 UDM 이벤트와 연결되어야 합니다.

조건 섹션이 생략된 다음 규칙을 살펴보세요.

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2 
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

다음은 <condition_section>유효한 예시입니다.

  • $u1 and !$u2 and $e1 and $e2
    • 모든 UDM 이벤트 및 항목이 조건 섹션에 있습니다.
    • 하나 이상의 UDM 이벤트가 제한되어 있습니다.
  • $u1 and !$u2 and $e1 and !$e2
    • $e2는 제한되어 있지 않습니다. 이는 제한된 $u1과 연결되기 때문에 허용됩니다. $e2$u1과 연결되지 않은 경우에는 유효하지 않습니다.
  • #port > 50 and #ip = 0
    • 조건 섹션에 UDM 이벤트 및 항목이 없습니다. 하지만 존재하는 자리표시자가 모든 UDM 이벤트 및 항목을 포함합니다.
    • $ip$u1$u2에 모두 할당되며 #ip = 0은 제한되지 않은 조건입니다. 하지만 제한된 조건은 제한되지 않은 조건보다 강력합니다. $port$u1에 할당되고 #port > 50이 제한된 조건이므로 $u1은 여전히 제한됩니다.

다음은 <condition_section>잘못된 예시입니다.

  • $u1 and $e1
    • 이벤트 섹션에 표시되는 모든 UDM 이벤트 및 항목은 조건 섹션에 표시되거나 조건 섹션에 표시되는 자리표시자가 할당되어야 합니다.
  • $u1, $u2, $e1, $u2, #port > 50
    • 쉼표는 조건 구분자로 허용되지 않습니다.
  • !$u1 and !$u2 and $e1 and $e2
    • 하나 이상의 UDM 이벤트가 제한되는 첫 번째 요구사항을 위반합니다.
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • or 키워드는 제한되지 않은 조건에서 지원되지 않습니다.
  • ($u1 or $u2) and $e1 and $e2
    • or 키워드는 서로 다른 이벤트 변수 간에 지원되지 않습니다.
  • not $u1 and $u2 and $e1 and $e2
    • not 키워드는 이벤트 및 자리표시자 조건에 허용되지 않습니다.
  • #port < 50 and #ip = 0
    • 존재하는 자리표시자에 모든 UDM 이벤트 및 항목이 포함됩니다. 그러나 모든 조건은 제한되지 않습니다. 즉, 어떠한 UDM 이벤트도 제한되지 않아 규칙 컴파일이 실패합니다.

결과 조건

키워드 and 또는 or를 조인하거나 또는 키워드 not 앞에 결과 변수에 대한 조건 조건자를 나열합니다.

결과 변수 유형에 따라 결과 조건을 다르게 지정합니다.

  • 정수: =, >, >=, <, <=, != 연산자와 정수 리터럴을 비교합니다. 예를 들면 다음과 같습니다.

    $risk_score > 10

  • 정수: =, >, >=, <, <=, != 연산자와 부동 소수점 리터럴을 비교합니다. 예를 들면 다음과 같습니다.

    $risk_score <= 5.5

  • 문자열: = 또는 != 중 하나와 문자열 리터럴을 비교합니다. 예를 들면 다음과 같습니다.

    $severity = "HIGH"

  • 정수 또는 배열 목록: arrays.contains 함수를 사용하여 조건을 지정합니다. 예를 들면 다음과 같습니다.

    arrays.contains($event_ids, "id_1234")

규칙 분류

일치 섹션이 있는 규칙에서 결과 조건부를 지정하면 규칙이 규칙 할당량에 대해 멀티 이벤트 규칙으로 분류됩니다. 단일 및 여러 이벤트 분류에 대한 자세한 내용은 단일 이벤트 규칙여러 이벤트 규칙을 참조하세요.

옵션 섹션 문법

options 섹션에서는 규칙에 대한 옵션을 지정할 수 있습니다. 다음은 옵션 섹션을 지정하는 방법의 예시입니다.

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

key = value 문법을 사용하여 옵션을 지정할 수 있습니다. 여기서 key는 사전 정의된 옵션 이름이어야 하고 value는 다음 옵션에 대해 지정된 대로 옵션에 유효한 값이어야 합니다.

allow_zero_values

이 옵션에 유효한 값은 이 옵션의 사용 설정 여부를 결정하는 truefalse입니다. 기본값은 false입니다. 이 옵션은 규칙에 지정되지 않으면 사용 중지됩니다.

이 설정을 사용 설정하려면 규칙의 옵션 섹션에 allow_zero_values = true를 추가합니다. 이렇게 하면 일치 섹션에서 0값 처리에 설명된 대로 규칙이 일치 섹션에서 사용되는 자리표시자의 0값을 암시적으로 필터링하지 못합니다.

불리언 표현식

불리언 표현식은 불리언 유형의 표현식입니다.

비교

조건으로 사용할 바이너리 표현식의 경우 다음 문법을 사용합니다.

  • <EXPR> <OP> <EXPR>

표현식은 이벤트 필드, 변수, 리터럴, 함수 표현식일 수 있습니다.

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

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

양쪽 모두 리터럴이면 컴파일 오류로 간주됩니다.

함수

일부 함수는 events 섹션에서 개별 조건자로 사용될 수 있는 부울 값을 반환합니다. 이러한 함수는 다음과 같습니다.

  • re.regex()
  • net.ip_in_range_cidr()

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

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

참조 목록 표현식

이벤트 섹션에서 참조 목록을 사용할 수 있습니다. 자세한 내용은 참조 목록 섹션을 참조하세요.

논리 표현식

다음 예시에 표시된 것처럼 events 섹션에서 논리적 and 및 논리적 or 연산자를 사용할 수 있습니다.

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

기본적으로 우선순위(가장 높은 것에서 가장 낮은 순)는 not, and, or입니다.

예를 들어 orand 연산자가 표현식에 명시적으로 정의된 경우 'a 또는 b 및 c'는 'a 또는 (b 및 c)'로 평가됩니다.

events 섹션에서 연산자가 명시적으로 정의되지 않은 경우 조건자는 and 연산자를 사용하여 조인됩니다.

and 연산자가 표현식에 암시적으로 포함된 경우 평가 순서가 다를 수 있습니다.

예를 들어 or가 명시적으로 정의된 다음 비교 표현식을 살펴보겠습니다. and 연산자는 묵시적입니다.

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

이 예시는 다음과 같이 해석됩니다.

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

or가 명시적으로 정의되었으므로 or 주변의 조건자가 먼저 그룹화되고 평가됩니다. 마지막 조건자 $e2.field = "bar"and를 사용하여 암시적으로 조인됩니다. 결과는 평가 순서 변경입니다.

열거형 유형

연산자는 열거형 유형과 함께 사용할 수 있습니다. 규칙에 적용하여 성능을 단순화하고 최적화(참조 목록 대신 연산자 사용)할 수 있습니다.

다음 예시에서 USER_UNCATEGORIZED' 및 'USER_RESOURCE_DELETION'은 15000와 15014에 해당하므로 규칙은 나열된 모든 이벤트를 찾습니다.

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

이벤트 목록

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

nocase 한정자

문자열 값 또는 정규 표현식 사이에 비교 표현식이 있으면 대소문자 표현을 무시하기 위해 표현식 끝에 nocase를 추가할 수 있습니다.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

필드 유형이 열거된 값인 경우에는 사용할 수 없습니다. 다음 예시는 잘못된 예시이고 컴파일 오류를 일으킵니다.

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

반복 필드

통합 데이터 모델(UDM)에서 일부 필드는 반복 필드로 라벨이 지정되어 값 또는 다른 메시지 유형의 목록임을 나타냅니다.

반복 필드 및 불리언 표현식

반복 필드에서 작동하는 불리언 표현식에는 두 가지 종류가 있습니다.

  1. 수정 시간
  2. 수정되지 않음

다음 이벤트를 고려하세요.

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

수정된 표현식

다음 섹션에서는 표현식에서 anyall 수정자를 사용하는 목적과 방법을 설명합니다.

모두

반복 필드의 요소 중 하나라도 조건을 충족하면 이벤트 전체가 조건을 충족합니다.

  • event_originalany $e.principal.ip = "192.0.2.1"을 충족합니다.
  • event_originalany $e.repeated_field.field_a = "9.9.9.9을 충족하지 않습니다.
모두

반복 필드의 모든 요소가 조건을 충족하면 이벤트 전체가 조건을 충족합니다.

  • event_originalnet.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")을 충족합니다.
  • event_originalall $e.principal.ip = "192.0.2.2"을 충족하지 않습니다.

any 또는 all을 사용하여 조건을 작성할 때 not을 사용하여 조건을 부정하는 것은 부정 연산자를 사용하는 것과 의미가 동일하지 않을 수 있습니다.

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

  • not all $e.principal.ip = "192.168.12.16"은 일부 IP 주소가 192.168.12.16과 일치하지 않는지 확인합니다. 즉, 규칙은 192.168.12.16과 일치하지 않는 IP 주소가 있는지 확인합니다.
  • all $e.principal.ip != "192.168.12.16"은 모든 IP 주소가 192.168.12.16과 일치하지 않는지 확인합니다. 즉, 규칙은 어떤 IP 주소도 192.168.12.16과 일치하는 않는 것을 확인합니다.

제약조건:

  • anyall 연산자는 반복 필드와만 호환됩니다(스칼라 필드가 아님).
  • anyall은 두 개의 반복 필드를 조인하는 데 사용될 수 없습니다. 예를 들어 any $e1.principal.ip = $e2.principal.ip는 잘못되었습니다.
  • anyall 연산자는 참조 목록 표현식에서 지원되지 않습니다.

수정되지 않은 표현식

수정되지 않은 표현식을 사용하면 반복 필드의 각 요소는 개별적으로 취급됩니다. 이벤트의 반복 필드에 n개의 요소가 포함되어 있으면 이벤트의 n개 사본에 규칙이 적용됩니다. 각 사본에는 반복 필드의 요소 중 하나가 포함됩니다. 이러한 사본은 일시적이며 저장되지 않습니다.

이 규칙은 다음 사본에 적용됩니다.

이벤트 사본 principal.ip principal.hostname
event_copy_1 "192.0.2.1" "host"
event_copy_2 "192.0.2.2" "host"
event_copy_3 "192.0.2.3" "host"

이벤트 사본 중 하나라도 반복 필드에서 수정되지 않은 모든 조건을 충족하면 이벤트 전체가 모든 조건을 충족합니다. 즉, 반복 필드에 여러 조건이 있는 경우 이벤트 사본이 모든 조건을 충족해야 합니다. 다음 규칙 예시에서는 앞의 데이터 세트 예시를 사용하여 이 동작을 보여줍니다.

event_copy_1은 모든 이벤트 조건자를 충족하므로 다음 규칙은 event_original 예시 데이터 세트에 대해 실행할 때 하나의 일치 항목을 반환합니다.

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

다음 규칙은 event_original 예시 데이터 세트에 대해 실행 시 일치를 반환하지 않습니다. 모든 이벤트 조건자를 충족하는 $e.principal.ip에는 이벤트 사본이 없기 때문입니다.

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

각 이벤트 사본의 요소 목록이 동일하므로 반복 필드의 수정된 표현식은 반복 필드의 수정되지 않은 표현식과 호환됩니다. 다음 규칙을 살펴보세요.

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1" 
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

이 규칙은 다음 사본에 적용됩니다.

이벤트 사본 principal.ip 모든 $e.principal.ip
event_copy_1 "192.0.2.1" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_2 "192.0.2.2" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_3 "192.0.2.3" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]

이 경우 모든 사본이 any $e.principal.ip = "192.0.2.1"을 충족하지만 event_copy_3만 $e.principal.ip = '192.0.2.3'을 충족합니다. 따라서 이벤트가 전체적으로 일치합니다.

이러한 표현식 유형에 대해 고려할 또 다른 방법은 다음과 같습니다.

  • any 또는 all을 사용하는 반복 필드의 조건은 event_original의 목록에서 작동합니다.
  • any 또는 all을 사용하지 않는 반복 필드의 조건은 개별 event_copy_n 이벤트에서 작동합니다.

반복 필드 및 자리표시자

반복 필드는 자리표시자 할당과 함께 사용할 수 있습니다. 반복 필드의 수정되지 않은 표현식과 마찬가지로 각 요소에 대해 이벤트 사본이 생성됩니다. 자리표시자는 event_copy의 동일한 예시를 사용하여 각 이벤트 사본에 대해 event_copy_n의 반복 필드 값을 가져옵니다. 여기서 n은 이벤트 사본 번호입니다. 자리표시자가 일치 섹션에 사용되면 일치 항목이 여러 개 발생할 수 있습니다.

다음 예시에서는 하나의 일치 항목을 생성합니다. $ip 자리표시자는 event_copy_1192.0.2.1과 동일하며, 규칙의 조건자를 충족합니다. 일치 항목의 이벤트 샘플에는 단일 요소 event_original이 포함됩니다.

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

다음 예시에서는 세 가지 일치 항목을 생성합니다. $ip 자리표시자는 서로 다른 event_copy_n 사본에 대해 다른 값을 갖습니다. 그룹화는 일치 섹션에 있으므로 $ip에서 수행됩니다. 따라서 $ip 일치 변수의 값이 서로 다른 3개의 일치 항목이 생성됩니다. 각 일치 항목에는 단일 요소인 event_original의 동일한 이벤트 샘플이 있습니다.

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

반복 필드에 할당된 자리표시자를 사용한 결과

자리표시자는 전체 목록이 아닌 각 반복 필드의 각 요소에 할당됩니다. 따라서 결과 섹션에서 사용되는 경우 이전 섹션을 충족한 요소만 사용하여 결과가 계산됩니다.

다음 규칙을 살펴보세요.

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

이 규칙에는 4가지 실행 단계가 있습니다. 첫 번째 단계는 이벤트 복사입니다.

이벤트 사본 $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id
event_copy_3 "192.0.2.3" "host" event_id

그러면 이벤트 섹션에서 필터와 일치하지 않는 행을 필터링합니다.

이벤트 사본 $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id

"192.0.2.3"$ip = "192.0.2.1" or $ip = "192.0.2.2"를 충족하지 않아 event_copy_3이 필터링되었습니다.

그런 다음 일치 섹션은 일치 변수별로 그룹화하고 결과 섹션은 각 그룹에 대해 집계를 수행합니다.

$host $o $e
"host" ["192.0.2.1", "192.0.2.2"] event_id

$o = array_distinct($ip)는 이벤트 복사 단계가 아니라 이전 단계의 $ip를 사용하여 계산됩니다.

마지막으로 조건 섹션에서는 각 그룹을 필터링합니다. 이 규칙은 $e의 존재 여부만 확인하므로 앞의 행에서 단일 감지를 생성합니다.

$o$e.principal.ip의 모든 요소를 포함하지 않습니다. 모든 요소가 이벤트 섹션의 모든 조건을 충족하는 것은 아니기 때문입니다. 하지만 이벤트 샘플에 event_original이 사용되기 때문에 e.principal.ip의 모든 요소가 이벤트 샘플에 표시됩니다.

배열 색인 생성

반복 필드에서 배열 색인 생성을 수행할 수 있습니다. n번째 반복 필드 요소에 액세스하려면 표준 목록 문법(요소 색인이 0부터 생성됨)을 사용합니다. 범위를 벗어난 요소는 기본값을 반환합니다.

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" 요소가 1,000개 미만이면 true로 평가됩니다.

제약조건:

  • 색인은 음수가 아닌 정수 리터럴이어야 합니다. 예를 들어 $e.principal.ip[-1]는 잘못되었습니다.
  • int 유형의 값(예: int로 설정된 자리표시자)은 계산되지 않습니다.
  • 배열 색인 생성은 any 또는 all과 결합할 수 없습니다. 예를 들어 any $e.intermediary.ip[0]는 잘못되었습니다.
  • 배열 색인 생성은 map 문법과 결합할 수 없습니다. 예를 들어 $e.additional.fields[0]["key"]는 잘못되었습니다.
  • 필드 경로에 반복 필드가 여러 개 있으면 모든 반복 필드가 배열 색인 생성을 사용해야 합니다. 예를 들어 intermediaryip는 모두 반복 필드이기 때문에 $e.intermediary.ip[0]는 유효하지 않지만 ip에 대한 색인만 있습니다.

반복 메시지

message 필드가 반복되면 의도하지 않은 효과는 일치 가능성을 줄이는 것입니다. 이는 다음 예시에서 확인할 수 있습니다.

다음 이벤트를 고려하세요.

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

반복 필드의 수정되지 않은 표현식에 설명된 대로, 반복 필드의 각 요소에 대해 이벤트의 임시 사본이 만들어집니다. 다음 규칙을 살펴보세요.

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1" 
    $e.about.hostname = "bob"
  condition:
    $e
}

이 규칙은 다음 사본에 적용됩니다.

이벤트 사본 about.ip about.hostname
event_copy_1 "192.0.2.1" "alice"
event_copy_2 "192.0.2.2" "alice"
event_copy_3 "192.0.2.3" "alice"
event_copy_4 "" "bob"

모든 표현식을 충족하는 이벤트 복사본이 없으므로 규칙에서 이벤트가 일치하지 않습니다.

반복 메시지 및 배열 색인 생성

반복 메시지 필드에서 수정되지 않은 표현식으로 배열 색인 생성을 사용할 때 다른 예기치 않은 동작이 발생할 수 있습니다. 배열 색인 생성을 사용하는 다음 규칙 예시를 살펴보세요.

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1" 
    $e.about[1].hostname = "bob"
  condition:
    $e
}

이 규칙은 다음 사본에 적용됩니다.

이벤트 사본 about.ip about[1].hostname
event_copy_1 "192.0.2.1" "bob"
event_copy_2 "192.0.2.2" "bob"
event_copy_3 "192.0.2.3" "bob"
event_copy_4 "" "bob"

event_copy_1repeated_message_2의 모든 표현식을 충족하므로 이벤트가 규칙과 일치합니다.

이로 인해 규칙 repeated_message_1에는 배열 색인 생성이 없고 일치 항목이 생성되지 않았지만 규칙 repeated_message_2는 배열 색인 생성을 사용하고 일치 항목을 생성했으므로 예기치 않은 동작이 발생할 수 있습니다.

설명

2개의 슬래시 문자(// comment)를 사용하여 설명을 지정하거나 C에서와 같이 슬래시와 별표 문자(/* comment */)를 사용하여 여러 줄에 걸친 설명을 지정할 수 있습니다.

리터럴

음수가 아닌 정수 및 부동 소수점 수, 문자열, 불리언, 정규 표현식 리터럴이 지원됩니다.

문자열 및 정규 표현식 리터럴

YARA-L 2.0에서는 다음 인용 문자를 사용하여 문자열을 묶을 수 있습니다. 하지만 인용된 텍스트는 사용 대상에 따라 다르게 해석됩니다.

  1. 큰따옴표(")—일반 문자열에 사용됩니다. 이스케이프 문자를 포함해야 합니다.
    예: 'hello\tworld'—\t가 탭 문자로 해석됩니다.

  2. 뒤쪽 인용부호(`)—모든 문자를 문자 그대로 해석하기 위해 사용됩니다.
    예: `hello\tworld`—\t가 탭 문자로 해석되지 않습니다.

정규 표현식의 경우 두 가지 옵션이 있습니다.

re.regex() 함수 없이 정규 표현식을 직접 사용하려면 정규 표현식 리터럴에 /regex/를 사용합니다.

또한 re.regex() 함수를 사용할 때 문자열 리터럴을 정규 표현식 리터럴로 사용할 수 있습니다. 큰따옴표 문자열 리터럴의 경우 어색해보일 수도 있는 백슬래시 문자로 백슬래시 문자를 이스케이프 처리해야 합니다.

예를 들어 다음 정규 표현식은 서로 동일합니다.

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

가독성을 위해서는 정규 표현식의 문자열에 뒤쪽 인용부호 문자를 사용하는 것이 좋습니다.

연산자

YARA-L에서는 다음 연산자를 사용할 수 있습니다.

연산자 설명
= 같음/선언
!= 같지 않음
< 미만
<= 이하
> 초과
>= 이상

변수

YARA-L 2.0에서는 모든 변수가 $<variable name>으로 표현됩니다.

다음 유형의 변수를 정의할 수 있습니다.

  • 이벤트 변수—정규화된 형태(UDM) 또는 항목 이벤트의 이벤트 그룹을 나타냅니다. events 섹션에서 이벤트 변수의 조건을 지정합니다. 이름, 이벤트 소스, 이벤트 필드를 사용하여 이벤트 변수를 식별합니다. 허용되는 소스는 udm(정규화된 이벤트) 및 graph(항목 이벤트)입니다. 소스가 생략된 경우 udm이 기본 소스로 설정됩니다. 이벤트 필드는 일련의 .<field name>으로 표현됩니다(예: $e.field1.field2). 일련의 이벤트 필드는 항상 최상위 소스(UDM 또는 Entity)로 시작됩니다.

  • 일치 변수—match 섹션에 선언됩니다. 일치 변수는 쿼리의 그룹화 필드가 됩니다. 여기에서 일치 변수의 각 고유 집합에 대해 그리고 각 기간에 대해 하나의 행이 반환됩니다. 규칙으로 일치 항목이 발견되면 일치 변수 값이 반환됩니다. 각 일치 변수가 events 섹션에서 나타내는 대상을 지정하세요.

  • 자리표시자 변수—events 섹션에서 선언되고 정의됩니다. 자리표시자 변수는 일치 변수와 비슷합니다. 하지만 condition 섹션에서 자리표시자 변수를 사용하여 일치 조건을 지정할 수 있습니다.

일치 변수 및 자리표시자 변수를 사용하여 전이적 조인 조건을 통해 이벤트 필드 간의 관계를 선언할 수 있습니다. 자세한 내용은 이벤트 섹션 문법을 참조하세요.

Keywords

YARA-L 2.0의 키워드는 대소문자를 구분하지 않습니다. 예를 들어 and 또는 AND는 동일합니다. 변수 이름이 키워드와 충돌하지 않아야 합니다. 예를 들어 $AND 또는 $outcome은 잘못되었습니다.

다음은 감지 엔진 규칙의 키워드입니다. rule, meta, match, over, events, condition, outcome, options, and, or, not, nocase, in, regex, cidr, before, after, all, any, if, max, min, sum, array, array_distinct, count, count_distinct, is, null.

지도

YARA-L은 구조체 및 라벨에 대한 맵 액세스를 지원합니다.

구조체 및 라벨

일부 UDM 필드는 구조체 또는라벨 데이터 유형을 사용합니다.

구조체와 라벨에서 특정 키-값 쌍을 검색하려면 표준 맵 문법을 사용합니다.

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

지도 액세스는 항상 문자열을 반환합니다.

지원 케이스

이벤트 및 결과 섹션
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
자리표시자에 맵 값 할당
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
조인 조건에서 맵 필드 사용
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

지원되지 않는 케이스

다음과 같은 경우 맵이 지원되지 않습니다.

맵을 사용하여 any 또는 all 키워드 결합

예를 들어 다음은 지원되지 않습니다.

all $e.udm.additional.fields["pod_name"] = "kube-scheduler"
기타 값 유형

맵 문법은 문자열 값만 반환할 수 있습니다. 구조체 데이터 유형의 경우 맵 문법은 값이 문자열인 키에만 액세스할 수 있습니다. 값이 정수와 같은 다른 기본 유형인 키에 액세스할 수 없습니다.

중복 값 처리

맵 액세스는 항상 단일 값을 반환합니다. 드문 경우지만 맵 액세스에서 여러 값을 참조할 수 있는 경우 맵 액세스는 첫 번째 값을 확정적으로 반환합니다.

다음 중 하나의 경우에 발생할 수 있습니다.

  • 라벨에 중복된 키가 있습니다.

    라벨 구조는 지도를 나타내지만 키 고유성을 적용하지는 않습니다. 규칙에 따라 지도에는 고유한 키가 있어야 하므로 Google Security Operations에서는 라벨을 중복 키로 채우지 않는 것이 좋습니다.

    규칙 텍스트 $e.metadata.ingestion_labels["dupe-key"]는 다음 데이터 예시를 대상으로 실행되는 경우 첫 번째 가능한 값인 val1을 반환합니다.

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • 라벨에는 상위 항목 반복 필드가 있습니다.

    반복 필드에는 라벨이 하위 필드로 포함될 수 있습니다. 최상위 반복 필드의 두 가지 서로 다른 항목에는 키가 동일한 라벨이 포함될 수 있습니다. 규칙 텍스트 $e.security_result.rule_labels["key"]는 다음 데이터 예시를 대상으로 실행되는 경우 첫 번째 가능한 값인 val3을 반환합니다.

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

함수

이 섹션에서는 감지 엔진 규칙 및 검색에 사용할 수 있는 YARA-L 2.0 함수를 설명합니다.

이러한 함수는 YARA-L 규칙의 다음 부분에서 사용할 수 있습니다.

arrays.length

다음에서 지원:
arrays.length(repeatedField)

설명

반복 필드 요소의 수를 반환합니다.

매개변수 데이터 유형

LIST

반환 유형

NUMBER

코드 샘플

예 1

반복 필드 요소의 수를 반환합니다.

arrays.length($e.principal.ip) = 2
예 2

경로를 따라 반복 필드가 여러 개 있으면 반복 필드 요소의 총 개수를 반환합니다.

arrays.length($e.intermediary.ip) = 3

디지털 지문

다음에서 지원:
hash.fingerprint2011(byteOrString)

설명

이 함수는 입력 바이트 시퀀스 또는 문자열의 fingerprint2011 해시를 계산합니다. 이 함수는 [2, 0xFFFFFFFFFFFFFFFF] 범위에서 부호 없는 INT 값을 반환합니다.

매개변수 데이터 유형

BTYE, STRING

반환 유형

INT

코드 샘플

id_fingerprint = hash.fingerprint2011("user123")

그룹

다음에서 지원:
group(field1, field2, field3, ...)

설명

비슷한 유형의 필드를 자리표시자 변수로 그룹화합니다.

코드 샘플

예 1

모든 IP 주소를 그룹화하고 스캔된 시간 범위에서 가장 보급된 IP 주소의 내림차순을 제공합니다.

$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
  $ip
outcome:
  $count = count_distinct(metadata.id)
order:
  $count desc

math.abs

다음에서 지원:
math.abs(numericExpression)

설명

정수 또는 부동 소수점 표현식의 절댓값을 반환합니다.

매개변수 데이터 유형

NUMBER

반환 유형

NUMBER

코드 샘플

예 1

이 예시는 이벤트가 지정된 시간 전후에 발생했는지 여부에 관계없이 이벤트가 지정된 시간부터 5분을 초과하면(초 단위, 유닉스 시간 기준) True를 반환합니다. math.abs 호출은 여러 변수나 자리표시자에 따라 달라질 수 없습니다. 예를 들어 다음 예시에서 하드코딩된 시간 값 1643687343을 $e2.metadata.event_timestamp.seconds로 바꿀 수 없습니다.

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

math.log

다음에서 지원:
math.log(numericExpression)

설명

정수 또는 부동 소수점 표현식의 자연 로그 값을 반환합니다.

매개변수 데이터 유형

NUMBER

반환 유형

NUMBER

코드 샘플

예 1
math.log($e1.network.sent_bytes) > 20

math.round

다음에서 지원:
math.round(numericExpression, decimalPlaces)

설명

지정된 소수점 자릿수로 반올림된 부동 표현식의 값을 반환합니다.

매개변수 데이터 유형

NUMBER

반환 유형

NUMBER

코드 샘플

math.round(10.7) // returns 11
math.round(1.2567, 2) // returns 1.25
math.round(-10.7) // returns -11
math.round(-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer

측정항목

다음에서 지원:

측정항목 함수는 대량의 과거 데이터를 집계할 수 있습니다. 결과 섹션에서 metrics.functionName()을 사용하여 규칙에 이를 사용할 수 있습니다.

자세한 내용은 YARA-L 측정항목을 참조하세요.

net.ip_in_range_cidr

다음에서 지원:
net.ip_in_range_cidr(ipAddress, subnetworkRange)

설명

제공된 IP 주소가 지정된 서브네트워크 내에 있으면 true를 반환합니다.

YARA-L을 사용하면 net.ip_in_range_cidr() 문을 사용하여 서브네트워크 내에서 모든 IP 주소로 UDM 이벤트를 검색할 수 있습니다. IPv4 및 IPv6 모두 지원됩니다.

IP 주소 범위로 검색하려면 IP UDM 필드와 CIDR 범위를 지정합니다. YARA-L은 단일 및 반복되는 IP 주소 필드를 모두 처리할 수 있습니다.

IP 주소 범위로 검색하려면 ip UDM 필드와 클래스 없는 도메인 간 라우팅(CIDR) 범위를 지정합니다. YARA-L은 단일 및 반복되는 IP 주소 필드를 모두 처리할 수 있습니다.

매개변수 데이터 유형

STRING, STRING

반환 유형

BOOL

코드 샘플

예 1

IPv4 예시:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
예 2

IPv6 예시:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

net.ip_in_range_cidr() 문을 사용하는 예시 규칙은 IP 주소 범위 내의 단일 이벤트의 예시 규칙을 참조하세요.

re.regex

다음에서 지원:

다음 문법 중 하나를 사용하여 YARA-L 2.0에서 정규 표현식 일치를 정의할 수 있습니다.

  • YARA 문법 사용–이벤트와 관련되어 있습니다. 다음은 이 문법의 일반적인 표현입니다.

    $e.field = /regex/
    
  • YARA-L 문법 사용–다음 문법에서 함수로 사용됩니다.

    • 정규 표현식이 적용되는 필드입니다.
    • 문자열로 지정된 정규 표현식입니다.

    다음은 이 문법의 일반적인 표현입니다.

    re.regex($e.field, `regex`)
    

설명

이 함수는 문자열에 제공된 정규 표현식과 일치하는 하위 문자열이 포함되면 true를 반환합니다. 정규 표현식의 시작 또는 끝 부분에 .*를 추가할 필요는 없습니다.

참고
  • 정확한 문자열 또는 프리픽스나 서픽스만 일치하는 항목을 찾으려면 정규 표현식에 ^(시작) 및 $(종료) 앵커 문자를 포함하세요. 예를 들어 /^full$/"full"과 정확하게 일치하지만 /full/"fullest", "lawfull", "joyfully"와 일치할 수 있습니다.
  • UDM 필드에 줄바꿈 문자가 포함되면 regexp는 UDM 필드의 첫 번째 줄만 일치합니다. 전체 UDM 필드 일치를 적용하려면 (?s)를 정규 표현식에 추가합니다. 예를 들어 /.*allUDM.*//(?s).*allUDM.*/으로 바꿉니다.
  • 문자열 다음에 nocase 한정자를 사용하여 검색 시 대소문자를 무시하도록 지정할 수 있습니다.

매개변수 데이터 유형

STRING, STRING

매개변수 표현식 유형

ANY, ANY

반환 유형

BOOL

코드 샘플

예 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

다음에서 지원:
re.capture(stringText, regex)

설명

인수에 제공된 정규 표현식 패턴을 사용하여 문자열에서 데이터를 캡처(추출)합니다.

이 함수에는 두 개의 인수가 사용됩니다.

  • stringText: 검색할 원래 문자열입니다.
  • regex: 검색할 패턴을 나타내는 정규 표현식입니다.

정규 표현식은 0 또는 1 캡처 그룹을 괄호로 포함할 수 있습니다. 정규 표현식에 0 캡처 그룹이 포함된 경우 함수가 첫 번째 전체 일치 하위 문자열을 반환합니다. 정규 표현식에 1 캡처 그룹이 포함된 경우 캡처 그룹의 첫 번째 일치 하위 문자열을 반환합니다. 캡처 그룹을 2개 이상 정의하면 컴파일 오류가 반환됩니다.

매개변수 데이터 유형

STRING, STRING

반환 유형

STRING

코드 샘플

예 1

이 예시에서 $e.principal.hostname에 'aaa1bbaa2'가 포함되면 함수가 첫 번째 인스턴스를 반환하므로 다음이 True입니다. 이 예시에는 캡처 그룹이 없습니다.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
예 2

이 예시에서는 이메일에서 @ 기호 다음에 있는 모든 내용을 캡처합니다. $e.network.email.from 필드가 test@google.com이면 예시에서 google.com을 반환합니다. 다음 예시에는 캡처 그룹 하나가 포함되어 있습니다.

"google.com" = re.capture($e.network.email.from , "@(.*)")
예 3

정규 표현식이 텍스트의 하위 문자열과 일치하지 않으면 함수는 빈 문자열을 반환합니다. 빈 문자열을 제외하여 일치하는 항목이 없는 이벤트를 생략할 수 있습니다. 이는 re.capture()를 불일치로 사용하는 경우에 특히 중요합니다.

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

다음에서 지원:
re.replace(stringText, replaceRegex, replacementText)

설명

정규 표현식 교체를 수행합니다.

이 함수에는 3개의 인수가 있습니다.

  • stringText: 원래 문자열입니다.
  • replaceRegex: 검색할 패턴을 나타내는 정규 표현식입니다.
  • replacementText: 각 일치 항목에 삽입할 텍스트입니다.

원래 stringText에서 파생된 새 문자열을 반환합니다. 여기서 replaceRegex의 패턴과 일치하는 모든 하위 문자열은 replacementText의 값으로 바뀝니다. replacementText 내에 백슬래시로 이스케이프 처리된 숫자(\1~\9)를 사용하여 replaceRegex 패턴에서 괄호로 묶인 해당 그룹과 일치하는 텍스트를 삽입할 수 있습니다. 전체 일치 텍스트를 나타내려면 \0을 사용합니다.

이 함수는 겹치지 않는 일치 항목을 교체하며 발견된 첫 번째 일치 항목을 교체하는 데 우선순위를 둡니다. 예를 들어 re.replace("banana", "ana", "111")는 'b111na' 문자열을 반환합니다.

매개변수 데이터 유형

STRING, STRING, STRING

반환 유형

STRING

코드 샘플

예 1

이 예시에서는 이메일에서 @ 기호 다음에 있는 모든 것을 캡처하고 comorg로 바꾼 후 해당 결과를 반환합니다. 중첩 함수 사용을 확인하세요.

"email@google.org" = re.replace($e.network.email.from, "com", "org")
예 2

이 예시에서는 replacementText 인수에 백슬래시로 이스케이프 처리된 숫자를 사용하여 replaceRegex 패턴과의 일치 항목을 참조합니다.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
예 3

빈 문자열과 re.replace()를 처리할 때는 다음 사례에 유의하세요.

빈 문자열을 replaceRegex로 사용:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

빈 문자열을 바꾸려면 "^$"replaceRegex로 사용:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

sample_rate

다음에서 지원:
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)

설명

이 함수는 확정적 샘플링 전략에 따라 이벤트를 포함할지 여부를 결정합니다. 이 함수는 다음을 반환합니다.

  • (rateNumerator / rateDenominator)와 동일한 입력 값의 일부에서 true는 이벤트가 샘플에 포함되어야 함을 나타냅니다.
  • false는 이벤트가 샘플에 포함되면 안 된다는 것을 나타냅니다.

이 함수는 이벤트의 하위 집합만 처리하려는 최적화 시나리오에 유용합니다. 다음과 같습니다.

hash.fingerprint2011(byteOrString) % rateDenominator < rateNumerator

매개변수 데이터 유형

  • byteOrString: BYTE 또는 STRING으로 평가되는 표현식입니다.
  • rateNumerator: 'INT'
  • rateDenominator: 'INT'

반환 유형

BOOL

코드 샘플

events:
    $e.metadata.event_type = "NETWORK_CONNECTION"
    $asset_id = $e.principal.asset.asset_id
    optimization.sample_rate($e.metadata.id, 1, 5) // Only 1 out of every 5 events

  match:
    $asset_id over 1h

  outcome:
    $event_count = count_distinct($e.metadata.id)
  // estimate the usage by multiplying by the inverse of the sample rate
    $usage_past_hour = sum(5.0 * $e.network.sent_bytes)

 condition:
  // Requiring a certain number of events after sampling avoids bias (e.g. a
  // device with just 1 connection will still show up 20% of the time and
  // if we multiply that traffic by 5, we'll get an incorrect estimate)
  $e and ($usage_past_hour > 1000000000) and $event_count >= 100

strings.base64_decode

다음에서 지원:
strings.base64_decode(encodedString)

설명

인코딩된 문자열을 base64로 디코딩한 버전이 포함된 문자열을 반환합니다.

이 함수는 하나의 base64 인코딩 문자열을 인수로 사용합니다. encodedString이 올바른 base64로 인코딩된 문자열이 아니면 함수에서 encodedString을 변경하지 않고 반환합니다.

매개변수 데이터 유형

STRING

반환 유형

STRING

코드 샘플

예 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

다음에서 지원:
strings.coalesce(a, b, c, ...)

설명

이 함수는 인수를 무제한으로 사용하고 빈 문자열로 평가되지 않는 첫 번째 표현식의 값을 반환합니다(예: '0이 아닌 값'). 모든 인수가 빈 문자열로 평가되면 함수 호출에서 빈 문자열을 반환합니다.

인수는 리터럴, 이벤트 필드 또는 함수 호출일 수 있습니다. 모든 인수는 STRING 유형이어야 합니다. 인수가 이벤트 필드인 경우 속성은 동일한 이벤트에서 생성되어야 합니다.

매개변수 데이터 유형

STRING

반환 유형

STRING

코드 샘플

예 1

다음 예시에는 문자열 변수를 인수로 포함합니다. (1) $e.network.email.fromsuspicious@gmail.com이거나 (2) $e.network.email.from이 비어 있고 $e.network.email.tosuspicious@gmail.com이면 조건이 True로 평가됩니다.

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
예 2

다음 예시에서는 인수가 3개 이상 있는 coalesce 함수를 호출합니다. 이 조건은 $e 이벤트에서 null이 아닌 첫 번째 IP 주소를 참조 목록 ip_watchlist의 값과 비교합니다. 이 호출에서 인수가 병합되는 순서는 규칙 조건에 열거되는 순서와 같습니다.

  1. $e.principal.ip가 먼저 평가됩니다.
  2. $e.src.ip가 다음에 평가됩니다.
  3. $e.target.ip가 다음에 평가됩니다.
  4. 마지막으로, 이전 ip 필드가 설정되지 않은 경우 'No IP' 문자열이 기본값으로 반환됩니다.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
예 3

다음 예시에서는 이벤트 $e1 및 이벤트 $e2principal.hostname을 병합하려고 시도합니다. 인수가 서로 다른 이벤트 변수이므로 컴파일러 오류가 반환됩니다.

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

다음에서 지원:
strings.concat(a, b, c, ...)

설명

무제한 항목 연결을 반환합니다. 각 항목은 문자열, 정수 또는 부동 소수점 수일 수 있습니다.

인수가 이벤트 필드인 경우 속성은 동일한 이벤트에서 생성되어야 합니다.

매개변수 데이터 유형

STRING, FLOAT, INT

반환 유형

STRING

코드 샘플

예 1

다음 예시에는 문자열 변수와 정수 변수가 인수로 포함됩니다. principal.hostnameprincipal.port 모두 같은 이벤트인 $e에서 생성 및 연결되어 문자열을 반환합니다.

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
예 2

다음 예시에는 문자열 변수와 문자열 리터럴이 인수로 포함됩니다.

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
예 3

다음 예시에는 문자열 변수와 부동 소수점 리터럴이 인수로 포함됩니다. 문자열로 표현될 경우 정수인 부동 소수점 수는 소수점 없이 형식으로 지정됩니다(예: 1.0은 '1'로 표시). 또한 16자리를 초과하는 부동 소수점 수는 소수점 이하 16번째 자리에서 잘립니다.

"google2.5" = strings.concat($e.principal.hostname, 2.5)
예 4

다음 예시에는 문자열 변수, 문자열 리터럴, 정수 변수, 부동 리터럴이 인수로 포함됩니다. 모든 변수는 같은 이벤트인 $e에서 생성되고 리터럴과 연결되어 문자열을 반환합니다.

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
예시 5

다음 예시에서는 이벤트 $e1의 principal.port를 이벤트 $e2principal.hostname과 연결하려고 시도합니다. 인수가 서로 다른 이벤트 변수이므로 컴파일러 오류가 반환됩니다.

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.to_lower

다음에서 지원:
strings.to_lower(stringText)

설명

이 함수는 입력 문자열을 가져와 모든 문자를 소문자로 변경한 후 문자열을 반환합니다.

매개변수 데이터 유형

STRING

반환 유형

STRING

코드 샘플

예 1

다음 예시에서는 true를 반환합니다.

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

다음에서 지원:
strings.to_upper(stringText)

설명

이 함수는 입력 문자열을 가져와 모든 문자를 대문자로 변경한 후 문자열을 반환합니다.

매개변수 데이터 유형

STRING

반환 유형

STRING

코드 샘플

예 1

다음 예시에서는 true를 반환합니다.

"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

timestamp.current_seconds

다음에서 지원:
timestamp.current_seconds()

설명

Unix 초로 현재 시간을 나타내는 정수를 반환합니다. 발견 항목 타임스탬프와 대략적으로 동일하고 규칙이 실행된 시간을 기반으로 합니다.

매개변수 데이터 유형

NONE

반환 유형

INT

코드 샘플

예 1

다음 예시에서는 인증서가 24시간을 초과하여 만료되면 true를 반환합니다. 현재 Unix 초를 빼고 크거나 같음 연산자를 사용하여 비교하는 방식으로 시간 차이를 계산합니다.

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

다음에서 지원:
timestamp.get_date(unix_seconds [, time_zone])

설명

이 함수는 타임스탬프가 있는 날짜를 나타내는 YYYY-MM-DD 형식의 문자열을 반환합니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • time_zone은 선택사항이며 time_zone을 나타내는 문자열입니다. 생략한 경우 기본값은 'GMT'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING

반환 유형

STRING

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값은 'GMT'입니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

다음에서 지원:
timestamp.get_minute(unix_seconds [, time_zone])

설명

이 함수는 분을 나타내는 [0, 59] 범위의 정수를 반환합니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • time_zone은 선택사항이며 시간대를 나타내는 문자열입니다. 생략한 경우 기본값은 'GMT'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING

반환 유형

INT

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값은 'GMT'입니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

다음에서 지원:
timestamp.get_hour(unix_seconds [, time_zone])

설명

이 함수는 시간을 나타내는 [0, 23] 범위의 정수를 반환합니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • time_zone은 선택사항이며 시간대를 나타내는 문자열입니다. 생략한 경우 기본값은 'GMT'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING

반환 유형

INT

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값은 'GMT'입니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

다음에서 지원:
timestamp.get_day_of_week(unix_seconds [, time_zone])

설명

이 함수는 일요일부터 시작하는 한 주의 요일을 나타내는 [1, 7] 범위의 정수를 반환합니다. 예를 들어 1은 일요일, 2는 월요일입니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • time_zone은 선택사항이며 time_zone을 나타내는 문자열입니다. 생략한 경우 기본값은 'GMT'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING

반환 유형

INT

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값은 'GMT'입니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_timestamp

다음에서 지원:
timestamp.get_timestamp(unix_seconds, optional timestamp_format, optional timezone)

설명

이 함수는 타임스탬프가 있는 날짜를 나타내는 YYYY-MM-DD 형식의 문자열을 반환합니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • timestamp_format은 선택사항이며 타임스탬프 형식을 나타내는 문자열입니다. 생략할 경우 기본값은 %F %T입니다. 문자열 리터럴을 사용하여 형식을 지정할 수 있습니다. 옵션은 날짜 및 시간 부분의 형식 요소 지정을 참조하세요.
  • time_zone은 선택사항이며 시간대를 나타내는 문자열입니다. 생략할 경우 기본값은 GMT입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.
    • IANA 시간대(TZ) 데이터베이스 이름입니다(예: America/Los_Angeles). 자세한 내용은 Wikipedia의 tz 데이터베이스 시간대 목록을 참조하세요.
    • UTC의 시간대 오프셋은 (+|-)H[H][:M[M]] 형식으로 지정됩니다(예: '-08:00').

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING, STRING

반환 유형

STRING

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값으로 GMT가 설정됩니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts) = "2024-02-22 10:43:51"
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%F %T", "America/Los_Angeles") = "2024-02-22 10:43:51"
예시 3

이 예시에서는 문자열 리터럴을 사용하여 timestamp_format을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%Y-%m", "GMT") = "2024-02"

timestamp.get_week

다음에서 지원:
timestamp.get_week(unix_seconds [, time_zone])

설명

이 함수는 해당 연도의 주를 나타내는 [0, 53] 범위의 정수를 반환합니다. 주는 일요일부터 시작됩니다. 해당 연도의 첫 번째 일요일 이전의 날짜는 주 0에 포함됩니다.

  • unix_seconds는 유닉스 시간을 기준으로 지난 초 수(예: $e.metadata.event_timestamp.seconds)를 나타내는 정수이거나 해당 값을 포함하는 자리표시자입니다.
  • time_zone은 선택사항이며 시간대를 나타내는 문자열입니다. 생략한 경우 기본값은 'GMT'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.

다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 time_zone 지정자의 예시입니다.

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

매개변수 데이터 유형

INT, STRING

반환 유형

INT

코드 샘플

예 1

이 예시에서는 time_zone 인수가 생략되었으므로 기본값은 'GMT'입니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
예 2

이 예시에서는 문자열 리터럴을 사용하여 time_zone을 정의합니다.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

자리표시자 할당 함수

events 섹션의 자리표시자에 함수 호출 결과를 할당할 수 있습니다. 예를 들면 다음과 같습니다.

$placeholder = strings.concat($e.principal.hostname, "my-string").

그런 다음 match, condition, outcome 섹션에서 자리표시자 변수를 사용할 수 있습니다. 그러나 자리표시자 할당 함수에는 두 가지 제한사항이 있습니다.

  1. 자리표시자 할당 함수의 모든 자리표시자는 이벤트 필드가 포함된 표현식에 할당해야 합니다. 예를 들어 다음 예시는 유효합니다.

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    그러나 다음 예시는 잘못되었습니다.

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. 함수 호출은 단 하나의 이벤트에 의존해야 합니다. 그러나 동일한 이벤트의 두 개 이상의 필드를 함수 호출 인수에 사용할 수 있습니다. 예를 들어 다음은 유효합니다.

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    하지만 다음은 유효하지 않습니다.

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

참조 목록 문법

참조 목록 동작 및 참조 목록 문법에 대한 자세한 내용은 참조 목록 페이지를 참조하세요.

events 또는 outcome 섹션에서 참조 목록을 사용할 수 있습니다. 다음은 규칙에 다양한 유형의 참조 목록을 사용하기 위한 문법입니다.

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

다음 예시와 같이 not 연산자와 nocase 연산자를 참조 목록과 함께 사용할 수도 있습니다.

// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list

// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase

nocase 연산자는 STRING 목록 및 REGEX 목록과 호환됩니다.

성능상의 이유로 Detection Engine은 참조 목록 사용을 제한합니다.

  • 특수 연산자가 있거나 없는 규칙의 최대 in 문: 7개
  • regex 연산자가 있는 최대 in 문: 4개
  • cidr 연산자가 있는 최대 in 문: 2개

유형 확인

Google Security Operations는 개발자가 인터페이스 내에 규칙을 만들 때 YARA-L 문법에 대해 유형 검사를 수행합니다. 표시된 유형 확인 오류는 이러한 방법으로 규칙을 수정하여 올바르게 작동하는지 확인하는 데 도움이 됩니다.

다음은 잘못된 조건자 예시입니다.

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

감지 이벤트 샘플링

멀티 이벤트 규칙의 감지에는 감지를 유발한 이벤트에 대한 컨텍스트를 제공하는 이벤트 샘플이 포함됩니다. 규칙에 정의된 각 이벤트 변수의 이벤트 샘플은 최대 10개로 제한됩니다. 예를 들어 규칙에서 2개의 이벤트 변수를 정의하는 경우 각 발견 항목에는 최대 20개의 이벤트 샘플이 있을 수 있습니다. 이 한도는 각 이벤트 변수에 개별적으로 적용됩니다. 이 감지에 적용 가능한 이벤트 2개가 있고 다른 이벤트 변수에 해당 이벤트가 15개 있는 경우 결과 감지에 12개의 이벤트 샘플(2 + 10)이 포함됩니다.

한도를 초과하는 이벤트 샘플은 감지에서 생략됩니다.

감지를 발생시킨 이벤트에 대한 자세한 내용을 알아보려면 결과 섹션의 집계를 사용하여 감지의 추가 정보를 출력하면 됩니다.

UI에서 감지를 보는 경우 감지에 대한 모든 이벤트 샘플을 다운로드할 수 있습니다. 자세한 내용은 이벤트 다운로드를 참조하세요.