MISP IOC 로그 수집
이 문서에서는 Bindplane을 사용하여 MISP (Malware Information Sharing Platform) IOC 로그를 Google Security Operations에 수집하는 방법을 설명합니다. 파서는 CSV 및 JSON 형식의 데이터를 모두 처리합니다. IP 주소, 도메인, 해시, URL과 같은 IOC 속성을 추출하여 심각도, 신뢰도, 설명과 같은 위협 세부정보와 함께 통합 데이터 모델 (UDM)에 매핑합니다. 파서는 입력 데이터 내의 단일 및 다중 IOC 항목을 모두 처리하여 일관된 UDM 출력으로 정규화합니다.
시작하기 전에
다음 기본 요건이 충족되었는지 확인합니다.
- Google SecOps 인스턴스입니다.
systemd
가 있는 Linux 호스트- 프록시 뒤에서 실행하는 경우 Bindplane 에이전트 요구사항에 따라 방화벽 포트가 열려 있는지 확인합니다.
- MISP 서버에 대한 권한이 있는 액세스
Google SecOps 수집 인증 파일 가져오기
- Google SecOps 콘솔에 로그인합니다.
- SIEM 설정 > 수집 에이전트로 이동합니다.
- 수집 인증 파일을 다운로드합니다.
- Bindplane이 설치될 시스템에 파일을 안전하게 저장합니다.
Google SecOps 고객 ID 가져오기
- Google SecOps 콘솔에 로그인합니다.
- SIEM 설정*> 프로필로 이동합니다.
- 조직 세부정보 섹션에서 고객 ID를 복사하여 저장합니다.
MISP API 사용자 인증 정보 가져오기
- 관리자로 MISP 웹 인터페이스에 로그인합니다.
- 관리 > 인증 키 목록으로 이동합니다.
- 인증 키 추가를 클릭합니다.
- 다음 구성 세부정보를 제공합니다.
- 사용자: 키와 연결된 사용자 계정을 선택합니다.
- 선택사항: 허용된 IP: 키에 허용된 IP 주소를 지정합니다.
- 만료: 만료가 없도록 하려면 비워두고 필요에 따라 설정합니다.
- 제출을 클릭합니다.
- API 키를 복사하여 안전한 위치에 저장합니다.
- 키를 기록했습니다를 클릭합니다.
MISP 데이터 내보내기 구성
MISP 서버에 PyMISP를 설치합니다.
pip3 install pymisp
내보내기 디렉터리를 만듭니다.
sudo mkdir -p /opt/misp/scripts sudo mkdir -p /opt/misp/ioc_export
사용자 인증 정보 파일
/opt/misp/scripts/keys.py
을 만듭니다.misp_url = 'https://<MISP_SERVER_URL>' misp_key = '<MISP_API_KEY>' misp_verifycert = True misp_client_cert = ''
<MISP_SERVER_URL>
을 MISP 서버 URL로 바꿉니다.<MISP_API_KEY>
를 사전 요구사항의 API 키로 바꿉니다.
내보내기 스크립트
/opt/misp/scripts/misp_export.py
를 만듭니다.#!/usr/bin/env python3 # -*- coding: utf-8 -*- import argparse from pymisp import ExpandedPyMISP from keys import misp_url, misp_key, misp_verifycert if __name__ == '__main__': parser = argparse.ArgumentParser(description='Export MISP IOCs to CSV format.') parser.add_argument("--controller", default='attributes', help="Controller to use for search (events, objects, attributes)") parser.add_argument("--event_id", help="Event ID to fetch. Without it, fetches recent data.") parser.add_argument("--attributes", nargs='*', help="Requested attributes for CSV export") parser.add_argument("--misp_types", nargs='+', help="MISP types to fetch (ip-src, hostname, domain, etc.)") parser.add_argument("--context", action='store_true', help="Add event level context (tags, metadata)") parser.add_argument("--outfile", required=True, help="Output file to write the CSV data") parser.add_argument("--last", required=True, help="Time period: days (d), hours (h), minutes (m) - e.g., 1d, 12h, 30m") args = parser.parse_args() api = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=False) response = api.search( controller=args.controller, return_format='csv', type_attribute=args.misp_types, publish_timestamp=args.last, include_context=args.context, requested_attributes=args.attributes or None ) with open(args.outfile, 'w') as response_file: response_file.write(response)
- 스크립트를 실행 가능하게 만듭니다.
sudo chmod +x /opt/misp/scripts/misp_export.py
MISP 데이터 내보내기 예약
- crontab을 사용하여 예약 내보내기를 만듭니다.
sudo crontab -e
다음 cron 항목을 추가합니다.
# Export different IOC types daily with context 0 0 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/domains.csv --misp_types domain --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 1 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-src.csv --misp_types ip-src --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 2 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/ip-dst.csv --misp_types ip-dst --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 3 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/urls.csv --misp_types url --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 4 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/sha256.csv --misp_types sha256 --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 5 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/filenames.csv --misp_types filename --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 6 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/registries.csv --misp_types regkey --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info 0 7 * * * python3 /opt/misp/scripts/misp_export.py --outfile /opt/misp/ioc_export/mutexes.csv --misp_types mutex --last 1d --context --attributes uuid event_id category type value comment to_ids date attribute_tag event_info
선택적으로 MISP에서 피드를 가져오도록 예약합니다.
23 0 * * * curl --insecure --header "Authorization: <MISP_API_KEY>" --header "Accept: application/json" --header "Content-Type: application/json" https://<MISP_SERVER_URL>/feeds/fetchFromAllFeeds
Bindplane 에이전트 설치
다음 안내에 따라 Linux 운영체제에 Bindplane 에이전트를 설치합니다.
Linux 설치
- 루트 또는 sudo 권한으로 터미널을 엽니다.
다음 명령어를 실행합니다.
sudo sh -c "$(curl -fsSlL https://github.com/observiq/bindplane-otel-collector/releases/latest/download/install_unix.sh)" install_unix.sh
추가 설치 리소스
- 추가 설치 옵션은 설치 가이드를 참고하세요.
MISP 로그를 수집하여 Google SecOps로 전송하도록 Bindplane 에이전트 구성
구성 파일에 액세스합니다.
config.yaml
파일을 찾습니다. 일반적으로 Linux의/etc/bindplane-agent/
디렉터리에 있습니다.- 텍스트 편집기 (예:
nano
,vi
)를 사용하여 파일을 엽니다.
다음과 같이
config.yaml
파일을 수정합니다.receivers: filelog: file_path: /opt/misp/ioc_export/*.log exporters: chronicle/chronicle_w_labels: compression: gzip # Adjust the path to the credentials file you downloaded in Step 1 creds_file_path: '/path/to/ingestion-authentication-file.json' # Replace with your actual customer ID from Step 2 customer_id: <customer_id> endpoint: malachiteingestion-pa.googleapis.com # Add optional ingestion labels for better organization ingestion_labels: log_type: 'MISP_IOC' raw_log_field: body service: pipelines: logs/source0__chronicle_w_labels-0: receivers: - filelog exporters: - chronicle/chronicle_w_labels
<CUSTOMER_ID>
를 사전 준비의 실제 고객 ID로 바꿉니다./path/to/ingestion-authentication-file.json
를 인증 파일이 저장된 경로로 업데이트합니다.
변경사항을 적용하려면 Bindplane 에이전트를 다시 시작하세요.
Linux에서 Bindplane 에이전트를 다시 시작하려면 다음 명령어를 실행합니다.
sudo systemctl restart observiq-otel-collector
UDM 매핑 테이블
로그 필드 | UDM 매핑 | 논리 |
---|---|---|
Attribute.category | entity.metadata.threat.category_details | Attribute 객체의 category 필드에서 직접 매핑 |
Attribute.comment | entity.metadata.threat.summary | Attribute 객체의 comment 필드에서 직접 매핑 |
Attribute.deleted | entity.metadata.threat.detection_fields.value | Attribute 객체의 deleted 필드에서 직접 매핑 키가 Attribute deleted 로 설정됩니다. |
Attribute.event_id | entity.metadata.threat.detection_fields.value | Attribute 객체의 event_id 필드에서 직접 매핑 키가 Attribute event_id 로 설정됩니다. |
Attribute.first_seen | entity.metadata.threat.detection_fields.value | Attribute 객체의 first_seen 필드에서 직접 매핑 키가 Attribute first_seen 로 설정됩니다. |
Attribute.id | entity.metadata.threat.detection_fields.value | Attribute 객체의 id 필드에서 직접 매핑 키는 원시 로그의 형식에 따라 Attribute id 또는 Attribute id $$ 로 설정됩니다. |
Attribute.timestamp | entity.metadata.threat.detection_fields.value | Attribute 객체의 timestamp 필드에서 직접 매핑 키가 Attribute timestamp 로 설정됩니다. |
Attribute.to_ids | entity.metadata.threat.detection_fields.value | Attribute 객체의 to_ids 필드에서 직접 매핑 키가 Attribute to_ids 로 설정됩니다. |
Attribute.type | entity.metadata.threat.category_details | Attribute 객체의 type 필드에서 직접 매핑 |
Attribute.type | log_type | IOC 유형을 확인하고 적절한 UDM 필드에 매핑하는 데 사용됩니다. |
Attribute.uuid | entity.metadata.product_entity_id | Attribute 객체의 uuid 필드에서 직접 매핑 |
Attribute.value | entity.entity.file.full_path | Attribute.type 이 filename 인 경우 매핑됩니다. |
Attribute.value | entity.entity.file.md5 | Attribute.type 이 md5 인 경우 매핑됩니다. |
Attribute.value | entity.entity.file.sha1 | Attribute.type 이 sha1 인 경우 매핑됩니다. |
Attribute.value | entity.entity.file.sha256 | Attribute.type 이 sha256 인 경우 매핑됩니다. |
Attribute.value | entity.entity.hostname | Attribute.type 이 domain 인 경우 매핑됩니다. |
Attribute.value | entity.entity.ip | Attribute.type 이 ip-dst , ip-dst|port 또는 ip-src 인 경우 매핑됩니다. 값은 grok 패턴을 사용하여 추출됩니다. |
Attribute.value | entity.entity.resource.name | Attribute.type 이 mutex 인 경우 매핑됩니다. |
Attribute.value | entity.entity.registry.registry_key | Attribute.type 이 regkey 인 경우 매핑됩니다. |
Attribute.value | entity.entity.url | Attribute.type 이 uri 또는 URL 인 경우 매핑됩니다. |
1 열 | entity.metadata.product_entity_id | CSV 데이터의 첫 번째 열에서 직접 매핑 |
column14 | event_info | threat_sr.description 필드에 추가 정보를 추가하는 데 사용됩니다. |
column16 | event_source_org | CSV 데이터의 16번째 열에서 직접 매핑됩니다. |
column18 | threat_level | CSV 데이터의 18번째 열에서 직접 매핑됩니다. |
column21 | 설명 | CSV 데이터의 21번째 열에서 직접 매핑됩니다. |
column3 | misp_category | CSV 데이터의 세 번째 열에서 직접 매핑됩니다. |
column4 | 유형 | CSV 데이터의 네 번째 열에서 직접 매핑 |
column5 | 값 | CSV 데이터의 다섯 번째 열에서 직접 매핑 |
column6 | 댓글 | CSV 데이터의 여섯 번째 열에서 직접 매핑됩니다. |
column8 | ts1 | CSV 데이터의 8번째 열에서 직접 매핑됩니다. |
설명 | ioc.description | 이 값은 description 필드와 event_info 필드를 - additional info: 로 구분하여 결합하여 생성됩니다. |
설명 | entity.metadata.threat.description | description 필드에서 직접 매핑 |
event_creator_email | entity.entity.labels.value | event_creator_email 필드에서 직접 매핑 키가 event_creator_email 로 설정됩니다. |
event_source_org | ioc.feed_name | event_source_org 필드에서 직접 매핑 |
event_source_org | entity.metadata.threat.threat_feed_name | event_source_org 필드에서 직접 매핑 |
Feed.publish | entity.metadata.threat.detection_fields.value | Feed 객체의 publish 필드에서 직접 매핑 키가 Feed publish 로 설정됩니다. |
first_seen | ioc.active_timerange.start | first_seen 필드에서 직접 매핑 값이 날짜로 파싱됩니다. |
first_seen | entity.metadata.interval.start_time | first_seen 필드에서 직접 매핑 값이 날짜로 파싱됩니다. |
정보 | entity.metadata.description | info 필드에서 직접 매핑 |
last_seen | ioc.active_timerange.end | last_seen 필드에서 직접 매핑 값이 날짜로 파싱됩니다. |
log.category | ioc.categorization | log 객체의 category 필드에서 직접 매핑 |
log.category | entity.metadata.threat.category_details | log 객체의 category 필드에서 직접 매핑 |
log.comment | entity.entity.file.full_path | log.type 이 filename 이고 comment 필드가 Artifacts dropped 이 아닌 경우 매핑됩니다. |
log.comment | entity.metadata.threat.detection_fields.value | log 객체의 comment 필드에서 직접 매핑 키가 Attribute comment 로 설정됩니다. |
log.comment | entity.metadata.threat.summary | log 객체의 comment 필드에서 직접 매핑 |
log.deleted | entity.metadata.threat.detection_fields.value | log 객체의 deleted 필드에서 직접 매핑 키가 Attribute deleted 로 설정됩니다. |
log.event_id | entity.metadata.threat.detection_fields.value | log 객체의 event_id 필드에서 직접 매핑 키가 Attribute event_id 로 설정됩니다. |
log.first_seen | entity.metadata.threat.detection_fields.value | log 객체의 first_seen 필드에서 직접 매핑 키가 Attribute first_seen 로 설정됩니다. |
log.id | entity.metadata.threat.detection_fields.value | log 객체의 id 필드에서 직접 매핑 키가 Attribute id 로 설정됩니다. |
log.timestamp | entity.metadata.threat.detection_fields.value | log 객체의 timestamp 필드에서 직접 매핑 키가 Attribute timestamp 로 설정됩니다. |
log.to_ids | entity.metadata.threat.detection_fields.value | log 객체의 to_ids 필드에서 직접 매핑 키가 Attribute to_ids 로 설정됩니다. |
log.type | ioc.categorization | log 객체의 type 필드에서 직접 매핑 |
log.type | log_type | IOC 유형을 확인하고 적절한 UDM 필드에 매핑하는 데 사용됩니다. |
log.uuid | entity.metadata.product_entity_id | log 객체의 uuid 필드에서 직접 매핑 |
log.value | entity.entity.file.full_path | log.type 이 filename 인 경우 매핑됩니다. |
log.value | entity.entity.file.md5 | log.type 이 md5 인 경우 매핑됩니다. |
log.value | entity.entity.file.sha1 | log.type 이 sha1 인 경우 매핑됩니다. |
log.value | entity.entity.file.sha256 | log.type 이 sha256 인 경우 매핑됩니다. |
log.value | entity.entity.hostname | log.type 이 domain 인 경우 매핑됩니다. |
log.value | entity.entity.ip | log.type 이 ip-dst , ip-dst|port 또는 ip-src 인 경우 매핑됩니다. 값은 grok 패턴을 사용하여 추출됩니다. |
log.value | entity.entity.resource.name | log.type 이 mutex 인 경우 매핑됩니다. |
log.value | entity.entity.registry.registry_key | log.type 이 regkey 인 경우 매핑됩니다. |
log.value | entity.entity.url | log.type 이 uri 또는 url 인 경우 매핑됩니다. |
log.value | ioc.domain_and_ports.domain | log.type 이 domain 인 경우 매핑됩니다. |
log.value | entity.entity.user.email_addresses | log.type 이 threat-actor 인 경우 매핑됩니다. |
misp_category | entity.metadata.threat.category_details | misp_category 필드에서 직접 매핑 |
Org.name | entity.metadata.threat.detection_fields.value | Org 객체의 name 필드에서 직접 매핑 키가 Org name 로 설정됩니다. |
게시됨 | entity.metadata.threat.detection_fields.value | published 필드에서 직접 매핑 키가 published 로 설정됩니다. |
Tag.colour | entity.metadata.threat.detection_fields.value | Tag 객체의 colour 필드에서 직접 매핑 키가 tag colour 로 설정됩니다. |
Tag.exportable | entity.metadata.threat.detection_fields.value | Tag 객체의 exportable 필드에서 직접 매핑 키가 tag exportable 로 설정됩니다. |
Tag.hide_tag | entity.metadata.threat.detection_fields.value | Tag 객체의 hide_tag 필드에서 직접 매핑 키가 tag hide_tag 로 설정됩니다. |
Tag.id | entity.metadata.threat.detection_fields.value | Tag 객체의 id 필드에서 직접 매핑 키가 tag id 로 설정됩니다. |
Tag.is_custom_galaxy | entity.metadata.threat.detection_fields.value | Tag 객체의 is_custom_galaxy 필드에서 직접 매핑 키가 tag is_custom_galaxy 로 설정됩니다. |
Tag.is_galaxy | entity.metadata.threat.detection_fields.value | Tag 객체의 is_galaxy 필드에서 직접 매핑 키가 tag is_galaxy 로 설정됩니다. |
Tag.isinherited | entity.metadata.threat.detection_fields.value | Tag 객체의 isinherited 필드에서 직접 매핑 키가 tag isinherited 로 설정됩니다. |
Tag.name | entity.metadata.threat.detection_fields.value | Tag 객체의 name 필드에서 직접 매핑 키가 tag name 로 설정됩니다. |
Tag.numerical_value | entity.metadata.threat.detection_fields.value | Tag 객체의 numerical_value 필드에서 직접 매핑 키가 tag numerical_value 로 설정됩니다. |
Tag.user_id | entity.metadata.threat.detection_fields.value | Tag 객체의 user_id 필드에서 직접 매핑 키가 tag user_id 로 설정됩니다. |
threat_level | ioc.raw_severity | threat_level 필드에서 직접 매핑 |
threat_level | entity.metadata.threat.severity_details | threat_level 필드에서 직접 매핑 |
threat_level_id | entity.entity.labels.value | threat_level_id 필드에서 직접 매핑 키가 threat_level_id 로 설정됩니다. |
ts1 | ioc.active_timerange.start | ts1 필드에서 직접 매핑 값이 날짜로 파싱됩니다. |
ts1 | entity.metadata.interval.start_time | ts1 필드에서 직접 매핑 값이 날짜로 파싱됩니다. |
entity.entity.file.full_path | type 이 filename 인 경우 매핑됩니다. |
|
entity.entity.file.md5 | type 이 md5 인 경우 매핑됩니다. |
|
entity.entity.file.sha1 | type 이 sha1 인 경우 매핑됩니다. |
|
entity.entity.file.sha256 | type 이 sha256 인 경우 매핑됩니다. |
|
entity.entity.hostname | type 이 domain 인 경우 매핑됩니다. |
|
entity.entity.ip | type 이 ip-dst , ip-dst|port 또는 ip-src 인 경우 매핑됩니다. 값은 grok 패턴을 사용하여 추출됩니다. |
|
entity.entity.port | port 필드가 비어 있지 않은 경우 매핑됩니다. 값이 정수로 변환됩니다. |
|
entity.entity.resource.name | type 이 mutex 인 경우 매핑됩니다. |
|
entity.entity.resource.resource_subtype | type 이 regkey 인 경우 매핑됩니다. 값은 regkey 로 설정됩니다. |
|
entity.entity.resource.resource_type | type 이 mutex 또는 regkey 인 경우 매핑됩니다. 값은 각각 MUTEX 또는 STORAGE_OBJECT 로 설정됩니다. |
|
entity.entity.registry.registry_key | type 이 regkey 인 경우 매핑됩니다. |
|
entity.entity.url | type 이 uri 또는 url 인 경우 매핑됩니다. |
|
entity.metadata.collected_timestamp | 값이 원시 로그 항목의 타임스탬프로 설정됩니다. | |
entity.metadata.description | 원시 로그가 CSV 형식인 경우 값은 type 필드로 설정됩니다. 그렇지 않으면 info 필드로 설정됩니다. |
|
entity.metadata.entity_type | 값은 type 또는 log_type 필드를 기반으로 결정됩니다. DOMAIN_NAME , FILE , IP_ADDRESS , MUTEX , RESOURCE , URL 일 수 있습니다. |
|
entity.metadata.interval.end_time | 값은 기본값인 253402300799초로 설정됩니다. | |
entity.metadata.interval.start_time | 값이 비어 있지 않으면 first_seen 필드로 설정됩니다. 그렇지 않으면 기본값인 1초 또는 원시 로그 항목의 타임스탬프로 설정됩니다. |
|
entity.metadata.product_name | 값은 MISP 로 설정됩니다. |
|
entity.metadata.threat.confidence | confidence 필드가 비어 있거나 f 인 경우 값은 UNKNOWN_CONFIDENCE 로 설정됩니다. 그렇지 않으면 confidence 필드의 값에 따라 HIGH_CONFIDENCE , MEDIUM_CONFIDENCE 또는 LOW_CONFIDENCE 로 설정됩니다. |
|
entity.metadata.threat.confidence_details | confidence 필드에서 직접 매핑 |
|
entity.metadata.threat.detection_fields | 값은 원시 로그의 다양한 필드에서 추출된 키-값 쌍 목록입니다. | |
entity.metadata.vendor_name | 값은 MISP 로 설정됩니다. |
|
ioc.active_timerange.end | 값이 비어 있지 않으면 last_seen 필드로 설정됩니다. |
|
ioc.active_timerange.start | 값이 비어 있지 않으면 ts1 또는 first_seen 필드로 설정됩니다. 그렇지 않으면 기본값인 1초로 설정됩니다. |
|
ioc.categorization | 원시 로그가 CSV 형식인 경우 값은 misp_category IOCs 으로 설정됩니다. 그렇지 않으면 Attribute 또는 log 객체의 category 필드로 설정됩니다. |
|
ioc.confidence_score | confidence 필드에서 직접 매핑 |
|
ioc.description | 이 값은 description 필드와 event_info 필드를 - additional info: 로 구분하여 결합하여 생성됩니다. |
|
ioc.domain_and_ports.domain | type 또는 log_type 이 domain 인 경우 매핑됩니다. |
|
ioc.feed_name | event_source_org 필드가 비어 있으면 값이 MISP 로 설정됩니다. 그렇지 않으면 event_source_org 필드로 설정됩니다. |
|
ioc.ip_and_ports.ip_address | ip 필드가 비어 있지 않은 경우 매핑됩니다. 값이 IP 주소로 변환됩니다. |
|
ioc.ip_and_ports.ports | port 필드가 비어 있지 않은 경우 매핑됩니다. 값은 부호 없는 정수로 변환됩니다. |
|
ioc.raw_severity | threat_level 필드에서 직접 매핑 |
|
타임스탬프 | 값이 원시 로그 항목의 타임스탬프로 설정됩니다. |
도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가로부터 답변을 받으세요.