ServiceNow Security 로그 수집

다음에서 지원:

이 문서에서는 비즈니스 규칙을 통해 구성된 아웃바운드 웹훅을 사용하여 ServiceNow 보안 이벤트를 Google Security Operations로 내보내는 방법을 설명합니다. 수집 라벨은 원시 로그 데이터를 구조화된 UDM 형식으로 정규화하는 파서를 식별합니다.

통합 아키텍처

  • 이 통합은 ServiceNow 비즈니스 규칙을 사용하여 보안 이벤트를 Google SecOps에 실시간으로 푸시합니다.

    ServiceNow Security Tables
        ↓ (Business Rules trigger on insert/update)
    ServiceNow RESTMessageV2 API
        ↓ (HTTP POST)
    Google Security Operations Webhook Endpoint
        ↓ (Parser: SERVICENOW_SECURITY)
    Unified Data Model (UDM)
    

통합 특성:

  • 이벤트 기반 푸시: 생성되거나 업데이트될 때 즉시 전송되는 이벤트
  • 실시간: 짧은 지연 시간 (초)
  • 선택적 내보내기: 내보낼 테이블 및 이벤트 구성
  • 대량 내보내기 아님: 이전 데이터를 전송하지 않음

시작하기 전에

다음 기본 요건이 충족되었는지 확인합니다.

  • Google SecOps 인스턴스
  • 보안 사고 대응 (SIR) 플러그인이 설치된 ServiceNow 인스턴스
  • 다음 역할이 있는 ServiceNow 사용자 계정:
    • admin 또는 sn_si.admin (비즈니스 규칙 만들기)
    • 시스템 정의 > 비즈니스 규칙에 대한 액세스
    • 시스템 정의> 스크립트 포함에 대한 액세스
  • Google Google Cloud 콘솔에 대한 권한 있는 액세스 (API 키 생성용)

내보낼 ServiceNow Security 테이블

다음 표에는 SIEM 분석을 위한 보안 관련 데이터가 포함되어 있습니다.

API 이름 설명 우선순위
보안 사고 sn_si_incident 보안 사고, 조사 높음
모니터링 가능성 sn_si_observable IOC: IP 주소, 도메인, 파일 해시 높음
시스템 로그 syslog 인증 이벤트, 로그인 실패 MEDIUM
감사 sys_audit 필드 수준 변경사항, 권한 수정 MEDIUM
사용자 역할 할당 sys_user_has_role 역할 부여/취소 LOW
보안 발견 항목 sn_si_finding 보안 감지 및 발견 항목 LOW

이 가이드에서는 우선순위가 '높음'인 테이블의 비즈니스 규칙 예를 제공합니다. 동일한 패턴을 사용하여 통합을 추가 테이블로 확장할 수 있습니다.

ServiceNow Security 이벤트를 수집하도록 Google SecOps에서 피드 구성

웹훅 피드 설정

  1. SIEM 설정> 피드로 이동합니다.
  2. 새 피드 추가를 클릭합니다.
  3. 다음 페이지에서 단일 피드 구성을 클릭합니다.
  4. 피드 이름 필드에 피드 이름을 입력합니다(예: ServiceNow Security Events).
  5. 소스 유형으로 웹훅을 선택합니다.
  6. 로그 유형으로 ServiceNow Security를 선택합니다.
  7. 다음을 클릭합니다.

피드 매개변수 구성

  1. 다음 입력 매개변수의 값을 지정합니다.

    • 분할 구분 기호: \n를 입력하여 로그 줄을 구분합니다.
    • 애셋 네임스페이스: 애셋 네임스페이스입니다.
    • 수집 라벨: 이 피드의 모든 이벤트에 적용되는 라벨입니다.
  2. 다음을 클릭합니다.

  3. 확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.

보안 비밀 키 생성 및 엔드포인트 URL 검색

  1. 보안 비밀 키 생성을 클릭하여 이 피드를 인증하기 위한 보안 비밀 키를 생성합니다.
  2. 보안 비밀 키를 복사하여 안전한 위치에 저장합니다.

  3. 세부정보 탭으로 이동합니다.

  4. 엔드포인트 정보 필드에서 피드 엔드포인트 URL을 복사합니다.

    • 엔드포인트 URL의 예: https://malachiteingestion-pa.googleapis.com/v2/unstructured/projects/PROJECT_ID/locations/LOCATION/instances/INSTANCE_ID/logTypes/SERVICENOW_SECURITY:import
  5. 완료를 클릭합니다.

인증을 위한 API 키 만들기

  1. Google Cloud 콘솔 사용자 인증 정보 페이지로 이동합니다.
  2. 사용자 인증 정보 만들기를 클릭한 후 API 키를 선택합니다.
  3. 키 제한을 클릭합니다.
  4. API 제한사항에서 다음을 수행합니다.
    • 키 제한을 선택합니다.
    • Google SecOps API (Chronicle API)를 선택합니다.
  5. 저장을 클릭합니다.
  6. API 키를 복사하여 안전한 위치에 저장합니다.

ServiceNow 통합 사용자 인증 정보 구성

안전한 액세스를 위해 Google SecOps 사용자 인증 정보를 ServiceNow 시스템 속성으로 저장합니다.

  1. ServiceNow에서 System Properties(시스템 속성) > sys_properties.list로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 첫 번째 속성을 만듭니다.
    • 이름: x_chronicle.endpoint_url
    • : 이전 단계에서 복사한 피드 엔드포인트 URL을 붙여넣습니다.
    • 유형: string
  4. 제출을 클릭합니다.
  5. 새로 만들기를 클릭하여 두 번째 속성을 만듭니다.
    • 이름: x_chronicle.api_key
    • : Google Cloud API 키를 붙여넣습니다.
    • 유형: password (값을 암호화함)
  6. 제출을 클릭합니다.
  7. 새로 만들기를 클릭하여 세 번째 속성을 만듭니다.
    • 이름: x_chronicle.secret_key
    • : Google SecOps 피드 보안 비밀 키를 붙여넣습니다.
    • 유형: password (값을 암호화함)
  8. 제출을 클릭합니다.

재사용 가능한 웹훅 유틸리티 스크립트 포함 만들기

이 스크립트 포함은 비즈니스 규칙에서 Google SecOps로 이벤트를 전송하기 위한 재사용 가능한 함수를 제공합니다.

  1. 시스템 정의 > 스크립트 포함으로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.
    • 이름: ChronicleWebhookUtil
    • API 이름: ChronicleWebhookUtil
    • 클라이언트 호출 가능: 선택되지 않음
    • 활성: 선택됨
  4. 스크립트 필드에 다음 코드를 입력합니다.

    var ChronicleWebhookUtil = Class.create();
    ChronicleWebhookUtil.prototype = {
        initialize: function() {
            // Read credentials from System Properties
            this.endpointURL = gs.getProperty('x_chronicle.endpoint_url');
            this.apiKey = gs.getProperty('x_chronicle.api_key');
            this.secretKey = gs.getProperty('x_chronicle.secret_key');
        },
    
        sendEvent: function(eventData, eventType) {
            try {
                // Validate credentials
                if (!this.endpointURL || !this.apiKey || !this.secretKey) {
                    gs.error('[Chronicle] Missing configuration. Check System Properties: x_chronicle.*');
                    return false;
                }
    
                // Prepare payload
                var payload = {
                    event_type: eventType,
                    timestamp: new GlideDateTime().getDisplayValue(),
                    data: eventData,
                    source: "ServiceNow",
                    source_instance: gs.getProperty('instance_name')
                };
    
                // Create REST message
                var request = new sn_ws.RESTMessageV2();
                request.setEndpoint(this.endpointURL + '?key=' + this.apiKey);
                request.setHttpMethod('POST');
    
                // Set headers
                request.setRequestHeader('Content-Type', 'application/json');
                request.setRequestHeader('x-chronicle-auth', this.secretKey);
    
                // Set request body
                request.setRequestBody(JSON.stringify(payload));
    
                // Execute request
                var response = request.execute();
                var statusCode = response.getStatusCode();
                var responseBody = response.getBody();
    
                // Check response
                if (statusCode == 200 || statusCode == 201 || statusCode == 204) {
                    gs.info('[Chronicle] Event sent successfully: ' + eventType + ' | Status: ' + statusCode);
                    return true;
                } else {
                    gs.error('[Chronicle] Failed to send event: ' + eventType + ' | Status: ' + statusCode + ' | Response: ' + responseBody);
                    return false;
                }
    
            } catch (ex) {
                gs.error('[Chronicle] Exception sending event: ' + ex.message);
                return false;
            }
        },
    
        type: 'ChronicleWebhookUtil'
    };
    
  5. 제출을 클릭합니다.

이벤트 내보내기를 위한 비즈니스 규칙 만들기

비즈니스 규칙은 ServiceNow 테이블에서 레코드가 생성되거나 업데이트될 때 자동으로 트리거됩니다. Google SecOps로 내보낼 각 테이블에 대해 비즈니스 규칙을 만듭니다.

비즈니스 규칙: 보안 사고

이 비즈니스 규칙은 보안 사고 이벤트를 Google SecOps로 내보냅니다.

  1. 시스템 정의 > 비즈니스 규칙으로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.

    실행 시점:

    필드
    이름 Chronicle - Export Security Incident
    Security Incident [sn_si_incident]
    활성 선택됨
    고급 선택됨
    시기 after
    삽입 선택됨
    업데이트 선택됨
    삭제 선택사항 (삭제를 추적하려면 선택)
    Order 100
  4. 고급 탭을 클릭하고 스크립트 필드로 이동하여 다음 코드를 입력합니다.

    (function executeRule(current, previous /*null when async*/) {
    
        // Extract incident data
        var incidentData = {
            sys_id: current.getValue('sys_id'),
            number: current.getValue('number'),
            short_description: current.getValue('short_description'),
            description: current.getValue('description'),
            state: current.getDisplayValue('state'),
            priority: current.getDisplayValue('priority'),
            severity: current.getDisplayValue('severity'),
            risk_score: current.getValue('risk_score'),
            category: current.getDisplayValue('category'),
            subcategory: current.getDisplayValue('subcategory'),
            assigned_to: current.getDisplayValue('assigned_to'),
            assignment_group: current.getDisplayValue('assignment_group'),
            caller: current.getDisplayValue('caller'),
            affected_user: current.getDisplayValue('affected_user'),
            opened_at: current.getValue('opened_at'),
            closed_at: current.getValue('closed_at'),
            resolved_at: current.getValue('resolved_at'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_updated_on: current.getValue('sys_updated_on'),
            sys_created_by: current.getValue('sys_created_by'),
            sys_updated_by: current.getValue('sys_updated_by'),
            work_notes: current.getValue('work_notes'),
            close_notes: current.getValue('close_notes')
        };
    
        // Send to Chronicle
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(incidentData, 'security_incident');
    
    })(current, previous);
    
  5. 제출을 클릭합니다.

비즈니스 규칙: 관찰 가능 항목 (IOC)

이 비즈니스 규칙은 관측 가능한 데이터 (IP 주소, 도메인, 파일 해시)를 Google SecOps로 내보냅니다.

  1. 시스템 정의 > 비즈니스 규칙으로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.

    필드
    이름 Chronicle - Export Observable
    Observable [sn_si_observable]
    활성 선택됨
    고급 선택됨
    시기 after
    삽입 선택됨
    업데이트 선택됨
    Order 100
  4. 고급 탭을 클릭하고 스크립트 필드로 이동하여 다음 코드를 입력합니다.

    (function executeRule(current, previous) {
    
        var observableData = {
            sys_id: current.getValue('sys_id'),
            value: current.getValue('value'),
            type: current.getDisplayValue('type'),
            finding: current.getDisplayValue('finding'),
            sighting_count: current.getValue('sighting_count'),
            notes: current.getValue('notes'),
            security_tags: current.getValue('security_tags'),
            mitre_technique: current.getDisplayValue('mitre_technique'),
            mitre_tactic: current.getDisplayValue('mitre_tactic'),
            mitre_malware: current.getDisplayValue('mitre_malware'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_created_by: current.getValue('sys_created_by')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(observableData, 'observable');
    
    })(current, previous);
    
  5. 제출을 클릭합니다.

비즈니스 규칙: 시스템 로그인 이벤트

이 비즈니스 규칙은 인증 및 로그인 이벤트를 Google SecOps로 내보냅니다.

  1. 시스템 정의 > 비즈니스 규칙으로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.

    필드
    이름 Chronicle - Export System Log
    System Log [syslog]
    활성 선택됨
    고급 선택됨
    시기 after
    삽입 선택됨
    Order 100
    조건 current.level == "error" || current.source.indexOf("login") != -1
  4. 고급 탭을 클릭하고 스크립트 필드로 이동하여 다음 코드를 입력합니다.

    (function executeRule(current, previous) {
    
        var logData = {
            sys_id: current.getValue('sys_id'),
            level: current.getValue('level'),
            source: current.getValue('source'),
            message: current.getValue('message'),
            sys_created_on: current.getValue('sys_created_on'),
            sys_created_by: current.getValue('sys_created_by')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(logData, 'system_log');
    
    })(current, previous);
    
  5. 제출을 클릭합니다.

비즈니스 규칙: 감사 추적 (권한 변경)

이 비즈니스 규칙은 감사 추적 목적으로 필드 수준 변경사항을 내보냅니다.

  1. 시스템 정의 > 비즈니스 규칙으로 이동합니다.
  2. New(새로 만들기)를 클릭합니다.
  3. 다음 구성 세부정보를 제공합니다.

    필드
    이름 Chronicle - Export Audit Changes
    Audit [sys_audit]
    활성 선택됨
    고급 선택됨
    시기 after
    삽입 선택됨
    Order 100
    조건 다음 스크립트를 참고하세요.

    조건 (중요한 변경사항만 필터링):

    ```javascript
    current.tablename == 'sys_user_has_role' || current.tablename == 'sys_user_group_member' || current.tablename == 'sn_si_incident' || current.fieldname == 'active' || current.fieldname == 'locked_out'
    ```
    
  4. 고급 탭을 클릭하고 스크립트 필드로 이동하여 다음 코드를 입력합니다.

    (function executeRule(current, previous) {
    
        var auditData = {
            sys_id: current.getValue('sys_id'),
            tablename: current.getValue('tablename'),
            documentkey: current.getValue('documentkey'),
            fieldname: current.getValue('fieldname'),
            oldvalue: current.getValue('oldvalue'),
            newvalue: current.getValue('newvalue'),
            user: current.getDisplayValue('user'),
            reason: current.getValue('reason'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(auditData, 'audit_change');
    
    })(current, previous);
    
  5. 제출을 클릭합니다.

선택사항: 내보낼 추가 테이블

사용자 역할 할당 변경

보안 감사를 위해 역할 부여 및 취소를 내보냅니다.

  • sys_user_has_role 테이블에 비즈니스 규칙을 만듭니다.

    (function executeRule(current, previous) {
    
        var roleData = {
            sys_id: current.getValue('sys_id'),
            user: current.getDisplayValue('user'),
            role: current.getDisplayValue('role'),
            granted_by: current.getDisplayValue('granted_by'),
            state: current.getValue('state'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(roleData, 'role_assignment');
    
    })(current, previous);
    

보안 발견 항목

보안 감지 및 발견 항목을 내보냅니다.

  • sn_si_finding 테이블에 비즈니스 규칙을 만듭니다.

    (function executeRule(current, previous) {
    
        var findingData = {
            sys_id: current.getValue('sys_id'),
            finding: current.getValue('finding'),
            confidence: current.getValue('confidence'),
            severity: current.getDisplayValue('severity'),
            observable: current.getDisplayValue('observable'),
            sys_created_on: current.getValue('sys_created_on')
        };
    
        var chronicleUtil = new ChronicleWebhookUtil();
        chronicleUtil.sendEvent(findingData, 'finding');
    
    })(current, previous);
    

Google SecOps 피드에 대한 자세한 내용은 Google SecOps 피드 문서를 참고하세요. 각 피드 유형의 요구사항은 유형별 피드 구성을 참고하세요.

피드를 만들 때 문제가 발생하면 Google SecOps 지원팀에 문의하세요.

UDM 매핑 테이블

ServiceNow 필드 UDM 매핑 논리
number metadata.product_event_type 문제 또는 이벤트 번호
short_description security_result.summary 보안 이벤트에 대한 간단한 설명
severity security_result.severity 이벤트 심각도 수준
priority security_result.priority 이벤트 우선순위
caller principal.user.userid 이벤트를 신고하거나 트리거한 사용자
affected_user target.user.userid 보안 이벤트의 영향을 받은 사용자
assigned_to security_result.action_details 인시던트에 할당된 분석가
sys_created_on metadata.event_timestamp 이벤트 생성 타임스탬프
value (관찰 가능) network.ip 또는 network.dns.questions.name 관측 가능한 값 (IP, 도메인, 해시)
type (관찰 가능) security_result.detection_fields.value 관찰 가능한 유형 (IP 주소, 도메인, 파일 해시)

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