YARA-L 2.0 언어 구문
이 섹션에서는 YARA-L 문법의 주요 요소들에 대해 설명합니다. YARA-L 2.0 언어 개요도 참조하세요.
규칙 구조
YARA-L 2.0의 경우 변수 선언, 정의, 사용을 다음 순서로 지정해야 합니다.
- meta
- events
- match(선택사항)
- outcome(선택사항)
- condition
- 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
섹션에 지정된 기간의 슬라이딩 기간이 생성됩니다. 그런 후 각 슬라이딩 창 내에서 이벤트에 대해 상관관계가 지정됩니다. 이렇게 하면 e1
이 e2
에서 최대 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를 제공해야 합니다.
수학적 연산
수학적 연산을 사용하여 규칙의 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 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
섹션이 규칙에 포함된 경우에 중요합니다. 집계 함수는 발견 항목을 생성한 모든 이벤트에서 작동하기 때문입니다.
예를 들어 outcome
및 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
조건 섹션에서는 발견 항목마다 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 > 1
은 c
변수가 2회 이상 발생해야 함을 의미합니다.
값 문자
$
문자는 condition
섹션에 사용되는 특수문자입니다. 결과 변수 이름 앞에 사용될 경우 해당 결과 값을 나타냅니다.
이벤트 또는 자리표시자 변수 이름 앞에 사용될 경우(예: $event
) #event > 0
을 나타냅니다.
이벤트 및 자리표시자 조건
여기에 and
및 or
키워드와 결합된 이벤트 및 자리표시자 변수의 조건 조건자를 나열합니다. 모든 조건 간에 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
존재하지 않는 조건 요구사항
존재하지 않는 조건이 있는 규칙을 컴파일할 경우 다음 요구사항을 충족해야 합니다.
- 최소 하나 이상의 UDM 이벤트에 제한된 조건이 있어야 합니다(즉, 하나 이상의 UDM 이벤트가 있어야 함).
- 자리표시자에 제한되지 않은 조건이 있는 경우 하나 이상의 제한된 UDM 이벤트와 연결되어야 합니다.
- 항목에 제한되지 않은 조건이 있는 경우 하나 이상의 제한된 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
이 옵션에 유효한 값은 이 옵션의 사용 설정 여부를 결정하는 true
및 false
입니다. 기본값은 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
입니다.
예를 들어 or
와 and
연산자가 표현식에 명시적으로 정의된 경우 '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)에서 일부 필드는 반복 필드로 라벨이 지정되어 값 또는 다른 메시지 유형의 목록임을 나타냅니다.
반복 필드 및 불리언 표현식
반복 필드에서 작동하는 불리언 표현식에는 두 가지 종류가 있습니다.
- 수정 시간
- 수정되지 않음
다음 이벤트를 고려하세요.
event_original {
principal {
// ip is a repeated field
ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]
hostname: "host"
}
}
수정된 표현식
다음 섹션에서는 표현식에서 any
및 all
수정자를 사용하는 목적과 방법을 설명합니다.
모두
반복 필드의 요소 중 하나라도 조건을 충족하면 이벤트 전체가 조건을 충족합니다.
event_original
은any $e.principal.ip = "192.0.2.1"
을 충족합니다.event_original
은any $e.repeated_field.field_a = "9.9.9.9
을 충족하지 않습니다.
모두
반복 필드의 모든 요소가 조건을 충족하면 이벤트 전체가 조건을 충족합니다.
event_original
은net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")
을 충족합니다.event_original
은all $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
과 일치하는 않는 것을 확인합니다.
제약조건:
any
및all
연산자는 반복 필드와만 호환됩니다(스칼라 필드가 아님).any
및all
은 두 개의 반복 필드를 조인하는 데 사용될 수 없습니다. 예를 들어any $e1.principal.ip = $e2.principal.ip
는 잘못되었습니다.any
및all
연산자는 참조 목록 표현식에서 지원되지 않습니다.
수정되지 않은 표현식
수정되지 않은 표현식을 사용하면 반복 필드의 각 요소는 개별적으로 취급됩니다. 이벤트의 반복 필드에 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
}
다음 예시에서는 세 가지 일치 항목을 생성합니다. $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"]
는 잘못되었습니다. - 필드 경로에 반복 필드가 여러 개 있으면 모든 반복 필드가 배열 색인 생성을 사용해야 합니다. 예를 들어
intermediary
및ip
는 모두 반복 필드이기 때문에$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_1
은 repeated_message_2
의 모든 표현식을 충족하므로 이벤트가 규칙과 일치합니다.
이로 인해 규칙 repeated_message_1
에는 배열 색인 생성이 없고 일치 항목이 생성되지 않았지만 규칙 repeated_message_2
는 배열 색인 생성을 사용하고 일치 항목을 생성했으므로 예기치 않은 동작이 발생할 수 있습니다.
설명
2개의 슬래시 문자(// comment
)를 사용하여 설명을 지정하거나 C에서와 같이 슬래시와 별표 문자(/* comment */
)를 사용하여 여러 줄에 걸친 설명을 지정할 수 있습니다.
리터럴
음수가 아닌 정수 및 부동 소수점 수, 문자열, 불리언, 정규 표현식 리터럴이 지원됩니다.
문자열 및 정규 표현식 리터럴
YARA-L 2.0에서는 다음 인용 문자를 사용하여 문자열을 묶을 수 있습니다. 하지만 인용된 텍스트는 사용 대상에 따라 다르게 해석됩니다.
큰따옴표(")—일반 문자열에 사용됩니다. 이스케이프 문자를 포함해야 합니다.
예: 'hello\tworld'—\t가 탭 문자로 해석됩니다.뒤쪽 인용부호(`)—모든 문자를 문자 그대로 해석하기 위해 사용됩니다.
예: `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 규칙의 다음 부분에서 사용할 수 있습니다.
events
섹션- 결과 섹션의 조건부
BOOL_CLAUSE
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
이 예시에서는 이메일에서 @
기호 다음에 있는 모든 것을 캡처하고 com
을 org
로 바꾼 후 해당 결과를 반환합니다. 중첩 함수 사용을 확인하세요.
"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.from
이 suspicious@gmail.com
이거나 (2) $e.network.email.from
이 비어 있고 $e.network.email.to
가 suspicious@gmail.com
이면 조건이 True로 평가됩니다.
"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
예 2
다음 예시에서는 인수가 3개 이상 있는 coalesce
함수를 호출합니다. 이 조건은 $e
이벤트에서 null이 아닌 첫 번째 IP 주소를 참조 목록 ip_watchlist
의 값과 비교합니다. 이 호출에서 인수가 병합되는 순서는 규칙 조건에 열거되는 순서와 같습니다.
$e.principal.ip
가 먼저 평가됩니다.$e.src.ip
가 다음에 평가됩니다.$e.target.ip
가 다음에 평가됩니다.- 마지막으로, 이전
ip
필드가 설정되지 않은 경우 'No IP' 문자열이 기본값으로 반환됩니다.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
예 3
다음 예시에서는 이벤트 $e1
및 이벤트 $e2
의 principal.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.hostname
및 principal.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를 이벤트 $e2
의 principal.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'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.- TZ 데이터베이스 이름, 예: 'America/Los_Angeles'. 자세한 내용은 이 페이지의 '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
코드 샘플
예 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'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.- TZ 데이터베이스 이름, 예: 'America/Los_Angeles'. 자세한 내용은 이 페이지의 '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
반환 유형
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'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.- TZ 데이터베이스 이름, 예: 'America/Los_Angeles'. 자세한 내용은 이 페이지의 '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
반환 유형
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'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.- TZ 데이터베이스 이름, 예: 'America/Los_Angeles'. 자세한 내용은 이 페이지의 '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
반환 유형
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').
- IANA 시간대(TZ) 데이터베이스 이름입니다(예:
다음은 시간 추출 함수에 두 번째 인수로 전달할 수 있는 다른 올바른 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'입니다. 문자열 리터럴을 사용하여 시간대를 지정할 수 있습니다. 옵션은 다음과 같습니다.- TZ 데이터베이스 이름, 예: 'America/Los_Angeles'. 자세한 내용은 이 페이지의 '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
반환 유형
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
섹션에서 자리표시자 변수를 사용할 수 있습니다.
그러나 자리표시자 할당 함수에는 두 가지 제한사항이 있습니다.
자리표시자 할당 함수의 모든 자리표시자는 이벤트 필드가 포함된 표현식에 할당해야 합니다. 예를 들어 다음 예시는 유효합니다.
$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.
함수 호출은 단 하나의 이벤트에 의존해야 합니다. 그러나 동일한 이벤트의 두 개 이상의 필드를 함수 호출 인수에 사용할 수 있습니다. 예를 들어 다음은 유효합니다.
$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에서 감지를 보는 경우 감지에 대한 모든 이벤트 샘플을 다운로드할 수 있습니다. 자세한 내용은 이벤트 다운로드를 참조하세요.