결과 섹션 구문
YARA-L 쿼리의 outcome 섹션은 규칙이 트리거될 때 검색 및 대시보드 쿼리의 출력과 감지에 대한 추가 컨텍스트 및 정보를 지정하는 결과 변수를 정의합니다. 이러한 변수는 대시보드에 관련 데이터를 표시하고 위험 점수를 생성하는 등 다양한 용도로 사용할 수 있습니다.
결과 섹션 정의
$ 문자 뒤에 변수 이름을 사용하여 단일 쿼리의 outcome 섹션에서 결과 변수를 정의합니다. 결과 변수를 최대 20개까지 정의할 수 있습니다. 변수 이름 자체는 임의로 지정할 수 있습니다. 규칙의 경우 결과 값은 각 감지를 기반으로 계산되고 집계됩니다.
각 결과 변수에는 표현식을 사용하여 값이 할당됩니다.
이 규칙은 새 위치에서 로그인 실패를 검색합니다.
rule failed_logins
{
meta:
author = "Security Team"
description = "Detects multiple failed user logins within 10-minute windows."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$user = $e.target.user.userid
match:
$user over 10m
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
condition:
#e >= 5
}
outcome 섹션에서는 이벤트 및 자리표시자 변수에 대한 집계를 실행합니다. 실패한 로그인 수를 집계하고, 고유 IP 수를 집계하고, 실패가 발생한 시간을 가져옵니다.
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
특수 $risk_score 결과 변수를 포함하고 채우면 쿼리로 생성된 알림의 알림 및 IoC 페이지에 해당 값 (정수 또는 부동 소수점)이 표시됩니다.
쿼리의 outcome 섹션에 $risk_score 변수를 포함하지 않으면 다음 기본값 중 하나가 설정됩니다.
쿼리가 알림을 생성하도록 구성된 경우
$risk_score가 40으로 설정됩니다.쿼리가 알림을 생성하도록 구성되지 않은 경우
$risk_score가 15로 설정됩니다.
$risk_score 값은 security_result.risk_score UDM 필드에 저장됩니다.
risk_score 결과 변수
Google SecOps 위험 분석은 감지 및 알림을 해당 감지 또는 알림과 관련된 항목에 자동으로 연결합니다. risk_score 결과 변수는 위험 정도를 할당하는 데 사용됩니다. 이 값이 설정되지 않으면 기본 감지 또는 알림 값이 사용됩니다. 설정에서 기본값을 구성할 수 있습니다.
플랫폼 전반에서 일관성을 유지하려면 맞춤 감지에 risk_score를 할당할 때 다음 점수 범위를 사용하는 것이 좋습니다. 이러한 정렬은 경보 우선순위 지정 및 대응 워크플로를 표준화하는 데 도움이 됩니다.
| 심각도 | 점수 범위 | 설명 | 예 |
|---|---|---|---|
| 알림 - 중요 | 90 - 100 | 단일 사용자 계정 또는 엔드포인트를 넘어 영향을 미칠 수 있는 활성 침해 즉시 검토가 필요합니다. | 도메인 컨트롤러에서 Mimikatz가 실행되었습니다. |
| 알림 - 높음 | 80~89 | 단일 엔드포인트 또는 엔티티의 활성 보안 침해입니다. 즉시 검토해야 합니다. | 최근에 알려진 C2를 호출하는 프로덕션 서버 |
| 알림 - 중간 | 50~79 | 조사가 필요한 잠재적인 보안 문제입니다. 확인된 보안 침해는 없지만 에스컬레이션이 가능합니다. | 노출된 사용자 인증 정보, 오용 징후 없음 |
| 알림 없음 - 낮음 | 20~49 | 다른 지표 또는 관찰 결과와 결합될 경우 더 심각한 사고로 이어질 수 있는 영향이 적은 보안 이벤트입니다. 일반적으로 검토가 필요하지 않으며, 복합 규칙을 통해 다른 감지와 결합하여 알림을 생성할 수 있습니다. | 내부 포트 스캔입니다. |
| 알림이 없는 관찰 | 1~19명 | 일반적으로 위협의 상황 인식에 도움이 되는 정보 기반 감지입니다. 일반적으로 검토가 필요하지 않으며, 복합 규칙을 통해 다른 감지와 결합하여 알림을 생성할 수 있습니다. | 로그인 이벤트이며 오용의 징후가 없습니다. |
risk_score는 결과 변수이므로 위협 인텔리전스나 기타 동시 조건과 같은 요인에 따라 규칙이 미묘한 차이를 표현할 수 있습니다.
항목 위험 점수를 사용하면 위험 기반 알림을 거의 실시간으로 생성할 수 있습니다. 자세한 내용은 위험 분석 개요를 참고하세요.
risk_entity_to_score 결과 변수
risk_score 결과 변수 외에 risk_entity_to_score 결과 변수를 지정할 수도 있습니다. 이 변수를 사용하면 규칙 감지에서 감지의 위험 점수를 적용해야 하는 항목을 명시적으로 지정할 수 있습니다.
변수에 고유한 문자열을 추가하여 여러 risk_entity_to_score 변수를 만들고 특정 항목에 위험 점수를 할당할 수 있습니다. 예를 들면 다음과 같습니다.
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
이러한 결과 변수는 규칙의 outcome 섹션에 지정된 risk_score를 $e.principal.asset.hostname 및 $e.target.user.userid 항목에 할당합니다.
예: 규칙에서 관리자 계정 로그인을 감지함
이 규칙은 높은 권한의 관리자 계정에 대한 로그인 성공을 감지합니다. risk_entity_to_score 키워드를 사용하여 로그인한 특정 사용자를 명시적으로 타겟팅합니다. 이 변수를 사용하면 감지에서 계산된 위험 점수가 소스 IP 주소와 같은 이벤트에 관련된 다른 항목이 아닌 해당 사용자에게만 적용됩니다.
다중 이벤트 규칙을 작성하는 방법에 대한 자세한 내용은 여러 이벤트 규칙을 참고하세요.
rule suspicious_admin_privilege_escalation {
// This rule matches single events. Rules can also match multiple events within
// the same time window.
meta:
// Allows for storage of arbitrary key-value pairs of rule details, such as
// who wrote it, what it detects on, and version control.
// The "author" and "severity" fields are special, since they are used as
// columns on the rules dashboard. To sort based on these fields on the
// dashboard, add them here.
// Severity value should be "Low", "Medium", or "High"
author = "analyst123"
description = "Detects suspicious login to critical admin accounts."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.target.user.attribute.roles.name = "ADMIN"
$e.security_result.summary = "Successful login with high-privilege access"
outcome:
// Multi-event rules require an aggregation function
// For example, risk_score = max(0)
// See https://cloud.google.com/chronicle/docs/detection/yara-l-2-0-overview#outcome_conditionals_example_rule
$risk_score = 80
$risk_entity_to_score = $e.target.user.userid
$source_ip = array_distinct($e.principal.ip)
condition:
$e
}
예: 규칙이 내부 네트워크 연결을 모니터링함
이 규칙은 내부 네트워크 세그먼트 간의 네트워크 연결을 식별하여 측면 이동을 확인합니다. $risk_entity_to_score prefix를 사용하여 단일 감지 내의 여러 항목에 위험을 할당합니다. 시작 호스트($risk_entity_to_score_source_asset)와 타겟 사용자($risk_entity_to_score_targeted_user)의 위험 점수가 모두 업데이트됩니다. 위험 엔진은 컨텍스트에 이 특정 접두사를 사용하지 않는 다른 결과 변수를 기록하지만 이를 무시합니다 (위험 점수는 동일하게 유지됨).
멀티 이벤트 규칙을 작성하는 방법에 관한 자세한 내용은 여러 이벤트 규칙 및 결과 조건부 예시 규칙을 참고하세요.
rule lateral_movement_network_connection {
// This rule matches single events. You can also match multiple events within
// the same time window.
meta:
// Allows for storage of arbitrary key-value pairs of rule details (for
// example, who wrote it, what it detects on, and version control).
// The "author" and "severity" fields are special, since they are used as
// columns on the rules dashboard. To sort based on these fields on the
// dashboard, add them here. Severity value should be "Low", "Medium" or "High"
author = "analyst123"
description = "Detects lateral movement attempts between internal segments."
severity = "MEDIUM"
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$e.principal.asset.hostname != ""
$e.target.user.userid != ""
// Can also use: $e.target.ip = /10\..*/
net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")
outcome:
// Multi-event rules require an aggregation function
// for example, risk_score = max(0)
// See https://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#outcome-conditionals-example-rule
$risk_score = 50
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
$target_ip_info = array_distinct($e.target.ip)
condition:
$e
}
결과 변수 데이터 유형
각 결과 변수의 데이터 유형은 다를 수 있으며, 해당 데이터 유형은 이를 계산하는 데 사용되는 표현식으로 결정됩니다. Google SecOps에서 지원되는 결과 데이터 유형은 다음과 같습니다.
- 정수
- 부동 소수점 수
- 문자열
- 정수 목록
- 부동 소수점 목록
- 문자열 목록
조건부 로직
조건부 로직을 사용하여 결과 값을 계산할 수 있습니다. 조건부는 다음 문법 패턴을 사용하여 지정됩니다.
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를 제공해야 합니다.
수학적 연산
수학적 연산을 사용하여 쿼리의 outcome 및 events 섹션에서 정수 또는 부동 소수점 데이터 유형을 계산할 수 있습니다. 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 query. 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 query 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 query 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 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개의 값(스칼라 값)만 있게 됩니다.
마찬가지로 일치 기간이 있는 쿼리의 outcome 섹션에 사용되는 반복되지 않은 이벤트 필드와 반복 이벤트 필드는 모두 비스칼라 값입니다.
예: 일치 섹션과 반복되지 않는 필드가 있는 그룹 이벤트
다음 쿼리는 `match` 섹션을 사용하여 이벤트를 그룹화하고 `outcome` 섹션에서 반복되지 않는 이벤트 필드를 참조합니다.
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}쿼리가 실행되는 5분 기간에는 이벤트가 0개, 1개 또는 여러 개 포함될 수 있습니다. 결과 섹션은 일치 기간의 모든 이벤트에 대해 작동합니다. 결과 섹션 내에서 참조되는 모든 이벤트 필드 변수는 일치 기간의 각 이벤트에 대한 0개, 1개 또는 여러 개의 필드 값을 가리킬 수 있습니다.
예를 들어 5분 기간에 $e 이벤트가 5개 포함된 경우 결과 섹션의 $e.principal.hostname은 서로 다른 호스트 이름 5개를 가리킵니다. 이 쿼리의 outcome 섹션에서 이벤트 필드 변수 $e.principal.hostname은 비스칼라 값으로 처리됩니다.
결과 변수는 항상 단일 스칼라 값을 생성해야 하므로 결과 할당이 종속된 비스칼라 값은 단일 스칼라 값을 생성하도록 집계해야 합니다. 결과 섹션에서 다음은 비스칼라 값이며 집계해야 합니다.
- 쿼리에서
match섹션을 사용하는 경우 이벤트 필드 (반복 또는 반복되지 않음) - 쿼리에서
match섹션을 사용할 때 이벤트 자리표시자 (반복 또는 반복되지 않음) - 쿼리에서
match섹션을 사용하지 않을 때 반복되는 이벤트 필드 - 쿼리에서
match섹션을 사용하지 않을 때 반복되는 이벤트 자리표시자
스칼라 이벤트 필드, 스칼라 이벤트 자리표시자, 상수는 match 섹션이 포함되지 않은 쿼리에서 집계 함수로 래핑할 수 있습니다. 하지만 대부분의 경우 이러한 집계는 래핑된 값을 반환하므로 불필요합니다.
스칼라 값을 배열로 명시적으로 변환하는 데 사용할 수 있는 array() 집계는 예외입니다.
결과 변수는 집계와 같이 처리됩니다. 다른 결과 할당에서 참조될 때 다시 집계되지 않아야 합니다.
다음 집계 함수를 사용할 수 있습니다.
| 집계 함수 | 설명 |
|---|---|
max() |
가능한 모든 값의 최댓값을 출력합니다. 정수 및 부동 소수점으로만 작동합니다. |
min() |
가능한 모든 값의 최솟값을 출력합니다. 정수 및 부동 소수점으로만 작동합니다. |
sum() |
가능한 모든 값의 합계를 출력합니다. 정수 및 부동 소수점으로만 작동합니다. |
count_distinct() |
가능한 모든 값을 수집한 후 가능한 값의 고유한 개수를 반환합니다. |
count() |
`count_distinct()`와 동일하게 동작하지만 가능한 값의 고유하지 않은 개수를 반환합니다. |
array_distinct() |
가능한 모든 고유 값을 수집한 후 이 값의 목록을 반환합니다. 고유 값 목록은 임의 요소 1,000개로 잘립니다. 고유 목록을 가져오기 위한 중복 삭제가 먼저 적용된 후 자르기가 적용됩니다. |
array() |
array_distinct()와 유사하게 작동하지만 고유하지 않은 값 목록을 반환합니다. 또한 값 목록은 1,000개의 임의 요소로 잘립니다. |
집계 함수는 여러 이벤트가 존재해야 함을 지정하는 condition 섹션이 규칙에 포함된 경우에 중요합니다. 집계 함수는 발견 항목을 생성한 모든 이벤트에서 작동하기 때문입니다.
예: 여러 이벤트의 조건
다음은 여러 이벤트의 조건 예시입니다. 결과 및 조건 섹션에 다음이 포함된 경우
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
`condition` 섹션에서는 발견 항목마다 `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섹션에서 이미 상관관계가 있는 이벤트 변수만 연결할 수 있습니다. 상관관계는 서로 다른 이벤트 변수의 두 이벤트 필드가 동일할 때 발생합니다.
outcome 섹션의 예는 YARA-L 2.0 개요를 참고하세요.
outcome 섹션에서 발견 항목 중복 제거에 대한 자세한 내용은 컨텍스트 인식 분석 만들기를 참고하세요.
다음 단계
추가 정보
도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가에게 문의하여 답변을 받으세요.