Menerapkan logika windowing YARA-L 2.0

Didukung di:

Panduan ini membantu Engineer Keamanan memilih jenis jendela yang benar untuk kueri guna menghindari error compiler "variable not bounded". Beralih dari jendela geser ke jendela berjatuhan memungkinkan Anda membangun logika yang bergantung pada tidak adanya peristiwa, seperti detak jantung yang hilang atau sumber log yang gagal.

Sebelum memulai

Pastikan akun Anda memiliki salah satu peran berikut untuk membuat dan mengubah kueri YARA-L:

  • Detection Engine Admin (roles/chronicle.detectionEngineAdmin)
  • SecOps Editor (roles/chronicle.editor)

Jenis jendela yang didukung

YARA-L 2.0 menggunakan perilaku windowing yang berbeda untuk menentukan cara membagi waktu dan cara mengelompokkan peristiwa. Anda dapat mengelompokkan kolom dan placeholder peristiwa di bagian match berdasarkan perincian waktu yang ditentukan menggunakan periode yang didukung berikut:

Jenis jendela yang didukung Sintaksis Deskripsi Kasus penggunaan umum
Hop $key over <duration> Membuat interval waktu yang tetap dan tumpang-tindih. Sistem menentukan tumpang-tindih dan penyelarasan untuk menangkap peristiwa di dekat batas. Korelasi umum beberapa peristiwa, terlepas dari waktu mulai yang tepat.
Tumbling $key by <duration> Membagi data menjadi blok berukuran tetap, berkelanjutan, dan tidak tumpang-tindih. Dievaluasi secara independen dari kedatangan peristiwa. Mengukur aktivitas dalam slot tetap (misalnya, $user by 30m) atau mendeteksi tidak adanya peristiwa.
Menggeser $key over <duration> [before|after] $pivot Menyematkan jendela ke peristiwa "pivot" tertentu. Memerlukan keberadaan titik pusat untuk memicu lihat kembali atau lihat ke depan. Pengurutan ketat yang mengutamakan urutan peristiwa (misalnya, File Download after Login).

Memahami logika window_start dan window_end

Google Security Operations menyediakan dua kata kunci universal yang dicadangkan dan diselesaikan langsung ke stempel waktu GoogleSQL untuk digunakan dalam kueri. Kata kunci ini memungkinkan Anda mengakses batas bucket waktu:

  • window_start: Batas awal bucket waktu.
  • window_end: Batas penutupan bucket waktu.

Batasan penggunaan

  • Persyaratan kecocokan: Anda harus menentukan periode (by atau over) di bagian match untuk menggunakan kata kunci ini.
  • Pembatasan bagian: Gunakan kata kunci ini di condition, order, atau outcome. Elemen tersebut tidak valid di bagian events.
  • Namespace: Jangan gunakan ini sebagai nama variabel kustom (misalnya, $window_start).

Menentukan jenis dan sintaksis jendela Anda

Gunakan tabel ini sebagai referensi cepat saat menentukan jenis dan sintaksis jendela yang akan digunakan untuk aturan deteksi Anda.

Skenario Periode yang direkomendasikan Kata kunci yang direkomendasikan Keunggulan utama
Deteksi frekuensi tinggi (misalnya, serangan brute force) Periode Geser (over) window_start, window_end Dipicu segera setelah nilai minimum tercapai dalam jangka waktu bergulir.
Tidak ada/tidak ada (misalnya, tidak ada detak jantung) Periode Tumbling (by) window_start, window_end Mengevaluasi blok waktu tetap meskipun tidak ada peristiwa yang terjadi, sehingga mencegah error Variabel Tidak Terikat.
Pelaporan kronologis Meluncur atau berguling order: window_start asc Menstandarkan output pemberitahuan untuk memudahkan analisis linimasa di UI Chronicle.
Pemfilteran dengan batas waktu Meluncur atau berguling condition: window_start > "2026-01-01 00:00:00Z" Membatasi evaluasi aturan ke tanggal tertentu menggunakan pemaksaan stempel waktu GoogleSQL.

Membandingkan jenis stempel waktu dan zona waktu

YARA-L mendukung perbandingan window_start dan window_end secara langsung dengan string dalam format stempel waktu GoogleSQL. Dengan demikian, Anda dapat melakukan pemfilteran yang akurat tanpa melakukan casting jenis secara manual.

Catatan: Selalu tentukan UTC menggunakan akhiran Z (misalnya, "2026-03-17T17:35:00Z") agar selaras dengan stempel waktu peristiwa UDM.

Gunakan filter stempel waktu untuk performa. Jika Anda hanya perlu mengonfirmasi bahwa satu peristiwa terjadi setelah peristiwa lainnya, perbandingan stempel waktu di bagian condition sering kali lebih efisien: $e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds.

Pelajari lebih lanjut sintaksis bagian match dan sintaksis bagian condition.

Contoh: window_end dan window_start

  • window_end < "2026-01-01T12:30:00Z" (tanggal, waktu, dan akhiran UTC)
  • window_start != "2026-01-01 15:00:00+00" (dengan selisih UTC)

Jika perbandingan Anda gagal, pastikan string Anda mengikuti format stempel waktu kanonis GoogleSQL.

Periode hopping

Periode hopping membuat interval waktu yang tumpang-tindih sehingga peristiwa yang terjadi di dekat batas periode tidak terlewat.

  • Kasus penggunaan: Paling cocok untuk deteksi saat Anda perlu menangkap skenario tertentu, terlepas dari kapan tepatnya interval jendela dimulai atau berakhir.
  • Dukungan: Didukung untuk agregasi di Penelusuran dan Dasbor.

Kueri YARA-L dengan bagian match menggunakan periode hopping untuk menghubungkan beberapa peristiwa dari waktu ke waktu. Sistem membagi rentang waktu eksekusi kueri menjadi serangkaian periode hopping tetap yang tumpang-tindih. Meskipun Anda menentukan durasi periode ini di bagian match, sistem akan menentukan interval tumpang-tindih dan penyesuaian periode. Kemudian, peristiwa berkorelasi dalam setiap periode yang telah ditentukan ini.

Pelajari lebih lanjut sintaksis bagian match.

Jendela hop memiliki implikasi khusus untuk deteksi aturan gabungan. Untuk mengetahui informasi selengkapnya, lihat Aturan komposit: interval waktu dan periode hopping.

Contoh: Periode hopping yang tumpang-tindih untuk korelasi berkelanjutan

Contoh berikut menunjukkan kueri yang dijalankan selama rentang waktu [1:00, 2:00], dengan bagian match $user over 30m. Kumpulan kemungkinan periode hopping yang tumpang-tindih yang dihasilkan sistem adalah [1:00, 1:30], [1:03, 1:33], dan [1:06, 1:36].

Aturan

rule hop_window_brute_force_example {
meta:
  description = "Detects multiple failed logins within a shifting 30-minute window."
  severity = "Medium"

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.extensions.auth.auth_status = "FAILURE"
  $login.principal.user.userid = $user

match:
  // This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
  $user over 30m

condition:
  // This will trigger if 10 or more failures fall into any single 30m hop
  #login >= 10
}
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user

match:
  // This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
  $user over 30m
  ```

Dasbor

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user

match:
  // This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
  $user over 30m

Contoh: Korelasi multiperistiwa menggunakan periode hopping

Contoh berikut merekam peristiwa yang terjadi dalam jangka waktu umum yang sama:

Aturan

rule hop_window_example {
meta:
  description = "Detect a user with a failed login followed by a success within 30m"

events:
  // Event 1: Capture failed login attempts
  $fail.metadata.event_type = "USER_LOGIN"
  $fail.security_result.action = "FAIL"
  $fail.principal.user.userid = $user

  // Event 2: Capture successful login attempts
  $success.metadata.event_type = "USER_LOGIN"
  $success.security_result.action = "ALLOW"
  $success.principal.user.userid = $user

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

condition:
  // Ensure both a failed ($fail) and a successful ($success) login event occurred for the same user within the 30m window.
  $fail and $success
}

Telusuri

// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder

// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

Dasbor

// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder

// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

Contoh: Perbandingan jendela lompatan

Untuk mengidentifikasi upaya brute force, jendela 10m mengelompokkan semua kegagalan USER_LOGIN. Kemudian, kondisi akan mengevaluasi apakah jumlah (#e) dalam bucket 10 menit tertentu tersebut melebihi nilai minimum Anda.

Aturan

rule failed_logins
{
meta:
  author = "Security Team"
  description = "Detects multiple failed user logins within 10-minute windows."
  severity = "HIGH"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.security_result.action = "FAIL"
  $user = $e.target.user.userid

match:
  $user over 10m

condition:
  #e >= 5
}

Telusuri

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid

match:
  $user over 10m

Dasbor

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid

match:
  $user over 10m

Periode tumbling

Catatan: Fitur ini hanya tersedia untuk pelanggan tertentu di wilayah tertentu.

Periode tumbling menyegmentasikan data ke dalam interval waktu berukuran tetap, tidak tumpang-tindih, dan berkelanjutan. Stempel waktu setiap peristiwa termasuk dalam tepat satu jendela. Tidak ada tumpang-tindih antara periode tumbling. Hal ini berbeda dengan periode hop atau periode geser, yang dapat memiliki interval waktu yang tumpang-tindih.

Untuk menerapkan jendela bergulir, gunakan operator by di bagian match. Periode tumbling membagi waktu menjadi blok berkelanjutan yang berurutan, misalnya:

  • by 1h: Membuat jendela untuk setiap jam (misalnya, [00:00:00-00:59:59], [01:00:00-01:59:59]).
  • by 10m: Membuat periode untuk setiap interval 10 menit (misalnya, [00:00:00-00:09:59], [00:10:00-00:19:59]).

Kasus penggunaan umum

Gunakan jendela tumbling jika Anda perlu:

  • Menganalisis peristiwa dalam blok waktu yang berbeda dan tidak tumpang-tindih.
  • Menghasilkan hanya satu deteksi untuk entitas tertentu (sebagaimana ditentukan oleh variabel kecocokan) dalam setiap interval waktu tetap, terlepas dari berapa kali peristiwa terjadi.
  • Menghitung entitas unik selama periode tetap.

Perilaku penghapusan duplikat

Karakteristik utama periode tumbling adalah cara mesin menangani deteksi dalam setiap periode untuk kumpulan variabel kecocokan yang sama:

  • Satu deteksi per jendela: Untuk sekumpulan nilai tertentu untuk variabel kecocokan (misalnya, $userid tertentu), mesin menghasilkan paling banyak satu deteksi untuk satu jendela bergulir.
  • Kedatangan pertama menang: Peristiwa pertama yang diproses yang memenuhi kondisi aturan untuk kumpulan variabel kecocokan tersebut dalam jendela tertentu akan memicu deteksi.
  • Penghapusan duplikat: Peristiwa berikutnya yang cocok dengan kriteria dalam instance periode yang sama tidak akan menghasilkan deteksi tambahan.

Sintaksis

Sintaksis di bagian match adalah: match: $variable by <duration>

  • $variable adalah variabel placeholder yang Anda cocokkan.
  • duration adalah angka yang diikuti dengan satuan waktu: m (menit), h (jam), d (hari).
  • Tentukan minimum satu menit dan maksimum 72 jam atau tiga hari.

Contoh: Pengelompokan interval tetap

Aturan berikut mengelompokkan login berdasarkan $userid dalam jangka waktu 1 jam yang tidak tumpang-tindih.

Aturan

rule TumblingWindowExample {
meta:
  description = "Example using a 1-hour tumbling window"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $userid

match:
  $userid by 1h

condition:
  $e
}

Telusuri

metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid

match:
  $userid by 1h

Dasbor

metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid

match:
  $userid by 1h

Contoh: Perilaku deteksi (pengguna = "Alex")

  • Peristiwa 1: Alex login pada pukul 00.30. Hal ini termasuk dalam jendela [00:00:00-00:59:59]. Mesin ini menghasilkan deteksi untuk Alex selama periode ini.
  • Peristiwa 2: Pengguna lain, "Taylor", login pada pukul 00.45. Ini juga termasuk dalam [00:00:00-00:59:59], tetapi karena $userid berbeda, mesin menghasilkan deteksi terpisah untuk Taylor.
  • Peristiwa 3: Alex login lagi pada pukul 00.40. Ini masih dalam periode [00:00:00-00:59:59]. Karena deteksi untuk Alex sudah ada, peristiwa ini diduplikasi. Tidak ada deteksi baru yang dibuat.
  • Peristiwa 4: Alex login pada pukul 01.20. Hal ini termasuk dalam jendela berikutnya, [01:00:00-01:59:59]. Mesin ini menghasilkan deteksi baru untuk Alex.

Meskipun Peristiwa 1 dan Peristiwa 4 untuk Alex terjadi dalam waktu kurang dari satu jam, keduanya termasuk dalam deteksi terpisah karena Peristiwa 4 melewati batas periode tetap.

Mengonfigurasi jendela bergulir untuk deteksi tidak ada aktivitas

Untuk memberikan peringatan pada jumlah nol dan menghindari kegagalan kompilator, selesaikan langkah-langkah berikut:

  1. Identifikasi sasaran deteksi. Tentukan apakah Anda menelusuri frekuensi tinggi atau kurangnya aktivitas.
  2. Pilih kata kunci window. Gunakan over untuk frekuensi dan by untuk tidak ada.
  3. Batas jendela referensi. Gunakan kata kunci window_start dan window_end untuk mereferensikan batas tertentu dari bucket waktu.

Konteks: Gunakan outcome: $ext_window_end = window_end untuk menyertakan waktu berakhir yang tepat dari detak jantung yang terlewat dalam metadata pemberitahuan.

Contoh: Mendeteksi detak jantung yang hilang dengan metadata

Jendela bergulir memungkinkan Anda memberikan pemberitahuan tentang jumlah nol, yang membantu Anda menghindari kegagalan compiler saat mencari kurangnya aktivitas.

Aturan

rule missing_heartbeat_detection {
meta:
  description = "Alert when a system fails to check in within a 24h block"

events:
  $e.metadata.event_type = "STATUS_UPDATE"
  $host = $e.principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count($e.metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

condition:
  $event_count = 0 and window_start > "2026-01-01T12:30:00Z"
}

Telusuri

metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count(metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

Dasbor

metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count(metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

Periode geser

Jendela geser ditambatkan ke peristiwa titik pusat tertentu dan melihat ke depan (after) atau ke belakang (before).

Kasus penggunaan umum

Gunakan jendela geser jika urutan peristiwa sangat penting:

  • Pengurutan ketat: Mendeteksi rangkaian serangan (misalnya, e1 terjadi hingga dua menit setelah e2).
  • Waktu relatif: Temukan peristiwa yang terjadi dalam offset pemicu tertentu (misalnya, Network Connection dalam 30 detik setelah Process Start).
  • Deteksi tidak adanya aktivitas: Mengidentifikasi kapan peristiwa "pembersihan" atau "detak jantung" yang diperlukan gagal terjadi setelah peristiwa mulai.

Sintaksis

match: <grouping_keys> over <duration> [before|after] <$pivot_event>

Komponen Deskripsi Contoh
Kunci pengelompokan Kolom umum yang digunakan untuk menautkan peristiwa. $host, $user
Durasi Selisih waktu dari peristiwa poros. 5m, 1h, 30s
Arah Apakah jendela diperluas ke depan atau ke belakang. after, before
Peristiwa pivot Variabel peristiwa yang menyematkan jendela. $proc, $alert

Berikut adalah contoh jendela geser yang valid:

  • $var1, $var2 over 5m after $e1
  • $user over 1h before $e2
  • $host, $ip over 1h before $e2

Persyaratan dan batasan

  • Performa: Jendela geser memerlukan lebih banyak daya pemrosesan daripada periode hopping. Gunakan hanya jika urutan peristiwa sangat diperlukan (misalnya, jika satu peristiwa harus terjadi dalam waktu lima menit setelah peristiwa lain).
  • Kueri peristiwa tunggal: Jangan gunakan jendela geser untuk logika peristiwa tunggal. Sebagai gantinya, gunakan beberapa variabel peristiwa di bagian condition.

Contoh: Korelasi yang berorientasi ke depan (after)

Aturan

rule sliding_window_after_example {
meta:
  description = "Detect a network connection occurring within 1 minute after a suspicious process launch."
  severity = "High"

events:
  $proc.metadata.event_type = "PROCESS_LAUNCH"
  $proc.principal.hostname = $host

  $net.metadata.event_type = "NETWORK_HTTP"
  $net.principal.hostname = $host

match:
  // $proc is the pivot; the 1-minute window starts at the $proc timestamp
  $host over 1m after $proc

condition:
  $proc and $net
}

Telusuri

after tidak didukung untuk Penelusuran.

Dasbor

after tidak didukung untuk Dasbor.

Contoh: Korelasi melihat ke belakang (before)

Gunakan jendela geser "before" untuk menyelidiki aktivitas yang menyebabkan peringatan tertentu. Hal ini sering digunakan dalam analisis penyebab utama untuk mengidentifikasi apa yang terjadi tepat sebelum deteksi penting.

Aturan

rule sliding_window_before_example {
meta:
  description = "Identify file modifications occurring in the 5 minutes before a ransomware alert."
  severity = "Critical"

events:
  $file.metadata.event_type = "FILE_MODIFICATION"
  $file.principal.hostname = $host

  $alert.metadata.event_type = "ANTIVIRUS_DETECTION"
  $alert.metadata.product_name = "Premium_AV"
  $alert.principal.hostname = $host

match:
  // $alert is the pivot; the 5-minute window ends at the $alert timestamp
  $host over 5m before $alert

condition:
  $file and $alert
}

Telusuri

before tidak didukung untuk Penelusuran.

Dasbor

before tidak didukung untuk Dasbor.

Pemecahan masalah

Gunakan bagian ini untuk memahami latensi, batas, dan perbaikan untuk masalah windowing umum di YARA-L.

Latensi dan batas

  • Aturan yang menggunakan jendela bergeser (by) hanya dipicu di akhir blok waktu tetap. Misalnya, aturan dengan match: $user by 24h hanya dievaluasi setelah periode 24 jam selesai sepenuhnya.

  • Latensi pemberitahuan: Aturan yang menggunakan by (berjatuhan) hanya dipicu setelah blok waktu tetap berlalu. Aturan by 24h tidak akan memberikan pemberitahuan di tengah jendela.

  • Ketidakcocokan UI: Di Penelusuran dan Dasbor, kata kunci window_start merujuk langsung ke kolom TIME_BUCKET. Saat Anda memfilter atau mengelompokkan menurut window_start, header kolom ditampilkan sebagai TIME_BUCKET di UI.Ini adalah batasan tampilan UI yang diketahui; logika Anda tetap valid.

Perbaikan error

Kode error Deskripsi Perbaiki
Variabel Tidak Terikat (Variable Not Bounded) Aturan ini menggunakan over (periode geser) dengan kondisi $count = 0. Ubah kata kunci windowing menjadi by (window berjatuhan). Periode geser memerlukan peristiwa untuk menyambungkan periode, sedangkan periode tumbling tidak.
Ketidakcocokan Header UI Pengguna melihat TIME_BUCKET di UI, bukan window_start. Tidak diperlukan perbaikan. Logika pemfilteran dan pengurutan tetap berfungsi dengan benar menggunakan kata kunci.
ID Tidak Diketahui: window_start Kata kunci digunakan, tetapi tidak ada jendela yang ditentukan dalam match. Tambahkan pernyataan windowing ke bagian match (misalnya, $hostname by 1h).
Penggunaan window_start yang tidak valid dalam peristiwa Kata kunci direferensikan di bagian events. Pindahkan logika ke bagian condition atau outcome. Batas jendela hanya dihitung setelah peristiwa dikelompokkan dalam fase pencocokan.

Langkah berikutnya

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