Aaron Jewitt

Kibana 케이스로 탐지 튜닝 요청 자동화하기

Elastic Security에서 탐지 규칙 조정 요청을 자동화하는 방법을 알아보세요. 이 가이드에서는 사례에 사용자 지정 필드를 추가하고, 튜닝 요구 사항을 감지하는 규칙을 만들고, 웹훅을 사용하여 분석가와 탐지 엔지니어 간에 원활한 피드백 루프를 만드는 방법을 보여 줍니다.

20분 읽기활성화
Kibana 케이스로 탐지 튜닝 요청 자동화하기

Elastic Security를 통한 탐지 조정 요청 자동화

Elastic의 Infosec 팀은 "고객 제로"입니다. 우리는 최신 버전의 Elastic 제품을 광범위하게 사용하여 조직을 보호하고 있으며, 이를 통해 실제 보안 문제를 해결하는 방법에 대한 고유한 인사이트를 얻을 수 있습니다. 보안 운영 센터(SOC)의 효율성을 개선한 방법 중 하나는 분석가들이 클릭 한 번으로 Kibana 케이스에서 바로 탐지 조정 요청을 열 수 있는 원활하고 자동화된 워크플로우를 만든 것입니다.

모든 SOC에서 보안 분석가와 탐지 엔지니어 간의 피드백 루프는 건강하고 효과적인 보안 태세를 유지하는 데 매우 중요합니다. 최전선에 있는 분석가들은 탐지 규칙이 실제 환경에서 어떻게 작동하는지 가장 먼저 확인할 수 있습니다. 어떤 알림이 가치 있고, 어떤 알림이 시끄럽고, 어떤 알림이 약간의 튜닝을 통해 개선될 수 있는지 알고 있습니다. 시끄러운 알림으로 인한 알림 피로는 실제 양성 알림을 놓칠 위험을 높입니다. 오탐을 신속하게 조정하는 것은 오탐에 대응하는 데 매우 중요합니다. 이메일 보내기, 티켓 열기, 쪽지 열기 등의 수동 프로세스는 일관성이 없고 시간이 많이 걸리며 추적하기 어려울 수 있습니다.

Elastic Security를 사용하면 분석가는 Kibana의 신규 또는 기존 사례에 경보를 첨부하고 조사를 수행할 수 있으며, 일부 사용자 정의와 자동화를 통해 Kibana 사례에서 직접 클릭 한 번으로 튜닝 요청을 시작할 수 있습니다. 이 글에서는 이러한 자동화를 구축한 방법과 유사한 시스템을 구현하여 피드백 루프를 닫고 탐지 및 대응 프로그램을 최적화하는 방법을 안내합니다.

Kibana 케이스의 사용자 정의 필드

사용자 정의 필드는 Kibana 케이스 내에서 이 자동화의 핵심 구성 요소입니다. 이러한 사용자 지정 필드를 사용하면 분석가가 이미 사용 중인 도구에서 직접 필요한 정보를 캡처할 수 있습니다. 이러한 사용자 지정 필드는 모든 신규 및 기존 사례에 표시되어 분석가가 검토를 위해 탐지에 플래그를 지정할 수 있는 명확하고 일관된 방법을 제공합니다.

참고: 케이스에 사용자 지정 필드를 추가하는 기능은 버전 8.15에 도입되었습니다. 자세한 내용은 공식 사례 문서를 참조하세요.

모든 Kibana 케이스는 전용 Elasticsearch 인덱스에 저장된 문서입니다: .kibana_alerting_cases. 즉, Elastic의 다른 데이터 소스와 마찬가지로 모든 사례 데이터를 쿼리, 집계 및 자동화에 사용할 수 있습니다. 각 사례 문서에는 다양한 정보가 포함되어 있지만 특히 메트릭 및 자동화에 유용한 몇 가지 필드가 있습니다. cases.status 필드는 케이스가 열려 있는지, 진행 중인지, 종료되었는지 추적하고, cases.created_atcases.updated_at 필드는 평균 해결 시간(MTTR)과 같은 지표를 계산하는 데 중요한 타임스탬프를 제공합니다. cases.severitycases.owner 같은 필드를 사용하면 메트릭을 세분화하여 팀의 성과를 확인할 수 있습니다. 이 블로그에서 가장 중요한 것은 cases.custom_fields 객체에는 구성한 사용자 정의 필드 배열이 포함되어 있다는 점입니다. 런타임 필드를 사용하여 사용자 지정 필드 배열을 구문 분석할 수 있으므로 워크플로를 트리거하는 쿼리, 대시보드, 시각화 및 감지 규칙을 구축할 수 있습니다.

사용자 지정 필드는 튜닝 요청 외에도 메트릭을 추적하고 사례를 보강하는 데 매우 유용하게 사용할 수 있습니다. 예를 들어, 해결에 1시간 이상 걸리는 케이스를 표시하는 "복잡한 케이스" 사용자 지정 필드를 통해 조사 시간을 줄이기 위해 더 나은 조사 가이드나 자동화가 필요할 수 있는 규칙을 식별할 수 있습니다. 또한 "탐지 규칙 유효""정 탐 경보" 같은 사용자 정의 필드를 사용하여 규칙 성능과 충실도에 대한 세분화된 피드백을 수집함으로써 Kibana에서 강력한 대시보드를 구축하여 SOC의 운영 효율성을 시각화할 수 있습니다.

사례 정보에 대한 데이터 보기를 아직 만들지 않았다면 사례에 런타임 필드 및 데이터 시각화를 사용하려는 경우 이를 만들어야 합니다.

인덱스 패턴으로 이동합니다: Kibana에서 스택 관리 > 데이터 보기로 이동하여 '새 데이터 보기 만들기'를 클릭합니다.

.kibana_alerting_cases 시스템 인덱스를 매핑하도록 데이터 보기를 구성합니다. 이를 허용하려면 숨김 및 시스템 인덱스 허용 버튼을 클릭해야 합니다. 타임스탬프 필드에는 cases.updated_at 필드를 사용하여 가장 최근 활동별로 사례가 표시되도록 하는 것이 좋습니다.

사용자 지정 필드 만들기

사용자 지정 필드에는 자유 형식 입력을 위한 Text 필드와 간단한 예/아니요 피드백을 위한 Toggle 필드 두 가지 유형이 있습니다. 튜닝 요청 자동화의 경우 각각 하나를 사용합니다. 텍스트 필드는 분석가의 추가 피드백을 캡처하는 데 사용되는 선택적 필드이며, 토글 필드는 자동화를 트리거하는 데 사용됩니다.

Kibana에서 보안 > 사례로 이동한 다음 오른쪽 상단의 설정을 클릭합니다. 설정 페이지에 원하는 새 필드를 추가할 수 있는 사용자 정의 필드 섹션이 표시됩니다. 필드는 케이스 UI에 알파벳 순서로 표시되므로 필드 앞에 숫자를 붙여 원하는 순서를 유지합니다.

새 사용자 지정 필드를 만들 수 있으며, UI에 추가된 레이블은 분석가 전용이며 사례 인덱스에 저장되지 않습니다. 이는 원하는 모든 가치가 될 수 있습니다.

사용자 정의 필드 추가: 이 워크플로에는 두 개의 필드가 필요합니다.

  • 필드 1: 튜닝 필요 토글
    • 애널리스트가 튜닝 요청을 시작하기 위해 클릭하는 버튼입니다.

      • 레이블: Open tuning request?
      • 유형: 토글
      • 기본값입니다: Off
    • 필드 2: 튜닝 요청 세부 정보

      • 이 필드에서 분석가는 예외 추가, 심각도 낮추기, 쿼리 로직 조정 등 변경해야 할 사항에 대한 구체적인 세부 정보를 제공할 수 있습니다.
      • Name: Tuning request detail
      • 유형: 텍스트
    • 기본값입니다: Off

런타임 필드를 사용하여 사용자 지정 필드 매핑하기

Kibana 케이스에서 사용자 정의 필드로 작업할 때 어려운 점은 cases.custom_fields 필드가 객체 배열로 매핑되고 각 객체가 이름과 값이 있는 사용자 정의 필드를 나타낸다는 점입니다. 이러한 구조로 인해 KQL에서 특정 사용자 정의 필드를 직접 쿼리하기 어렵습니다. 예를 들어 cases.custom_fields.open_tuning_request : "true" 과 같은 쿼리를 사용할 수 없습니다. 이를 극복하기 위해 런타임 필드를 사용하여 사용자 지정 필드를 구문 분석하고 쿼리할 수 있습니다.

런타임 필드는 쿼리 시점에 평가되는 필드입니다. 데이터를 다시 색인할 필요 없이 즉석에서 새 필드를 만들 수 있습니다. .kibana_alerting_cases 인덱스에 런타임 필드를 정의하여 간단한 스크립트를 사용하여 cases.custom_fields 배열을 구문 분석하고 필요한 값을 쉽게 쿼리할 수 있는 새 필드로 추출할 수 있습니다.

이 워크플로에서는 위에서 만든 사용자 정의 필드에 매핑할 두 개의 런타임 필드를 만들겠습니다:
* TuningRequired: " 튜닝 요청 열기" 토글이 켜져 있는 경우 true 가 되는 부울 필드입니다.
* TuningDetail: " 튜닝 요청 세부 정보" 필드에 있는 애널리스트의 의견을 담을 텍스트 필드입니다.

런타임 필드를 생성하기 전에, 먼저 Kibana가 각 사용자 정의 필드에 할당하는 고유 ID(key)를 식별해야 합니다. 현재 UI에서 이 ID를 바로 확인할 수 있는 방법은 없습니다. 이를 찾기 위해 다음과 같은 해결 방법을 사용했습니다:

  1. 필드를 만듭니다. 다른 사용자 정의 필드를 사용하는 경우 새 필드 키를 쉽게 식별할 수 있도록 사용자 정의 필드를 한 번에 하나씩 만들어야 합니다. 위에서 언급한 두 개의 필드만 있는 경우 텍스트 또는 토글이 될 수 있는 type 값을 사용하여 구분할 수 있습니다.
  2. 새 케이스를 만듭니다. 필드를 추가한 후, Kibana에서 테스트 케이스를 생성하고 설명 필드에 일부 데이터를 추가하고 다른 모든 사용자 정의 필드를 거짓 또는 공백으로 설정한 상태에서 튜닝 필수 필드를 true로 전환했습니다.
  3. 사례 문서를 확인합니다. 그런 다음 Discover로 이동하여 .kibana_alerting_cases 인덱스를 쿼리하여 새 사례에 대한 문서를 찾았습니다. 문서 소스에서 cases.customFields 배열을 검사하면 새 사용자 정의 필드와 연결된 key 을 찾을 수 있습니다. 런타임 스크립트에서 사용할 key 필드의 값을 저장합니다.

cases.customFields 데이터의 형식은 다음과 같습니다:

  [
    {
      "key": "4537b921-3ca4-4ff0-aa39-02dd6a3177bd",
      "type": "text",
      "value": "This alert is too noisy"
    },
    {
      "key": "cdf28896-c793-43d2-9384-99562e23a646",
      "type": "toggle",
      "value": true
    }
  ]

런타임 필드 생성

Kibana UI를 통해 또는 개발 도구 콘솔에서 Elasticsearch API를 사용하여 런타임 필드를 추가할 수 있습니다. 사례 정보에 대한 데이터 보기를 아직 만들지 않았다면 먼저 만들어야 합니다.

새 Kibana 사례 데이터 보기에서 '필드 추가' 버튼을 클릭하면 플라이아웃 메뉴가 열리고 새 런타임 필드가 만들어집니다.

필드 이름을 입력합니다(이 예에서는 TuningRequired 을 새 부울 필드 유형으로 구성합니다). '값 설정' 토글을 클릭하여 간편한 스크립트를 통해 구성된 새 런타임 필드로 구성합니다. 이 간편한 스크립트를 업데이트하여 TUNING_REQUIRED_FIELD_KEY_UUID 을 튜닝 필요 사용자 지정 필드의 key 값으로 바꾸고 값 필드에 붙여넣고 새 런타임 필드를 저장합니다.

...
    if (params._source.containsKey('cases') &&
    params._source.cases != null &&
    params._source.cases.containsKey('customFields') &&
    params._source.cases.customFields != null) 
{
  for (def cf : params._source.cases.customFields) {
    if (cf != null &&
        cf.containsKey('key') &&
        cf.key != null &&
        cf.key.contains('TUNING_REQUIRED_FIELD_KEY_UUID') &&
        cf.containsKey('value') &&
        cf.value != null) {
      emit(cf.value);
      break;
    }
  }
}

TuningDetail 필드에 대해 이 과정을 반복하되, 이 필드의 텍스트 필드에 있는 key 값을 사용하는 것을 잊지 마세요. 대시보드나 메트릭에 사용하려는 추가 사용자 지정 필드가 있는 경우 동일한 프로세스를 통해 해당 필드도 매핑할 수 있습니다.

클러스터 설정과 데이터 보기를 '코드로' 제어하는 경우, Kibana 개발자 도구 콘솔에서 업데이트 매핑 API를 사용하여 인덱스 매핑에 런타임 필드를 추가할 수도 있습니다.

튜닝 요청 생성 자동화

이 자동화는 사용자 지정 감지 규칙(튜닝 요청으로 케이스가 업데이트될 때 새 알림을 생성하여 커넥터로 전송)을 통해 또는 API를 쿼리하는 예약된 외부 자동화를 통해 두 가지 방법으로 트리거할 수 있습니다.

이 자동화는 Tines, Github 액션 또는 사용자 지정 스크립팅과 같은 모든 자동화 플랫폼을 사용하여 만들 수 있습니다. 이것이 바로 자동화에 사용하는 로직입니다:

1단계: 최근에 다음과 같이 태그가 지정된 사례를 찾습니다. TuningRequired

이 elasticsearch 쿼리를 사용하여 TuningRequired 필드가 true 으로 설정된 지난 1시간 이내에 업데이트된 모든 사례를 찾을 수 있습니다. 이 쿼리는 cases.updated_at 필드를 시간 범위로 사용합니다. 사용자 정의 필드를 쿼리하려면 런타임 필드 매핑이 API 요청에 포함되어 있어야 합니다.

이 쿼리는 .kibana_alerting_cases 인덱스에서 지난 한 시간 동안 업데이트된 모든 사례 문서를 반환하며 TuningRequired 필드는 다음과 같이 설정되어 있습니다. true

POST /.kibana_alerting_cases/_search  
{  
  "query": {  
    "bool": {  
      "must": [],  
      "filter": [  
        {  
          "bool": {  
            "should": [  
              {  
                "match": {  
                  "TuningRequired": true  
                }  
              }  
            ],  
            "minimum_should_match": 1  
          }  
        },  
        {  
          "range": {  
            "cases.updated_at": {  
              "format": "strict_date_optional_time",  
              "gte": "now-1h",  
              "lte": "now"  
            }  
          }  
        }  
      ],  
      "should": [],  
      "must_not": []  
    }  
  },  
 "runtime_mappings": {  
   "TuningDetail": {  
     "type": "keyword",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('6cadc70a-7d68-4531-9861-7d5bc24c4c1c') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   },  
   "TuningRequired": {  
     "type": "boolean",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('496e71f2-2bce-47a2-93a8-00db0de2d1b4') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   }  
 },  
  "fields": [  
    "TuningDetail",  
    "TuningRequired"  
  ]  
}

케이스에서 필드가 변경되거나 댓글이 작성될 때마다 updated_at 필드가 현재 시간으로 업데이트됩니다. 케이스에 업데이트나 댓글을 추가하면 이 타임스탬프가 업데이트되므로 케이스가 업데이트되는 동안 이 자동화를 정기적으로 실행하면 하나의 케이스가 여러 번 반환될 수 있습니다. 이를 위해 활용되는 모든 자동화 프로세스에는 이 시나리오에서 동일한 사례를 여러 번 처리하는 것을 방지하기 위한 중복 제거 프로세스가 있어야 합니다.

2단계: 각 케이스 구문 분석

이전 쿼리에서 반환된 각 사례를 반복하여 한 번에 하나씩 처리합니다. 반환되는 각 문서에는 사용자 정의 필드의 값과 기타 유용한 필드가 포함된 fields 배열이 포함됩니다. 다음 각 필드를 구문 분석하여 나중에 사용할 수 있도록 저장합니다:

  • _id 필드의 형식은 cases:{{case_ID}} 과 같은 형식입니다. 케이스 ID는 향후 자동화에서 케이스에 댓글을 추가하거나 케이스에 첨부된 모든 알림을 검색하기 위한 API 요청에 사용됩니다.
  • cases.title 는 케이스의 제목입니다.
  • cases.assignees 케이스가 할당되는 대상입니다.
  • cases.updated_by 는 케이스를 마지막으로 업데이트한 사람으로, 튜닝 요청을 제출한 사람인 경우가 많으며 자세한 정보를 얻기 위해 누구에게 연락해야 하는지 알 때 유용합니다.
  • cases.tags 태그를 사용하여 케이스를 정렬하거나 식별하는 경우 유용할 수 있습니다.

3단계: 케이스에 첨부된 알림 검색하기

각 케이스에 대해 어떤 알림이 첨부되어 있는지 확인하여 어떤 알림을 조정해야 하는지 알 수 있습니다. 케이스에 대한 _id 필드와 함께 케이스 API를 사용하여 이 작업을 수행할 수 있습니다.

/api/cases/{caseId}/alerts

이 쿼리는 케이스에 첨부된 모든 알림 id 값의 배열을 반환합니다. 이 ID 값을 사용하여 .siem-signals* elasticsearch 인덱스를 쿼리하여 조정이 필요한 케이스에 첨부된 각 알림에 대한 전체 정보를 찾을 수 있습니다.

POST /.siem-signals-*/_search  
{  
 "size": 1,  
 "query": {  
   "bool": {  
     "must": [],  
     "filter": [  
       {  
         "bool": {  
           "should": [  
             {  
               "match": {  
                 "_id": "{{alert_id}}"  
               }  
             }  
           ],  
           "minimum_should_match": 1  
         }  
       },  
       {  
         "range": {  
           "@timestamp": {  
             "format": "strict_date_optional_time",  
             "gte": "now-30d",  
             "lte": "now"  
           }  
         }  
       }  
     ],  
     "should": [],  
     "must_not": []  
   }  
 }  
}

이 쿼리 결과에서 이름, 작성 날짜 등 알림에 대한 정보와 함께 user.name 또는 process.name 필드와 같이 튜닝에 도움이 될 수 있는 기타 정보를 추출할 수 있습니다. 하나의 케이스에 여러 개의 알림이 첨부될 수 있으므로 signal.rule.name 값으로 알림을 중복 제거해야 합니다.

4단계: 튜닝 요청 열기.

이 단계는 사용자 환경에서 사용하는 티켓팅 시스템에 따라 다릅니다. 저희 팀은 깃허브 이슈를 사용하여 튜닝 요청과 슬랙 알림을 추적하지만, 자동화를 지원하는 티켓팅 또는 프로젝트 관리 시스템에서도 이 작업을 수행할 수 있습니다.

다음은 Github과 Slack을 모두 사용하여 튜닝 요청을 추적하는 자동화에 사용하는 로직 흐름입니다:

  • 알림의 이름을 사용하여 기존 미결 튜닝 요청을 검색합니다.
    • 기존 튜닝 요청이 있는 경우 해당 요청을 케이스의 세부 정보와 새 요청으로 업데이트합니다.
    • 기존 요청이 없는 경우 새 튜닝 요청 이슈를 열고 정보를 첨부합니다.
  • 그런 다음 조정 요청 링크, 사례 링크, 요청 및 알림에 대한 세부 정보가 포함된 슬랙 알림을 탐지 엔지니어링 팀의 슬랙 채널로 보냅니다.
  • 그런 다음 사례 API를 사용하여 원래 사례에 튜닝 요청 이슈에 대한 링크가 포함된 댓글을 추가합니다.
  • 선택적 AI 에이전트: 저희는 AI 에이전트를 사용하여 알림 및 사례 정보를 분석한 다음 튜닝 요청에 대한 더 나은 컨텍스트를 제공하고 잠재적으로 탐지 규칙에 대한 변경 사항을 추천하는 실험을 시작하고 있습니다.

이 자동화의 최종 결과는 SOC 분석가가 케이스에서 클릭 한 번으로 상세한 탐지 튜닝 요청 티켓을 생성할 수 있다는 것입니다. 이러한 자동화를 통해 오탐지 감소와 탐지 규칙의 전반적인 효율성이 크게 향상되었습니다.

결론

사용자 정의 필드와 함께 Kibana 케이스를 사용하고 자동화 플랫폼과 통합하면 많은 수동 프로세스를 최적화할 수 있습니다. 이 자동화된 워크플로는 분석가 피드백 수집과 관련된 수작업 오버헤드를 줄여주므로 귀중한 분석가 인사이트를 탐지 규칙의 실행 가능한 개선 사항으로 신속하게 전환할 수 있습니다. 그 결과 새로운 위협에 빠르게 적응하고 경보 피로를 줄일 수 있는 보다 효율적이고 정확하며 탄력적인 SOC를 구축할 수 있습니다.

SOC의 효율성을 최적화하고 탐지 태세를 개선할 준비가 되셨나요? 지금 바로 Elastic Security를 살펴보고 자동화된 조정 요청 워크플로우를 구축하세요!

이 문서 공유하기