반복 필드

다음에서 지원:

통합 데이터 모델(UDM)에서 일부 필드는 반복 필드로 라벨이 지정되어 값 또는 다른 메시지 유형의 목록임을 나타냅니다. 이 문서에서는 반복되는 UDM 필드에 표현식, 자리표시자, 배열 색인, 반복 메시지를 사용하는 방법을 설명합니다.

불리언 표현식 및 반복 필드

수정된 불리언 표현식과 수정되지 않은 불리언 표현식은 반복 필드에서 작동할 수 있습니다.

다음 이벤트를 고려해 보세요.

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

    hostname: "host"
  }
}

수정된 표현식

반복 필드의 표현식에서 anyall 수정자를 사용합니다.

  • any - 반복 필드의 요소 중 하나라도 조건을 충족하면 이벤트 전체가 조건을 충족합니다. 예를 들면 다음과 같습니다.

    • event_originalany $e.principal.ip = "192.0.2.1"을 충족함
    • event_originalany $e.repeated_field.field_a = "9.9.9.9"을 충족하지 않음
  • all - 반복 필드의 모든 요소가 조건을 충족하면 이벤트 전체가 조건을 충족합니다. 예를 들면 다음과 같습니다.

    • 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_1` 의 경우 `192.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
}

다음 예시에서는 3개의 일치 항목을 생성합니다. $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
}

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

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

다음 규칙을 고려하세요.

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이 필터링되었습니다.

그러면 match 섹션에서 일치 변수별로 그룹화하고 outcome 섹션에서 각 그룹에 대해 집계를 실행합니다.

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

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

마지막으로 condition 섹션에서 각 그룹을 필터링합니다. 이 규칙은 $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는 모두 반복 필드이지만 ip에만 색인이 있으므로 $e.intermediary.ip[0]는 유효하지 않습니다.

반복되는 메시지

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는 배열 색인 생성을 사용하고 일치 항목을 생성했으므로 예기치 않은 동작이 발생할 수 있습니다.

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