컨텍스트 인식 분석 만들기

Chronicle을 사용하면 Chronicle 계정 내에서 원격 분석, 항목 컨텍스트, 관계, 취약점을 한 번의 감지 작업으로 확인할 수 있습니다. 원격 분석의 행동 패턴과 이러한 패턴의 영향을 받는 항목 컨텍스트까지 모두 이해할 수 있게 해주는 항목 컨텍스트화 기능을 제공합니다.

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

  • 무작위 공격 로그인이 시도되는 계정의 권한을 제공합니다.
  • 아웃바운드 네트워크 활동의 소스이기도 한 애셋에서 호스팅되는 데이터의 중요도

고객은 감지 필터링, 휴리스틱 알림 우선순위화, 분류, 조사에 이러한 컨텍스트화를 사용할 수 있습니다.

보안 분석가 및 감지 엔지니어는 일반적으로 이벤트 원격 분석의 기본 패턴(아웃바운드 네트워크 연결)에 따라 감지를 구성해서 분석가 분류를 위해 여러 감지를 만듭니다. 분석가는 알림이 트리거된 상황과 해당 위협의 중요성에 대한 이해를 결합하려고 시도합니다.

컨텍스트 인식 분석은 감지 작성 및 실행 워크플로의 초기에 고급 보강 기능을 사용함으로써 다음과 같은 추가 기능을 제공할 수 있게 해줍니다.

  • 인간 분류 단계보다는 감지 실행 시간에 감지에 대한 휴리스틱 기반의 상황별 위험 평가를 위해 관련 컨텍스트를 사용할 수 있도록 지원
  • 분류 시간을 줄이고 개별 IT 보안 시스템(EDR 콘솔, 방화벽/프록시 로그, CMDB 및 IAM 컨텍스트, 취약점 스캔 결과)의 정보를 수동으로 결합할 수 있도록 지원
  • 분석가 및 감지 엔지니어가 예상 가능하거나 기업에 거의 위험하지 않은 전체 위협을 필터로 제외할 수 있도록 지원(샌드박스 환경의 멀웨어 테스트, 민감한 정보 또는 액세스 권한 없이 개발 네트워크에서 수행되는 취약점 및 비정상 활동 등)

컨텍스트 인식 분석을 위한 규칙 작성

Detection Engine 규칙을 사용하여 Chronicle 계정의 항목 컨텍스트 데이터를 검색할 수 있습니다.

항목 컨텍스트 데이터를 검색하려면 다음을 수행합니다.

  1. udm 또는 항목을 사용하여 소스를 지정합니다.

    $eventname.[<source>].field1.field2 항목 컨텍스트에서 <source>는 'graph'입니다. UDM 이벤트에서 <source>는 'udm'입니다. 생략하면 <source>에 기본적으로 udm이 사용됩니다.

  2. 항목 데이터를 지정합니다.

    $e1.graph.entity.hostname = "my-hostname"

    $e1.graph.entity.relations.relationship = "OWNS"

  3. UDM 이벤트 데이터를 지정합니다. 다음 문은 동일합니다.

    $e1.udm.principal.asset_id = "my_asset_id"

    $e1.principal.asset_id = "my_asset_id"

다음을 포함하여 UDM 이벤트에서와 같이 항목 컨텍스트에 같은 유형의 많은 규칙을 만들 수 있습니다.

  • 여러 이벤트 규칙

  • 항목 컨텍스트를 다른 항목 컨텍스트와 비교

  • 항목 컨텍스트를 UDM 이벤트와 비교

  • 항목 컨텍스트의 반복 필드

  • 슬라이딩 기간

  • 감지를 위한 위험 점수 계산

UDM 이벤트와 달리 항목 컨텍스트에는 특정 타임스탬프가 없습니다. 각 항목 컨텍스트에는 연결이 유효한 시간 범위가 있습니다. 시간 범위는 일 경계에서 시작할 필요가 없고 임의 기간일 수 있습니다.

  • UDM 이벤트를 윈도잉이 있는 항목 컨텍스트와 비교할 때 항목 컨텍스트는 지정된 기간 동안의 상수 값을 나타냅니다.
  • 항목 컨텍스트에서 해당 값이 변경되는 인접한 일 버킷이 있는 경우 Chronicle은 모든 항목 컨텍스트 값과 매칭을 시도하고 발견된 모든 일치 항목을 반환합니다.

규칙 예시

관리자 컨텍스트로 항목 검색

다음 규칙은 관리자 권한에 연결된 항목을 검색합니다. 관리자 권한이 있는 누군가가 시스템에서 로그인 또는 로그아웃을 시도한 시간을 찾습니다.

rule LoginLogout {
  meta:
  events:
    $log_in.metadata.event_type = "USER_LOGIN"
    $log_in.principal.user.user_display_name = $user
    $log_in.principal.user.userid = "alice"

    $log_out.metadata.event_type = "USER_LOGOUT"
    $log_out.principal.user.user_display_name = $user
    $log_out.principal.user.userid = "alice"

    $log_in.metadata.event_timestamp.seconds <=
     $log_out.metadata.event_timestamp.seconds

    $context.graph.entity.user.user_display_name = $user
    $context.graph.entity.resource.attribute.roles.type = "ADMINISTRATOR"

  match:
    $user over 2m

  condition:
    $log_in and $log_out and $context
}

슬라이딩 구간 예시

다음 슬라이딩 구간 예시는 유효합니다.

rule Detection {
  meta:
  events:
    $e1.graph.entity.hostname = $host
    $e2.udm.principal.hostname = $host

  match:
    // Using e2 (a UDM event) as a pivot.
    $host over 3h after $e2

  condition:
    $e1 and $e2
}

잘못된 슬라이딩 구간 예시

다음 슬라이딩 구간 예시는 유효하지 않습니다. 항목 컨텍스트는 슬라이딩 구간의 피벗으로 사용될 수 없습니다.

rule Detection {
  meta:
  events:
    $e1.graph.entity.hostname = $host
    $e2.udm.principal.hostname = $host

  match:
    // Attempting to use $e1 (an entity context) as a pivot. Invalid.
    $host over 3h after $e1

  condition:
    $e1 and $e2
}

결과 섹션을 사용한 로그인 예시

다음 예시에서는 outcome 섹션을 사용하여 감지 위험 점수를 계산합니다.

rule Detection {
  meta:
  events:
    $auth.metadata.event_type = "USER_LOGIN"
    $auth.metadata.vendor_name = "Acme"
    $auth.metadata.product_name = "Acme SSO"
    $auth.target.user.userid = $user
    $auth.target.user.termination_date.seconds > 0

    $auth.metadata.event_timestamp.seconds >
       $context.graph.entity.user.termination_date.seconds

    $context.graph.metadata.vendor_name = "Microsoft"
    $context.graph.metadata.product_name = "Azure Active Directory"
    $context.graph.metadata.entity_type = "USER"
    $context.graph.entity.user.userid = $user
    $context.graph.entity.user.termination_date.seconds > 0

  match:
    $user over 15m

  outcome:
    $risk_score = max(
        if ( $auth.metadata.event_type = "USER_LOGIN", 50) +
        if (
            $context.graph.entity.user.title = "Remote" nocase or
            $context.graph.entity.user.title = "Temp" nocase or
            $context.graph.entity.user.title = "Vendor" nocase, 40) +
        if ( $context.graph.entity.user.title = "Legal" nocase, 10)
    )

  condition:
    $auth and $context
}

의심스러운 프로세스 실행 예시

다음 예시에서는 항목 컨텍스트로 저장된 IOC 컨텍스트 데이터에 대해 UDM 이벤트 프로세스 데이터를 평가합니다.

rule ProcessLaunch {
  meta:
  events:
    $ioc.graph.metadata.vendor_name = "ACME"
    $ioc.graph.metadata.product_name = "IOCs"
    $ioc.graph.metadata.entity_type = "FILE"
    $ioc.graph.entity.file.sha256 = $hash

    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.principal.hostname = $hostname
    (
        not $process.target.process.file.sha256 = "" and
        $process.target.process.file.sha256 = $hash
    )

  match:
    $hash over 15m

  condition:
    $ioc and $process
}

항목 컨텍스트의 추가 한정자

항목 컨텍스트를 사용하는 이벤트 변수를 만들려면 이벤트 이름 다음에 <source>를 제공해야 합니다. <source>graph여야 합니다.

다음 패턴은 항목 컨텍스트를 참조합니다.

  • $e.graph.entity.hostname

UDM 이벤트를 참조할 때는 두 가지 동일한 메서드가 있습니다.

  • $u.udm.principal.asset_id
  • $u.principal.asset_id

규칙 텍스트에서 이러한 한정자를 모두 혼합하고 매칭할 수 있습니다. 동일한 이벤트에 다른 한정자를 사용할 수도 있습니다.

0 기본값

필드가 규칙을 실행할 이벤트에서 자동으로 생략될 수 있습니다. 필드가 생략되면 기본적으로 0 값으로 지정됩니다.

예를 들어 생략된 문자열 값은 기본적으로 ""입니다.

둘 다 생략된 2개 필드를 동일시 하는 경우 둘 다 기본적으로 0 값으로 지정될 수 있습니다. 그러면 둘 다 0 값을 포함하기 때문에 2개 필드가 일치하는 의도치 않은 일치 결과로 이어질 수 있습니다. 명시적으로 0 값을 지정하여 이 동작을 방지할 수 있습니다.

예를 들어 2개 필드에 따라 2개 이벤트를 동일시하는 규칙이 있으면 이러한 필드가 모두 비어 있을 때 두 필드가 일치할 가능성이 있습니다.

$e1.field1 = $e2.field2

데이터에 e1.field1e2.field2가 모두 생략되었으면 "" = ""이 true이므로, 일치가 발생합니다.

다음을 지정합니다.

$e1.field1 = $e2.field2
$e1.field != ""

이렇게 하면 단순히 e1.field1e2.field2에 데이터가 포함되지 않기 때문에 일치가 발생하지 않도록 보장됩니다.

결과 섹션

Detection Engine에서는 규칙에서 더 많은 정보를 파생할 수 있게 해주는 outcome 섹션이 지원됩니다. outcome 섹션에 정의된 논리는 각 감지에 대해 평가됩니다. 규칙으로 N 감지가 생성될 때 각 N 감지는 서로 다른 결과를 일으킵니다.

다음은 outcome 섹션을 사용하는 예시 규칙입니다.

rule DetectionWithOutcomeSectionAndConditionalsAndAddition {
    meta:
    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)
        )
    condition:
      $u and $asset_context
}

outcome 섹션에서는 $risk_score라는 단일 변수 이름을 정의해야 합니다. $risk_score 값은 가장 중요하게 검토할 감지를 우선 지정할 수 있게 해주는 정수여야 합니다.

조건부 논리 및 집계 함수를 사용하여 $risk_score 값을 계산합니다.

위 예시 표현식에는 조건 지정을 위한 다음 구문 패턴이 포함되어 있습니다.

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

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

  • 비교 연산자를 포함한 UDM 필드 이름, 예: $context.graph.entity.user.title = "Vendor"
  • events 섹션에 정의된 변수 이름, 예: $severity = "HIGH"
  • 부울 반환 함수, 예: re.regex($e.network.email.from, .*altostrat\.com)

THEN_CLAUSE 및 ELSE_CLAUSE는 int 리터럴이어야 합니다.

ELSE_CLAUSE가 포함되지 않았으면 기본값으로 평가됩니다. 예를 들어 if($e.field = "a", 5)if($e.field = "a", 5, 0)과 동일합니다.

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

$risk_score 값 계산 표현식은 집계 함수로 래핑해야 합니다. Chronicle에서는 max, min, sum 함수가 지원됩니다.

집계 함수는 여러 이벤트가 존재해야 하도록 지정하는 condition 섹션이 규칙에 포함된 경우에 중요합니다. 예를 들어 조건 섹션이 다음과 같은 경우:

condition:
   #u > 2

그리고 risk_score 계산에 다음 줄이 포함된 경우:

+ if($u.principal.hostname = "my-hostname")

u 이벤트가 여러 개 있으므로 집계 함수가 여러 가능한 이벤트에서 작동합니다.

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

  • outcome 섹션의 변수 이름이 $risk_score여야 합니다.
  • $risk_score 변수에 정수를 저장해야 합니다.
  • $risk_score 계산 표현식은 더하기 및 빼기 연산자를 지원하는 수식 문입니다.
  • 표현식에는 다음이 포함될 수 있습니다.
    • Int 리터럴
    • 조건문
  • match 섹션이 있는 규칙인 멀티 이벤트 규칙에서만 outcome 섹션을 사용할 수 있습니다.
  • 규칙에는 UDM 이벤트 데이터만 평가하는 멀티 이벤트 규칙의 outcome 섹션이 포함될 수 있습니다. 항목 컨텍스트 데이터는 포함할 필요가 없습니다.
  • outcome 섹션은 events 섹션에 정의되지 않은 이벤트를 포함할 수 없습니다. events 섹션에 이미 상관 관계가 있는 이벤트만 상관 관계를 지정할 수 있습니다. 이와 비슷하게 events 섹션에 아직 정의되지 않은 새로운 자리표시자 변수는 정의할 수 없습니다.