YARA-L 2.0 언어 개요

다음에서 지원:

YARA-L 2.0은 기업 로그 데이터가 Google Security Operations 인스턴스에 수집될 때 이 데이터를 검색할 수 있는 규칙을 만들기 위해 사용되는 컴퓨터 언어입니다. YARA-L 구문은 VirusTotal에서 개발된 YARA 언어로부터 파생됩니다. 이 언어는 Google SecOps Detection Engine과 함께 작동하며 대량의 데이터에 대해 위협 요소 및 기타 이벤트를 찾을 수 있게 해줍니다.

자세한 내용은 다음을 참조하세요.

YARA-L 2.0 예시 규칙

다음 예시는 YARA-L 2.0으로 작성된 규칙을 보여줍니다. 각 항목은 규칙 언어 내에서 이벤트의 상관관계를 지정하는 방법을 보여줍니다.

규칙 및 조정

다음 규칙은 이벤트 데이터의 특정 패턴을 확인하고 패턴이 발견되면 감지를 만듭니다. 이 규칙에는 이벤트 유형과 metadata.event_type UDM 필드를 추적할 수 있도록 $e1 변수가 포함됩니다. 이 규칙은 e1과 일치하는 정규 표현식 특정 일치 항목을 확인합니다. $e1 이벤트가 발생하면 감지가 생성됩니다. not 조건은 악성이 아닌 특정 경로를 제외하는 규칙에 포함되어 있습니다. not 조건을 추가하여 거짓양성을 방지할 수 있습니다.

rule suspicious_unusual_location_svchost_execution
{

 meta:
   author = "Google Cloud Security"
   description = "Windows 'svchost' executed from an unusual location"
   yara_version = "YL2.0"
   rule_version = "1.0"

 events:

   $e1.metadata.event_type = "PROCESS_LAUNCH"
   re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
   not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase

condition:

   $e1
}

다른 도시의 로그인

다음 규칙은 5분 이내에 두 개 이상의 도시에서 회사에 로그인한 사용자를 검색합니다.

rule DifferentCityLogin {
  meta:

  events:
    $udm.metadata.event_type = "USER_LOGIN"
    $udm.principal.user.userid = $user
    $udm.principal.location.city = $city

  match:
    $user over 5m

  condition:
    $udm and #city > 1
}

일치 변수: $user

이벤트 변수:$udm

자리표시자 변수: $city$user

다음은 이 규칙의 작동 방법을 설명합니다.

  • 이벤트를 사용자 이름($user)과 그룹으로 묶고 일치가 발견되면 이를 반환($user)합니다.
  • 기간은 5분입니다. 즉, 서로 5분 이내에 발생하는 이벤트만 상관관계가 지정됩니다.
  • 해당 이벤트 유형이 USER_LOGIN인 이벤트 그룹($udm)을 검색합니다.
  • 이 이벤트 그룹에 대해 이 규칙은 사용자 ID를 $user로 호출하고 로그인 도시를 $city.로 호출합니다.
  • city 값(#city로 표시됨)의 고유 숫자가 이벤트 그룹($udm)에서 5분 기간 내에 1보다 크면 일치를 반환합니다.

빠른 사용자 만들기 및 삭제

다음 규칙은 생성되고 4시간 내에 삭제된 사용자를 검색합니다.

rule UserCreationThenDeletion {
  meta:

  events:
    $create.target.user.userid = $user
    $create.metadata.event_type = "USER_CREATION"

    $delete.target.user.userid = $user
    $delete.metadata.event_type = "USER_DELETION"

    $create.metadata.event_timestamp.seconds <=
       $delete.metadata.event_timestamp.seconds

  match:
    $user over 4h

  condition:
    $create and $delete
}

이벤트 변수: $create$delete

일치 변수: $user

자리표시자 변수: 해당 없음

다음은 이 규칙의 작동 방법을 설명합니다.

  • 이벤트를 사용자 이름($user)과 그룹으로 묶고 일치가 발견되면 이를 반환($user)합니다.
  • 기간은 4시간이며, 간격이 4시간 미만인 이벤트만 상관관계가 지정됩니다.
  • $create#create >= 1과 동일한 2개의 이벤트 그룹($create$delete)을 검색합니다.
  • $createUSER_CREATION 이벤트에 해당하며 사용자 ID를 $user로 호출합니다.
  • $user는 2개의 이벤트 그룹을 하나로 조인하기 위해 사용됩니다.
  • $deleteUSER_DELETION 이벤트에 해당하며 사용자 ID를 $user로 호출합니다. 이 규칙은 두 이벤트 그룹의 사용자 식별자가 동일한 일치를 찾습니다.
  • 이 규칙은 $delete의 이벤트가 $create의 이벤트보다 늦게 발생하는 경우를 찾고, 발견되면 일치를 반환합니다.

단일 이벤트 규칙

단일 이벤트 규칙은 단일 이벤트에 대한 상관관계가 있는 규칙입니다. 단일 이벤트 규칙은 다음과 같을 수 있습니다.

  • 일치 섹션이 없는 모든 규칙
  • 1개 이벤트 존재만 확인하는 match 섹션 및 condition 섹션의 규칙(예: "$e", "#e > 0", "#e >= 1", "1 <= #e", "0 < #e")

예를 들어 다음 규칙은 사용자 로그인 이벤트를 검색하고 Google SecOps 계정 내에 저장된 기업 데이터 내에서 발생하는 첫 번째 항목을 반환합니다.

rule SingleEventRule {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"

  condition:
    $e
}

다음은 일치 섹션이 있는 단일 이벤트 규칙의 예시입니다. 이 규칙은 5분 이내에 한 번 이상 로그인한 사용자를 검색합니다. 사용자 로그인 이벤트의 단순한 존재를 확인합니다.

rule SingleEventRule {
  meta:
    author = "alice@example.com"
    description = "windowed single event example rule"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 5m

  condition:
    #e > 0
}
rule MultiEventRule{
  meta:
    author = "alice@example.com"
    description = "Rule with outcome condition and simple existence condition on one event variable"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 10m

  outcome:
    $num_events_in_match_window = count($e.metadata.id)

  condition:
    #e > 0 and $num_events_in_match_window >= 10 // Could be rewritten as #e >= 10
}

여러 이벤트 규칙

여러 이벤트 규칙을 사용하여 지정된 기간 동안 많은 이벤트를 그룹화하고 이벤트 간 상관관계를 찾습니다. 일반적인 여러 이벤트 규칙에는 다음이 포함됩니다.

  • 이벤트를 그룹화해야 하는 시간 범위를 지정하는 match 섹션
  • 발견 항목을 트리거하고 여러 이벤트의 존재 여부를 확인하는 조건을 지정하는 condition 섹션

예를 들어 다음 규칙은 10분 이내에 최소 10번 이상 로그인한 사용자를 검색합니다.

rule MultiEventRule {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.user.userid = $user

  match:
    $user over 10m

  condition:
    #e >= 10
}

IP 주소 범위 내의 단일 이벤트

다음 예시는 2명의 특정 사용자와 특정 IP 주소 범위 사이의 일치를 검색하는 단일 이벤트 규칙을 보여줍니다.

rule OrsAndNetworkRange {
  meta:
    author = "noone@altostrat.com"

  events:
    // Checks CIDR ranges.
    net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")

    // Detection when the hostname field matches either value using or.
    $e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/

  condition:
    $e
}

모든 규칙 예시

다음 규칙은 모든 소스 IP 주소가 5분 내에 안전한 것으로 알려진 IP 주소와 일치하지 않는 로그인 이벤트를 검색합니다.

rule SuspiciousIPLogins {
  meta:
    author = "alice@example.com"

  events:
    $e.metadata.event_type = "USER_LOGIN"

    // Detects if all source IP addresses in an event do not match "100.97.16.0"
    // For example, if an event has source IP addresses
    // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
    // it will be detected since "100.97.16.1", "100.97.16.2",
    // and "100.97.16.3" all do not match "100.97.16.0".

    all $e.principal.ip != "100.97.16.0"

    // Assigns placeholder variable $ip to the $e.principal.ip repeated field.
    // There will be one detection per source IP address.
    // For example, if an event has source IP addresses
    // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
    // there will be one detection per address.

    $e.principal.ip = $ip

  match:
    $ip over 5m

  condition:
    $e
}

규칙의 정규 표현식

다음 YARA-L 2.0 정규 표현식 예시는 altostrat.com 도메인에서 수신된 이메일이 있는 이벤트를 검색합니다. nocase$host 변수 regex 비교 및 regex 함수에 추가되었기 때문에 이 비교는 대소문자를 구분하지 않습니다.

rule RegexRuleExample {
  meta:
    author = "noone@altostrat.com"

  events:
    $e.principal.hostname = $host
    $host = /.*HoSt.*/ nocase
    re.regex($e.network.email.from, `.*altostrat\.com`) nocase

  match:
    $host over 10m

  condition:
    #e > 10
}

복합 규칙 예시

복합 탐지는 복합 규칙을 사용하여 위협 감지를 향상시킵니다. 이러한 복합 규칙은 다른 규칙의 감지를 입력으로 사용합니다. 이를 통해 개별 규칙에서 감지하지 못할 수 있는 복잡한 위협을 감지할 수 있습니다. 자세한 내용은 복합 감지 개요를 참고하세요.

트립와이어 감지

트립와이어 복합 감지는 결과 변수 또는 규칙 메타데이터와 같이 감지 발견 내 필드에서 작동하는 가장 간단한 형태의 복합 감지입니다. 관리자 사용자 또는 프로덕션 환경과 같이 위험도가 더 높을 수 있는 조건에 대한 감지를 필터링하는 데 도움이 됩니다.

rule composite_admin_detection {
  meta:
    rule_name = "Detection with Admin User"
    author = "Google Cloud Security"
    description = "Composite rule that looks for any detections where the actor is an admin user"
    severity = "Medium"

  events:
    $rule_name = $d.detection.detection.rule_name
    $principal_user = $d.detection.detection.outcomes["principal_users"]
    $principal_user = /admin|root/ nocase

  match:
    $principal_user over 1h

  outcome:
    $risk_score = 75
    $upstream_rules = array_distinct($rule_name)

  condition:
    $d
}

기준점 및 집계 감지

집계 합성 감지 규칙을 사용하면 호스트 이름 또는 사용자 이름과 같은 공유 속성을 기반으로 감지 결과를 그룹화하고 집계된 데이터를 분석할 수 있습니다. 일반적인 사용 사례는 다음과 같습니다.

  • 보안 알림 또는 집계된 위험을 다량으로 생성하는 사용자를 식별합니다.
  • 관련 감지를 집계하여 비정상적인 활동 패턴이 있는 호스트를 감지합니다.

위험 집계 예시:

rule composite_risk_aggregation {
  meta:
    rule_name = "Risk Aggregation Composite"
    author = "Google Cloud Security"
    description = "Composite detection that aggregates risk of a user over 48 hours"
    severity = "High"

  events:
    $rule_name = $d.detection.detection.rule_name
    $principal_user = $d.detection.detection.outcomes["principal_users"]
    $risk = $d.detection.detection.risk_score

  match:
    $principal_user over 48h

  outcome:
    $risk_score = 90
    $cumulative_risk = sum($risk)
    $principal_users = array_distinct($principal_users)
    $upstream_rules = array_distinct($rule_name)

  condition:
    $d and $cumulative_risk > 500
}

전술 집계 예시:

rule composite_tactic_aggregation {
  meta:
    rule_name = "MITRE Tactic Aggregation Composite"
    author = "Google Cloud Security"
    description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
    severity = "Medium"

  events:
    $principal_user = $d.detection.detection.outcomes["principal_users"]
    $tactic = $d.detection.detection.rule_labels["tactic"]
    $rule_name = $d.detection.detection.rule_name

  match:
    $principal_user over 48h

  outcome:
    $mitre_tactics_count = count_distinct($tactic)
    $mitre_tactics = array_distinct($d.detection.rule_labels["tactic"])
    $risk_score = min(100, (50+15*$mitre_tactics_count))
    $upstream_rules = array_distinct($rule_name)

  condition:
    $d and $mitre_tactics_count > 1
}

순차 복합 감지

순차 복합 감지는 무작위 로그인 시도 감지 후 로그인 성공과 같이 감지 순서가 중요한 관련 이벤트의 패턴을 식별합니다. 이러한 패턴에는 여러 기본 감지 또는 기본 감지와 이벤트의 조합이 포함될 수 있습니다.

rule composite_bruteforce_login {
  meta:
    rule_name = "Bruteforce Login Composite"
    author = "Google Cloud Security"
    description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
    severity = "High"

  events:
    $bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
    $bruteforce_ip = $d.detection.detection.outcomes["principal_ips"]

    $login_event.metadata.product_name = "login"
    $login_event.metadata.product_event_type = "login_success"
    $login_event.metadata.vendor_name = "Google Workspace"
    $login_ip = $login_event.principal.ip

    // Ensure the brute force detection and successful login occurred from the same IP
    $login_ip = $bruteforce_ip

    $target_account = $login_event.target.user.email_addresses

    // Ensure the brute force detection occurred before the successful login
    $bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

  match:
    $bruteforce_ip over 24h

  outcome:
    $risk_score = 90
    $principal_users = array_distinct($target_account)

  condition:
    $bruteforce_detection and $login_event
}

컨텍스트 인식 감지

컨텍스트 인식 복합 감지는 위협 피드에서 발견된 IP 주소와 같은 추가 컨텍스트로 감지를 보강합니다.

rule composite_tor_enrichment {
  meta:
    rule_name = "Detection with IP from TOR Feed"
    author = "Google Cloud Security"
    description = "Adds additional context from the TOR intel feed to detections"
    severity = "High"

  events:
    $detection_ip = $d.detection.detection.outcomes["principal_ips"]
    $gcti.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
    $gcti_feed.graph.metadata.source_type = "GLOBAL_CONTEXT"
    $gcti.graph.metadata.product_name = "GCTI Feed"
    $gcti.graph.metadata.threat.threat_feed_name = "Tor Exit Nodes"

    $detection_ip = $gcti.graph.entity.ip

    $rule_name = $d.detection.detection.rule_name
    $risk = $d.detection.detection.outcomes["risk_score"]

  match:
    $detection_ip, $rule_name over 1h

  outcome:
    $risk_score = 80
    $upstream_rule = array_distinct($rule_name)

  condition:
    $d and $gcti
}

동시 발생 감지

동시 발생 합성 감지는 사용자가 트리거한 권한 상승 감지와 데이터 유출 감지의 조합과 같은 관련 이벤트 조합을 감지할 수 있는 집계의 한 형태입니다.

rule composite_privesc_exfil_sequential {
  meta:
    rule_name = "Privilege Escalation and Exfiltration Composite"
    author = "Google Cloud Security"
    description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
    severity = "High"

  events:
    $privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
    $exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

    $pe_user = $privilege_escalation.detection.detection.outcomes["principal_users"]
    $ex_user = $exfiltration.detection.detection.outcomes["principal_users"]

    $pe_user = $ex_user

  match:
    $pe_user over 48h

  outcome:
    $risk_score = 75
    $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
    $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

  condition:
    $privilege_escalation and $exfiltration
}

슬라이딩 기간 규칙 예시

다음 YARA-L 2.0 슬라이딩 창 예시는 firewall_1 이벤트 후 firewall_2 이벤트의 부재를 검색합니다. after 키워드는 피벗 이벤트 변수 $e1과 함께 사용되어 이벤트의 상관관계를 지정할 때 10분 후에만 각 firewall_1 이벤트를 검사하도록 지정합니다.

rule SlidingWindowRuleExample {
  meta:
    author = "alice@example.com"

  events:
    $e1.metadata.product_name = "firewall_1"
    $e1.principal.hostname = $host

    $e2.metadata.product_name = "firewall_2"
    $e2.principal.hostname = $host

  match:
    $host over 10m after $e1

  condition:
    $e1 and !$e2
}

0 값 제외 예시

규칙 엔진은 match 섹션에 사용된 모든 자리 표시자에 대해 0 값을 암시적으로 필터링합니다. 자세한 내용은 match 섹션의 0 값 처리를 참조하세요. 이는 allow_zero_values에 설명된 대로 allow_zero_values 옵션을 사용하여 사용 중지할 수 있습니다.

하지만 다른 참조된 이벤트 필드의 경우 명시적으로 조건을 지정하지 않으면 0 값이 제외되지 않습니다.

rule ExcludeZeroValues {
  meta:
    author = "alice@example.com"

  events:
    $e1.metadata.event_type = "NETWORK_DNS"
    $e1.principal.hostname = $hostname

    // $e1.principal.user.userid may be empty string.
    $e1.principal.user.userid != "Guest"

    $e2.metadata.event_type = "NETWORK_HTTP"
    $e2.principal.hostname = $hostname

    // $e2.target.asset_id cannot be empty string as explicitly specified.
    $e2.target.asset_id != ""

  match:
    // $hostname cannot be empty string. The rule behaves as if the
    // predicate, `$hostname != ""` was added to the events section, because
    // `$hostname` is used in the match section.
    $hostname over 1h

  condition:
    $e1 and $e2
}

outcome 섹션이 있는 규칙 예시

YARA-L 2.0 규칙에 선택적인 outcome 섹션을 추가하여 각 발견 항목에 대한 추가 정보를 추출할 수 있습니다. 조건 섹션에서 결과 변수에 조건부를 지정할 수도 있습니다. 감지 규칙의 outcome 섹션을 사용해서 다운스트림 소비에 대한 변수를 설정할 수 있습니다. 예를 들어 분석 중인 이벤트의 데이터를 기반으로 심각도 점수를 설정할 수 있습니다.

자세한 내용은 다음을 참조하세요.

결과 섹션이 있는 멀티 이벤트 규칙:

다음 규칙에서는 두 가지 이벤트를 확인하여 $hostname 값을 가져옵니다. $hostname 값이 5분 이상 일치하면 심각도 점수가 적용됩니다. match 섹션에 기간을 포함하면 규칙이 지정된 기간 내에 확인합니다.

rule OutcomeRuleMultiEvent {
    meta:
      author = "Google Cloud Security"
    events:
      $u.udm.principal.hostname = $hostname
      $asset_context.graph.entity.hostname = $hostname

      $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

    match:
      $hostname over 5m

    outcome:
      $risk_score =
        max(
            100
          + if($hostname = "my-hostname", 100, 50)
          + if($severity = "HIGH", 10)
          + if($severity = "MEDIUM", 5)
          + if($severity = "LOW", 1)
        )

      $asset_id_list =
        array(
          if($u.principal.asset_id = "",
             "Empty asset id",
             $u.principal.asset_id
          )
        )

      $asset_id_distinct_list = array_distinct($u.principal.asset_id)

      $asset_id_count = count($u.principal.asset_id)

      $asset_id_distinct_count = count_distinct($u.principal.asset_id)

    condition:
      $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

rule OutcomeRuleMultiEvent {
    meta:
      author = "alice@example.com"
    events:
      $u.udm.principal.hostname = $hostname
      $asset_context.graph.entity.hostname = $hostname

      $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

    match:
      $hostname over 5m

    outcome:
      $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

      $risk_score = if(total_network_bytes > 1024, 100, 50) + 
        max(
          if($severity = "HIGH", 10)
          + if($severity = "MEDIUM", 5)
          + if($severity = "LOW", 1)
        )

      $asset_id_list =
        array(
          if($u.principal.asset_id = "",
             "Empty asset id",
             $u.principal.asset_id
          )
        )

      $asset_id_distinct_list = array_distinct($u.principal.asset_id)

      $asset_id_count = count($u.principal.asset_id)

      $asset_id_distinct_count = count_distinct($u.principal.asset_id)

    condition:
      $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

결과 섹션이 있는 단일 이벤트 규칙:

rule OutcomeRuleSingleEvent {
    meta:
        author = "alice@example.com"
    events:
        $u.metadata.event_type = "FILE_COPY"
        $u.principal.file.size = $file_size
        $u.principal.hostname = $hostname

    outcome:
        $suspicious_host = $hostname
        $admin_severity = if($u.principal.userid in %admin_users, "SEVERE", "MODERATE")
        $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

    condition:
        $u
}

멀티 이벤트 결과 규칙을 단일 이벤트 결과 규칙으로 리팩터링

단일 이벤트 규칙(match 섹션이 없는 규칙) 및 멀티 이벤트 규칙(match 섹션이 있는 규칙) 모두 outcome 섹션을 사용할 수 있습니다. 이전에 결과 섹션을 사용할 수 있도록 규칙을 다중 이벤트로 설계한 경우, match 섹션을 삭제하여 해당 규칙을 선택적으로 리팩터링하면 성능을 개선할 수 있습니다. 규칙에 그룹화를 적용하는 match 섹션이 더 이상 없으므로 더 많은 감지가 수신될 수 있습니다. 이 리팩터링은 다음 예시에 표시된 것처럼 1개 이벤트 변수를 사용하는 규칙에만 가능합니다.

하나의 이벤트 변수만 사용하는 멀티 이벤트 결과 규칙(리팩터링에 적합함):

rule OutcomeMultiEventPreRefactor {
    meta:
      author = "alice@example.com"
      description = "Outcome refactor rule, before the refactor"

    events:
      $u.udm.principal.hostname = $hostname

    match:
      $hostname over 5m

    outcome:
      $risk_score = max(if($hostname = "my-hostname", 100, 50))

    condition:
      $u
}

match 섹션을 삭제하여 규칙을 리팩터링할 수 있습니다. 이제 규칙이 단일 이벤트가 되므로 outcome 섹션에서 집계도 삭제해야 합니다. 집계에 대한 자세한 내용은 결과 집계를 참조하세요.

rule OutcomeSingleEventPostRefactor {
    meta:
      author = "alice@example.com"
      description = "Outcome refactor rule, after the refactor"

    events:
      $u.udm.principal.hostname = $hostname

    // We deleted the match section.

    outcome:
      // We removed the max() aggregate.
      $risk_score = if($hostname = "my-hostname", 100, 50)

    condition:
      $u
}

자리 표시자 규칙 예시 함수

함수 호출의 결과에 자리 표시자 변수를 할당하고 match 섹션, outcome 섹션, condition 섹션과 같은 규칙의 다른 섹션에 자리 표시자 변수를 사용할 수 있습니다. 아래 예시를 참조하세요.

rule FunctionToPlaceholderRule {
    meta:
      author = "alice@example.com"
      description = "Rule that uses function to placeholder assignments"

    events:
        $u.metadata.event_type = "EMAIL_TRANSACTION"

        // Use function-placeholder assignment to extract the
        // address from an email.
        // address@website.com -> address
        $email_to_address_only = re.capture($u.network.email.from , "(.*)@")

        // Use function-placeholder assignment to normalize an email:
        // uid@??? -> uid@company.com
        $email_from_normalized = strings.concat(
            re.capture($u.network.email.from , "(.*)@"),
            "@company.com"
        )

        // Use function-placeholder assignment to get the day of the week of the event.
        // 1 = Sunday, 7 = Saturday.
        $dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)

    match:
        // Use placeholder (from function-placeholder assignment) in match section.
        // Group by the normalized from email, and expose it in the detection.
        $email_from_normalized over 5m

    outcome:
        // Use placeholder (from function-placeholder assignment) in outcome section.
        // Assign more risk if the event happened on weekend.
        $risk_score = max(
            if($dayofweek = 1, 10, 0) +
            if($dayofweek = 7, 10, 0)
        )

    condition:
        // Use placeholder (from function-placeholder assignment) in condition section.
        // Match if an email was sent to multiple addresses.
        #email_to_address_only > 1
}

결과 조건부 예시 규칙

condition 섹션에서 outcome 섹션에 정의된 결과 변수를 사용할 수 있습니다. 다음 예시는 결과 조건부를 사용해서 감지에서 노이즈를 줄이기 위해 위험 점수를 필터링하는 방법을 보여줍니다.

rule OutcomeConditionalRule {
    meta:
        author = "alice@example.com"
        description = "Rule that uses outcome conditionals"

    events:
        $u.metadata.event_type = "FILE_COPY"
        $u.principal.file.size = $file_size
        $u.principal.hostname = $hostname

        // 1 = Sunday, 7 = Saturday.
        $dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)

    outcome:
        $risk_score =
            if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
            if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
            if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
            if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

    condition:
        $u and $risk_score >= 10
}

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