Menerapkan logika windowing YARA-L 2.0
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 (
byatauover) di bagianmatchuntuk menggunakan kata kunci ini. - Pembatasan bagian: Gunakan kata kunci ini di
condition,order, atauoutcome. Elemen tersebut tidak valid di bagianevents. - 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
}
Telusuri
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,
$useridtertentu), 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>
$variableadalah variabel placeholder yang Anda cocokkan.durationadalah 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$useridberbeda, 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:
- Identifikasi sasaran deteksi. Tentukan apakah Anda menelusuri frekuensi tinggi atau kurangnya aktivitas.
- Pilih kata kunci
window. Gunakanoveruntuk frekuensi danbyuntuk tidak ada. - Batas jendela referensi. Gunakan kata kunci
window_startdanwindow_enduntuk 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,
e1terjadi hingga dua menit setelahe2). - Waktu relatif: Temukan peristiwa yang terjadi dalam offset pemicu tertentu (misalnya,
Network Connectiondalam 30 detik setelahProcess 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 denganmatch: $user by 24hhanya dievaluasi setelah periode 24 jam selesai sepenuhnya.Latensi pemberitahuan: Aturan yang menggunakan
by(berjatuhan) hanya dipicu setelah blok waktu tetap berlalu. Aturanby 24htidak akan memberikan pemberitahuan di tengah jendela.Ketidakcocokan UI: Di Penelusuran dan Dasbor, kata kunci
window_startmerujuk langsung ke kolomTIME_BUCKET. Saat Anda memfilter atau mengelompokkan menurutwindow_start, header kolom ditampilkan sebagaiTIME_BUCKETdi 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.