Mengumpulkan log ESET Threat Intelligence

Didukung di:

Dokumen ini menjelaskan cara menyerap log ESET Threat Intelligence ke Google Security Operations menggunakan Google Cloud Storage V2, fungsi Cloud Run, dan Cloud Scheduler.

ESET Threat Intelligence (ETI) memberikan informasi berbasis bukti dan saran yang dapat ditindaklanjuti tentang ancaman yang ada atau yang baru muncul. Layanan ETI memperingatkan Anda tentang software atau aktivitas berbahaya yang dapat mengancam organisasi Anda atau pelanggannya. Layanan ini mengirimkan data intelijen ancaman melalui feed TAXII 2.1 dalam format STIX 2.1, termasuk IoC APT, C&C dan target botnet, domain berbahaya, IP, URL, file, URL phishing, ransomware, dan ancaman Android.

Sebelum memulai

Pastikan Anda memiliki prasyarat berikut:

  • Instance Google SecOps
  • Project Google Cloud dengan API berikut diaktifkan:
    • Cloud Storage API
    • Cloud Run Functions API
    • Cloud Scheduler API
    • Cloud Pub/Sub API
  • Izin untuk membuat dan mengelola bucket Google Cloud Storage, fungsi Cloud Run, topik Pub/Sub, dan tugas Cloud Scheduler
  • Izin untuk mengelola kebijakan IAM pada bucket Google Cloud Storage
  • Langganan ESET Threat Intelligence yang aktif
  • Akses ke portal ESET Threat Intelligence di https://eti.eset.com

Membuat bucket Google Cloud Storage

  1. Buka Konsol Google Cloud.
  2. Pilih project Anda atau buat project baru.
  3. Di menu navigasi, buka Cloud Storage > Buckets.
  4. Klik Create bucket.
  5. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Beri nama bucket Anda Masukkan nama yang unik secara global (misalnya, eset-ti-logs)
    Location type Pilih berdasarkan kebutuhan Anda (Region, Dual-region, Multi-region)
    Location Pilih lokasi (misalnya, us-central1)
    Kelas penyimpanan Standar (direkomendasikan untuk log yang sering diakses)
    Access control Seragam (direkomendasikan)
    Alat perlindungan Opsional: Aktifkan pembuatan versi objek atau kebijakan retensi
  6. Klik Create.

Mengumpulkan kredensial TAXII ESET Threat Intelligence

Agar fungsi Cloud Run dapat mengambil data intelijen ancaman, Anda harus mengaktifkan feed TAXII dan membuat kredensial TAXII dari portal ETI.

Mengaktifkan feed TAXII

  1. Login ke portal ESET Threat Intelligence di https://eti.eset.com.
  2. Buka Feed Data di menu utama.
  3. Klik ikon tiga titik di samping feed data yang ingin Anda aktifkan.
  4. Pilih Aktifkan feed.
  5. Ulangi langkah 3-4 untuk setiap feed yang ingin Anda masukkan ke Google SecOps.

Membuat kredensial TAXII

  1. Di portal ESET Threat Intelligence, buka Admin Settings > Access Credentials.
  2. Klik Generate TAXII Credentials.
  3. Pada dialog yang muncul, salin dan simpan nilai berikut:

    • Nama pengguna: Nama pengguna TAXII Anda
    • Sandi: Sandi TAXII Anda

Mencatat detail feed TAXII

Setelah mengaktifkan feed dan membuat kredensial, catat informasi berikut untuk setiap feed yang ingin Anda masukkan:

  1. Di portal ESET Threat Intelligence, buka Data Feeds.
  2. Klik ikon tiga titik di samping feed yang diaktifkan.
  3. Pilih Tampilkan detail Feed Data.
  4. Di panel samping, perhatikan nilai berikut:

    • Nama feed TAXII: ID feed (misalnya, botnet stix 2.1)
    • ID TAXII 2: ID koleksi (misalnya, 0abb06690b0b47e49cd7794396b76b20)
    • URL feed TAXII 2: URL koleksi lengkap

Feed TAXII yang tersedia

  • ESET Threat Intelligence menyediakan feed TAXII 2.1 berikut:

    Nama Feed Nama Feed TAXII ID Koleksi
    Feed pencuri info Android androidinfostealer stix 2.1 9ee501cde0c44d6db4ae995fead1a7c8
    Feed ancaman Android androidthreats stix 2.1 daf3de8fab144552a1cb5af054ed07ee
    IoC APT apt stix 2.1 97e3eb74ae5f46dd9e22f677a6938ee7
    Feed botnet botnet stix 2.1 0abb06690b0b47e49cd7794396b76b20
    Botnet - C&C botnet.cc stix 2.1 d1923a526e8f400dbb301259240ee3d5
    Botnet - Target botnet.target stix 2.1 61b6e4f9153e411ca7a9982a2c6ae788
    Feed penipuan kripto cryptoscam stix 2.1 2c183ce9551a43338c6cc2ed7c2a704d
    Feed domain domain stix 2.1 a34aa0a4f9de419582a883863503f9c4
    Feed IoC eCrime ecrime stix 2.1 08059376eac84ec4a076cfd682493f91
    Feed IP ip stix 2.1 baaed2a92335418aa753fe944e13c23a
    Lampiran email berbahaya emailattachments stix 2.1 c0d56cf7f81d482eb97fd46beaa4bae0
    Feed file berbahaya file stix 2.1 ee6a153ed77e4ec3ab21e76cc2074b9f
    Feed URL phishing phishingurl stix 2.1 d0a6c0f962dd4dd2b3eeb96b18612584
    Feed file adware PUA puaadware stix 2.1 d1bfc81202fc4c6599326771ec2da41d
    Feed file aplikasi penggunaan ganda PUA puadualapps stix 2.1 970a7d0039ac4668addf058cd9feb953
    Feed ransomware ransomware stix 2.1 8d3490d688ce4a989aee9af5c680d8bf
    Feed URL scam scamurl stix 2.1 2130adc3c67c43f9a3664b187931375e
    Feed smishing smishing stix 2.1 330ad7d0c736476babe5e49077b96c95
    Feed scam SMS smsscam stix 2.1 6e20217a2e1246b8ab11be29f759f716
    Feed URL url stix 2.1 1d3208c143be49da8130f5a66fd3a0fa

Buat akun layanan untuk Cloud Run Function

  1. Di Konsol Google Cloud, buka IAM & Admin > Service Accounts.
  2. Klik Create Service Account.
  3. Berikan detail konfigurasi berikut:

    • Nama akun layanan: Masukkan eset-ti-collector
    • Deskripsi akun layanan: Masukkan Service account for ESET Threat Intelligence Cloud Run function to write STIX objects to GCS
  4. Klik Create and Continue.

  5. Di bagian Grant this service account access to project, tambahkan peran berikut:

    1. Klik Select a role, lalu cari dan pilih Storage Object Admin.
    2. Klik Add Another Role, lalu telusuri dan pilih Cloud Run Invoker.
  6. Klik Lanjutkan.

  7. Klik Done.

Memberikan izin IAM pada bucket Google Cloud Storage

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket Anda (misalnya, eset-ti-logs).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:

    • Tambahkan prinsipal: Masukkan email akun layanan (misalnya, eset-ti-collector@PROJECT_ID.iam.gserviceaccount.com)
    • Tetapkan peran: Pilih Storage Object Admin
  6. Klik Simpan.

Membuat topik Pub/Sub

Topik Pub/Sub memicu fungsi Cloud Run saat pesan dipublikasikan oleh Cloud Scheduler.

  1. Di konsol Google Cloud, buka Pub/Sub > Topics.
  2. Klik Buat Topik.
  3. Berikan detail konfigurasi berikut:
    • ID Topik: Masukkan eset-ti-trigger
    • Tambahkan langganan default: Biarkan dipilih
  4. Klik Create.

Membuat fungsi Cloud Run

  1. Di konsol Google Cloud, buka Cloud Run functions.
  2. Klik Create function.
  3. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Lingkungan Generasi ke-2
    Nama fungsi eset-ti-collector
    Region Pilih region yang sama dengan bucket GCS Anda
    Jenis pemicu Cloud Pub/Sub
    Topik Pub/Sub eset-ti-trigger
    Memori yang dialokasikan 512 MiB
    Waktu tunggu 540 detik
    Akun layanan runtime eset-ti-collector
  4. Klik Berikutnya.

  5. Tetapkan Runtime ke Python 3.12.

  6. Tetapkan Entry point ke main.

  7. Di file requirements.txt, tambahkan dependensi berikut:

    functions-framework==3.*
    google-cloud-storage==2.*
    urllib3==2.*
    
  8. Di file main.py, tempelkan kode berikut:

    import functions_framework
    import json
    import os
    import logging
    import time
    import urllib3
    from datetime import datetime, timedelta, timezone
    from google.cloud import storage
    
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)
    
    HTTP = urllib3.PoolManager(retries=False)
    storage_client = storage.Client()
    
    API_ROOT = "https://taxii.eset.com/taxii2/643f4eb5-f8b7-46a3-a606-6d61d5ce223a"
    TAXII_CONTENT_TYPE = "application/taxii+json;version=2.1"
    
    def _load_state(bucket_name: str, state_key: str, lookback_hours: int) -> str:
        """Return ISO8601 checkpoint (UTC)."""
        try:
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(state_key)
            if blob.exists():
                state_data = blob.download_as_text()
                state = json.loads(state_data)
                ts = state.get("last_poll_time")
                if ts:
                    logger.info(f"Loaded state: {ts}")
                    return ts
        except Exception as e:
            logger.warning(f"State read error: {e}")
        default_ts = (
            datetime.now(timezone.utc) - timedelta(hours=lookback_hours)
        ).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        logger.info(f"No previous state found, using lookback: {default_ts}")
        return default_ts
    
    def _save_state(bucket_name: str, state_key: str, ts: str) -> None:
        """Persist the checkpoint to GCS."""
        bucket = storage_client.bucket(bucket_name)
        blob = bucket.blob(state_key)
        blob.upload_from_string(
            json.dumps({"last_poll_time": ts}),
            content_type="application/json",
        )
        logger.info(f"Saved state: {ts}")
    
    def _fetch_objects(
        username: str,
        password: str,
        collection_id: str,
        added_after: str,
        max_records: int,
    ) -> list:
        """Query TAXII 2.1 collection objects with pagination."""
        url = f"{API_ROOT}/collections/{collection_id}/objects/"
        headers = urllib3.make_headers(basic_auth=f"{username}:{password}")
        headers["Accept"] = TAXII_CONTENT_TYPE
        headers["User-Agent"] = "Chronicle-ESET-TI-GCS/1.0"
    
        all_objects = []
        params = {"added_after": added_after}
    
        while True:
            qs = "&".join(f"{k}={v}" for k, v in params.items())
            request_url = f"{url}?{qs}" if qs else url
    
            for attempt in range(3):
                try:
                    resp = HTTP.request("GET", request_url, headers=headers)
                    break
                except Exception as e:
                    wait = 2 ** (attempt + 1)
                    logger.warning(f"Request error: {e}, retrying in {wait}s")
                    time.sleep(wait)
            else:
                raise RuntimeError("Exceeded retry budget for TAXII API")
    
            if resp.status == 401:
                raise RuntimeError("Authentication failed: check TAXII credentials")
            if resp.status == 404:
                raise RuntimeError(
                    f"Collection not found: {collection_id}"
                )
            if resp.status not in (200, 206):
                raise RuntimeError(
                    f"TAXII API error {resp.status}: {resp.data[:500]}"
                )
    
            body = json.loads(resp.data.decode("utf-8"))
            objects = body.get("objects", [])
            all_objects.extend(objects)
            logger.info(
                f"Fetched {len(objects)} objects (total: {len(all_objects)})"
            )
    
            if len(all_objects) >= max_records:
                logger.info(f"Reached max_records limit: {max_records}")
                all_objects = all_objects[:max_records]
                break
    
            more = body.get("more", False)
            next_param = body.get("next")
            if more and next_param:
                params = {"added_after": added_after, "next": next_param}
            else:
                break
    
        return all_objects
    
    @functions_framework.cloud_event
    def main(cloud_event):
        """Cloud Run function entry point triggered by Pub/Sub."""
        bucket_name = os.environ["GCS_BUCKET"]
        prefix = os.environ.get("GCS_PREFIX", "eset-ti")
        state_key = os.environ.get("STATE_KEY", "eset-ti/state.json")
        username = os.environ["TAXII_USERNAME"]
        password = os.environ["TAXII_PASSWORD"]
        collection_id = os.environ["COLLECTION_ID"]
        max_records = int(os.environ.get("MAX_RECORDS", "10000"))
        lookback_hours = int(os.environ.get("LOOKBACK_HOURS", "48"))
    
        try:
            last_poll = _load_state(bucket_name, state_key, lookback_hours)
            objects = _fetch_objects(
                username, password, collection_id, last_poll, max_records
            )
    
            if not objects:
                logger.info("No new STIX objects found")
                return "No new objects", 200
    
            now_str = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
            blob_path = (
                f"{prefix}/eset_ti_{collection_id}_{now_str}.json"
            )
            ndjson_body = "\n".join(
                json.dumps(obj, separators=(",", ":")) for obj in objects
            )
    
            bucket = storage_client.bucket(bucket_name)
            blob = bucket.blob(blob_path)
            blob.upload_from_string(
                ndjson_body, content_type="application/x-ndjson"
            )
    
            new_poll_time = datetime.now(timezone.utc).strftime(
                "%Y-%m-%dT%H:%M:%S.000Z"
            )
            _save_state(bucket_name, state_key, new_poll_time)
    
            msg = (
                f"Wrote {len(objects)} STIX objects to "
                f"gs://{bucket_name}/{blob_path}"
            )
            logger.info(msg)
            return msg, 200
    
        except Exception as e:
            logger.error(f"Error collecting ESET TI: {e}")
            raise
    
  9. Klik Deploy.

  10. Tunggu hingga fungsi di-deploy. Status akan berubah menjadi tanda centang hijau saat deployment selesai.

Mengonfigurasi variabel lingkungan

  1. Setelah fungsi di-deploy, buka Cloud Run functions > eset-ti-collector.
  2. Klik Edit dan deploy revisi baru.
  3. Klik tab Variables and Secrets (atau luaskan Runtime, build, connections and security settings untuk generasi ke-1).
  4. Tambahkan variabel lingkungan berikut:

    Kunci Nilai contoh
    GCS_BUCKET eset-ti-logs
    GCS_PREFIX eset-ti
    STATE_KEY eset-ti/state.json
    TAXII_USERNAME Nama pengguna TAXII Anda dari portal ETI
    TAXII_PASSWORD Sandi TAXII Anda dari portal ETI
    COLLECTION_ID 0abb06690b0b47e49cd7794396b76b20
    MAX_RECORDS 10000
    LOOKBACK_HOURS 48
  5. Klik Deploy.

Buat tugas Cloud Scheduler

Cloud Scheduler memublikasikan pesan ke topik Pub/Sub sesuai jadwal, yang memicu fungsi Cloud Run untuk melakukan polling ESET Threat Intelligence guna mendapatkan objek STIX baru.

  1. Di konsol Google Cloud, buka Cloud Scheduler.
  2. Klik Create Job.
  3. Berikan detail konfigurasi berikut:

    Setelan Nilai
    Nama eset-ti-poll
    Region Pilih region yang sama dengan fungsi Anda
    Frekuensi 0 */1 * * * (setiap jam)
    Zona Waktu Pilih zona waktu Anda (misalnya, UTC)
  4. Klik Lanjutkan.

  5. Di bagian Konfigurasi eksekusi:

    • Jenis target: Pilih Pub/Sub
    • Topik: Pilih eset-ti-trigger
    • Isi pesan: Masukkan {"poll": true}
  6. Klik Create.

Memverifikasi fungsi Cloud Run

  1. Di Cloud Scheduler, temukan tugas eset-ti-poll.
  2. Klik Jalankan Paksa untuk memicu eksekusi langsung.
  3. Buka Cloud Run functions > eset-ti-collector > Logs.
  4. Pastikan fungsi berhasil dieksekusi dengan memeriksa entri log seperti:

    Fetched 250 objects (total: 250)
    Wrote 250 STIX objects to gs://eset-ti-logs/eset-ti/eset_ti_0abb06690b0b47e49cd7794396b76b20_20250115_103000.json
    
  5. Buka Cloud Storage > Buckets > eset-ti-logs.

  6. Buka awalan eset-ti/.

  7. Pastikan file NDJSON dibuat dengan objek STIX.

Mengambil akun layanan Google SecOps dan mengonfigurasi feed

Google SecOps menggunakan akun layanan unik untuk membaca data dari bucket GCS Anda. Anda harus memberi akun layanan ini akses ke bucket Anda.

Dapatkan email akun layanan

  1. Buka Setelan SIEM > Feed.
  2. Klik Tambahkan Feed Baru.
  3. Klik Konfigurasi satu feed.
  4. Di kolom Nama feed, masukkan nama untuk feed (misalnya, ESET Threat Intelligence - Botnet).
  5. Pilih Google Cloud Storage V2 sebagai Source type.
  6. Pilih ESET Threat Intelligence sebagai Jenis log.
  7. Klik Get Service Account. Email akun layanan yang unik akan ditampilkan, misalnya:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. Salin alamat email ini untuk digunakan di langkah berikutnya.

  9. Klik Berikutnya.

  10. Tentukan nilai untuk parameter input berikut:

    • URL bucket penyimpanan: Masukkan URI bucket GCS dengan jalur awalan:

      gs://eset-ti-logs/eset-ti/
      
    • Opsi penghapusan sumber: Pilih opsi penghapusan sesuai preferensi Anda:

      • Jangan pernah: Tidak pernah menghapus file apa pun setelah transfer (direkomendasikan untuk pengujian).
      • Hapus file yang ditransfer: Menghapus file setelah transfer berhasil.
      • Hapus file yang ditransfer dan direktori kosong: Menghapus file dan direktori kosong setelah transfer berhasil.

    • Usia File Maksimum: Menyertakan file yang diubah dalam beberapa hari terakhir (defaultnya adalah 180 hari)

    • Namespace aset: Namespace aset

    • Label penyerapan: Label yang akan diterapkan ke peristiwa dari feed ini (misalnya, ESET_IOC)

  11. Klik Berikutnya.

  12. Tinjau konfigurasi feed baru Anda di layar Selesaikan, lalu klik Kirim.

Memberikan izin IAM ke akun layanan Google SecOps

Akun layanan Google SecOps memerlukan peran Storage Object Viewer di bucket Google Cloud Storage Anda.

  1. Buka Cloud Storage > Buckets.
  2. Klik nama bucket Anda (misalnya, eset-ti-logs).
  3. Buka tab Izin.
  4. Klik Grant access.
  5. Berikan detail konfigurasi berikut:
    • Add principals: Tempel email akun layanan Google SecOps
    • Tetapkan peran: Pilih Storage Object Viewer
  6. Klik Simpan.

Tabel pemetaan UDM

Kolom Log Pemetaan UDM Logika
kapan metadata.event_timestamp Stempel waktu saat peristiwa terjadi
metadata.event_type Jenis peristiwa (misalnya, USER_LOGIN, NETWORK_CONNECTION)
messageid metadata.id ID unik untuk peristiwa
protokol network.ip_protocol Protokol IP (misalnya, TCP, UDP)
deviceName principal.hostname Nama host sumber
srcAddr principal.ip Alamat IP sumber koneksi
srcPort principal.port Nomor port sumber
tindakan security_result.action Tindakan yang dilakukan oleh produk keamanan (misalnya, IZINKAN, BLOKIR)
dstAddr target.ip Alamat IP tujuan
dstPort target.port Nomor port tujuan
metadata.product_name Nama produk
metadata.vendor_name Nama vendor/perusahaan

Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.