Masalah umum dan batasan YARA-L 2.0
Dokumen ini ditujukan untuk Engineer Deteksi yang ingin men-debug logika aturan dan mengoptimalkan eksekusi YARA-L 2.0. Bagian ini menjelaskan cara menangani perilaku mesin yang tidak standar, seperti pembatalan penyusunan kolom, perluasan produk Cartesian dalam agregasi, dan konsistensi akhir pengayaan. Dengan mengikuti metode ini, Anda dapat mencegah error logika yang menyebabkan nilai hasil yang meningkat atau deteksi yang terlewat.
YARA-L 2.0 menggunakan model eksekusi tertentu di mana kolom berulang diperluas menjadi baris peristiwa individual selama evaluasi. Karena transformasi ini terjadi di tingkat mesin, mereferensikan beberapa kolom berulang atau melakukan aritmatika pada jenis UDM yang tidak bertanda memerlukan solusi sintaksis tertentu untuk menghindari error compiler atau kumpulan hasil yang salah. Dokumen ini menguraikan batasan teknis tersebut dan pola logika yang diperlukan untuk menyelesaikannya.
Sebelum memulai
Pastikan akun Anda memiliki hak teknis berikut sebelum menguji atau mengubah aturan YARA-L 2.0:
Peran IAM yang diperlukan
roles/chronicle.viewer(Pelihat Operasi Keamanan): Untuk melihat aturan yang ada dan metadata deteksi.roles/chronicle.editor(Editor Operasi Keamanan): Untuk mengubah logika aturan dan menyimpan perubahan.
Izin yang diperlukan
chronicle.rules.runTest: Diperlukan untuk menjalankan fitur Jalankan Pengujian pada data historis.chronicle.detections.get: Untuk memeriksa output peristiwa yang tidak bertingkat di dasbor deteksi.
Terminologi utama
- UDM (Model Data Terpadu): Skema yang dinormalisasi yang digunakan untuk menyusun semua telemetri keamanan yang di-ingest di seluruh platform.
- Membuka Nesting: Perluasan tingkat mesin dari satu peristiwa UDM yang berisi kolom berulang (array) menjadi beberapa baris. Setiap baris mewakili elemen unik dari array, yang dapat menyebabkan perkalian baris selama evaluasi aturan.
- T₀ (run awal): Eksekusi pertama aturan pada telemetri yang masuk. Hal ini terjadi selama fase "streaming", sering kali sebelum proses pengayaan latar belakang (seperti penyesuaian GeoIP atau ASN) diselesaikan.
Agregasi hasil dengan pembukaan kolom berulang
Jika aturan mereferensikan kolom berulang dalam variabel peristiwa dengan beberapa elemen, setiap elemen akan dibagi menjadi baris peristiwa terpisah.
Misalnya, dua alamat IP di kolom berulang target.ip pada peristiwa $e dibagi menjadi dua instance $e, masing-masing dengan nilai target.ip yang berbeda.
rule outbound_ip_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$outbound_ip_count = count($e.target.ip) // yields 2.
condition:
$e
}
Kumpulan data peristiwa: Sebelum dan setelah memisahkan
Tabel di bagian ini menunjukkan cara satu peristiwa yang berisi array alamat IP diubah menjadi dua catatan yang berbeda.
Sebelum memisahkan
Tabel berikut menunjukkan rekaman peristiwa sebelum memisahkan kolom berulang:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[192.0.2.20, 192.0.2.28] |
Setelah memisahkan
Tabel berikut menunjukkan rekaman peristiwa setelah memisahkan kolom berulang:
| metadata.id | principal.application | target.ip |
|---|---|---|
aaaaaaaaa |
Google SecOps |
192.0.2.20 |
aaaaaaaaa |
Google SecOps |
192.0.2.28 |
Kolom berulang bertingkat (produk Cartesian)
Jika aturan mereferensikan kolom berulang yang berada di dalam kolom lain, seperti security_results.action, pelepasan akan terjadi di kedua tingkat (induk dan turunan) secara bersamaan. Hal ini menghasilkan produk Cartesian dari semua elemen.
Dalam contoh berikut, peristiwa $e dengan dua nilai berulang pada security_results dan dua nilai berulang pada security_results.actions di-unnest menjadi empat instance.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$security_action_count = count($e.security_results.actions) // yields 4.
condition:
$e
}
Rekaman peristiwa sebelum pembukaan bersarang
Catatan asli menyimpan tindakan dalam struktur array bertingkat.
| metadata.id | principal.application | security_results |
|---|---|---|
aaaaaaaaa |
Google SecOps |
[ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ] |
Rekaman peristiwa setelah pembukaan bersarang
Setelah perluasan, setiap tindakan unik akan menjadi barisnya sendiri, yang dapat menyebabkan jumlah yang tidak terduga dalam penggabungan yang tidak berbeda.
| metadata.id | principal.application | security_results.actions |
|---|---|---|
aaaaaaaaa |
Google SecOps |
IZINKAN |
aaaaaaaaa |
Google SecOps |
GAGAL |
aaaaaaaaa |
Google SecOps |
TANTANGAN |
aaaaaaaaa |
Google SecOps |
BLOKIR |
Dampak pada kolom yang tidak terkait
Perilaku pelepasan ini dalam evaluasi aturan dapat menghasilkan agregasi hasil yang tidak terduga jika aturan mereferensikan satu atau beberapa kolom berulang dengan kolom induk yang juga merupakan kolom berulang. Agregasi yang tidak berbeda
seperti sum(), array(), dan count() tidak dapat memperhitungkan nilai duplikat pada
kolom lain pada peristiwa yang sama yang dihasilkan oleh perilaku pelepasan.
Dalam contoh berikut, peristiwa $e memiliki satu nama host (google.com), tetapi hasilnya (hostnames) digabungkan di empat instance yang tidak bertingkat dari peristiwa $e yang sama, masing-masing dengan nilai principal.hostname duplikat. Hasil ini menghasilkan empat nama host (bukan satu)
karena pelepasan nilai berulang pada security_results.actions.
rule security_action_per_app {
meta:
events:
$e.principal.application = $app
match:
$app over 10m
outcome:
$hostnames = array($e.principal.hostname) // yields 4.
$security_action_count = count($e.security_results.action) // yields 4.
condition:
$e
}
Rekaman peristiwa sebelum memisahkan dengan kolom yang tidak terkait
Nama host adalah nilai tunggal, tetapi berada di samping hasil keamanan yang berulang.
| metadata.id | principal.application | principal.hostname | security_results |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
[ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ] |
Rekaman peristiwa setelah memisahkan dengan kolom yang tidak terkait
Nama host kini diduplikasi di empat baris, sehingga fungsi array() mengambilnya empat kali.
| metadata.id | principal.application | principal.hostname | security_results.action |
|---|---|---|---|
aaaaaaaaa |
Google SecOps |
google.com |
IZINKAN |
aaaaaaaaa |
Google SecOps |
google.com |
GAGAL |
aaaaaaaaa |
Google SecOps |
google.com |
TANTANGAN |
aaaaaaaaa |
Google SecOps |
google.com |
BLOKIR |
Solusi untuk perilaku pelepasan
Untuk memastikan nilai hasil Anda akurat saat pelepasan terjadi, gunakan versi berbeda dari agregasi yang dipilih. Fungsi berikut mengabaikan baris duplikat yang dibuat dengan membatalkan nest:
max()min()array_distinct()count_distinct()
Agregasi hasil dengan beberapa variabel peristiwa
Jika aturan berisi beberapa variabel peristiwa, ada item terpisah dalam agregasi untuk setiap kombinasi peristiwa yang disertakan dalam deteksi. Misalnya, jika contoh aturan berikut dijalankan terhadap peristiwa yang tercantum:
events:
$e1.field = $e2.field
$e2.somefield = $ph
match:
$ph over 1h
outcome:
$some_outcome = sum(if($e1.otherfield = "value", 1, 0))
condition:
$e1 and $e2
event1:
// UDM event 1
field="a"
somefield="d"
event2:
// UDM event 2
field="b"
somefield="d"
event3:
// UDM event 3
field="c"
somefield="d"
Jumlah dihitung untuk setiap kombinasi peristiwa, sehingga Anda dapat menggunakan kedua variabel peristiwa dalam perhitungan nilai hasil. Elemen berikut digunakan dalam penghitungan:
1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2
Hal ini menghasilkan kemungkinan jumlah maksimum 6, meskipun $e2 hanya dapat berkorespondensi dengan 3 peristiwa berbeda.
Hal ini memengaruhi jumlah, penghitungan, dan array. Untuk jumlah dan array, menggunakan count_distinct
atau array_distinct dapat menyelesaikan masalah, tetapi tidak ada solusi
untuk jumlah.
Tanda kurung di awal ekspresi
Memulai ekspresi dengan tanda kurung tidak didukung dan memicu error penguraian di editor aturan.
Sintaksis tidak valid
parsing: error with token: ")"
invalid operator in events predicate
Contoh berikut menghasilkan jenis error ini:
($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1
Variasi sintaksis yang valid
Variasi sintaksis berikut menampilkan hasil yang sama, tetapi dengan sintaksis yang valid:
$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600
Array indeks dalam hasil memerlukan agregasi
Pengindeksan array secara langsung dalam bagian outcome untuk kolom berulang tidak diizinkan. Memerlukan variabel placeholder sementara.
outcome:
$principal_user_dept = $suspicious.principal.user.department[0]
Solusi
Ambil indeks array tertentu ke dalam variabel placeholder dalam bagian events, lalu rujuk placeholder tersebut dalam hasil Anda.
events:
$principal_user_dept = $suspicious.principal.user.department[0]
outcome:
$principal_user_department = $principal_user_dept
Kondisi OR dengan tidak adanya
Jika Anda menerapkan kondisi OR antara dua variabel peristiwa terpisah dan jika aturan cocok dengan tidak adanya, aturan berhasil dikompilasi, tetapi dapat menghasilkan deteksi positif palsu.
Misalnya, sintaksis aturan berikut dapat mencocokkan peristiwa yang memiliki $event_a.field = "something" meskipun seharusnya tidak:
events:
not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
$event_a and #event_b >= 0
Solusi
Pisahkan pemeriksaan tidak ada ke dalam blok individual untuk setiap variabel guna mempertahankan integritas logika.
events:
not ($event_a.field = "something")
not ($event_b.field = "something")
condition:
$event_a and #event_b >= 0
Aritmatika dengan kolom peristiwa yang tidak bertanda
Jika Anda mencoba menggunakan konstanta bilangan bulat dalam operasi aritmatika dengan kolom UDM yang jenisnya adalah bilangan bulat tidak bertanda, Anda akan mendapatkan error. Contoh:
events:
$total_bytes = $e.network.received_bytes * 2
Konstanta bilangan bulat standar secara default adalah bilangan bulat bertanda, yang tidak kompatibel dengan kolom UDM yang ditentukan sebagai bilangan bulat tidak bertanda, seperti network.received_bytes.
Solusi
Anda dapat melewati error ini dengan memaksa konstanta bilangan bulat berperilaku sebagai float melalui operasi pembagian.
events:
$total_bytes = $e.network.received_bytes * (2/1)
Pengayaan GeoIP dan konsistensi tertunda
Sistem memprioritaskan kecepatan daripada akurasi langsung pada tahap pengayaan awal (Streaming dan Latensi Sensitif), yang dapat menyebabkan data hilang dan potensi positif palsu. Sistem terus memperkaya data di latar belakang, tetapi data mungkin tidak tersedia saat aturan dijalankan. Hal ini merupakan bagian dari proses konsistensi akhir yang normal.
Untuk mencegah positif palsu yang disebabkan oleh keterlambatan pengayaan, periksa secara eksplisit bahwa kolom tidak kosong sebelum mengevaluasi nilainya.
Misalnya, pertimbangkan peristiwa aturan ini:
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
Aturan ini mengandalkan fakta bahwa peristiwa harus memiliki $e.principal.ip_geo_artifact.network.asn = "16509" DAN $e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom" yang keduanya merupakan kolom yang diperkaya. Jika pengayaan tidak selesai tepat waktu, aturan akan menghasilkan positif palsu.
Untuk menghindarinya, pemeriksaan yang lebih baik untuk aturan ini adalah:
$e.principal.ip_geo_artifact.network.asn != "" AND
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"
Aturan ini menghilangkan kemungkinan peristiwa dipicu oleh IP dengan ASN 16509, tetapi berlokasi di luar Inggris Raya. Hal ini meningkatkan presisi keseluruhan aturan.
Pelajari cara memecahkan masalah keterlambatan pengayaan.
Pemecahan masalah
Bagian ini menguraikan ekspektasi performa dan memberikan perbaikan layanan mandiri untuk masalah umum yang menyebabkan perilaku deteksi langsung berbeda dari hasil pengujian.
Acara yang dijadwalkan pada masa mendatang
Aturan multi-peristiwa dirancang untuk memproses peristiwa dalam urutan kronologis relatif terhadap penyerapan. Jika Anda menentukan dan mengaktifkan aturan multi-peristiwa, aturan tersebut tidak akan membuat deteksi untuk peristiwa dengan stempel waktu di masa mendatang, misalnya saat event.timestamp memiliki tanggal dan waktu yang ditetapkan setelah ingest.timestamp.
Jeda pengayaan
Google SecOps memprioritaskan kecepatan penyerapan untuk menampilkan pemberitahuan awal secepat mungkin. Namun, proses pengayaan latar belakang, seperti menyelesaikan metadata GeoIP, ASN, atau UDM, mengikuti model konsistensi tertunda.
Operasi awal (T₀)
Mesin live dapat mengevaluasi aturan sebelum pengayaan latar belakang selesai. Bergantung pada apakah logika Anda mengandalkan kolom yang diperkaya untuk deteksi atau pengecualian, hal ini dapat menyebabkan perbedaan sementara berikut:
Negatif palsu (keterlambatan deteksi): Ini adalah hasil umum. Jika aturan bergantung pada pemicu kolom yang diperkaya (misalnya,
target.user.department == "Finance"), dan kolom tersebut adalahnull, aturan tidak cocok selama proses awal.Positif palsu (kegagalan pengecualian): Jika aturan Anda menggunakan kolom yang dipertkaya untuk memfilter aktivitas yang diketahui baik (misalnya,
NOT target.ip_geo_country == "US"), aturan tersebut dapat memicu positif palsu karena data "pengecualian" belum diterapkan.
Menjalankan penyesuaian
Eksekusi latar belakang ini mengevaluasi ulang data setelah jeda (misalnya, 45 menit atau 30 jam). Hal ini "menyesuaikan" status deteksi sebagai berikut:
Deteksi terlambat: Peristiwa yang "negatif palsu" pada T₀ kini menghasilkan deteksi setelah pengayaan selesai.
Koreksi: Semua positif palsu T₀ tetap ada dalam sistem, tetapi data yang sepenuhnya di-enrich dapat dilihat di penampil UDM untuk triase manual.
Perbedaan pengujian
Alat Jalankan Pengujian beroperasi pada data historis yang telah disesuaikan. Karena data sudah sepenuhnya di-enrich pada saat Anda menjalankan pengujian manual, Anda dapat langsung melihat hasil "penyesuaian". Artinya, Anda tidak akan melihat negatif palsu T₀ atau positif palsu berbasis pengecualian yang terjadi selama proses awal langsung.
Perbaikan error
Gunakan tabel berikut untuk menyelesaikan perbedaan antara pemberitahuan aktif dan hasil pengujian.
| Masalah | Deskripsi | Perbaikan yang dapat ditindaklanjuti |
|---|---|---|
| Kegagalan pengecualian | Aturan diaktifkan meskipun ada pengecualian (misalnya, != "ASN_123") karena kolom bernilai null selama proses awal. |
Tambahkan pemeriksaan tidak null ke bagian peristiwa untuk memastikan data diperkaya sebelum evaluasi, misalnya:$e.principal.ip_geo_artifact.network.asn != ""
|
| Live dibandingkan dengan pertandingan uji coba | Aturan aktif memicu pemberitahuan, tetapi Jalankan Pengujian pada data yang sama menampilkan "No Results". |
Tambahkan $e.field != "" yang memeriksa semua kolom yang di-enrich (GeoIP, ASN, File Path) untuk menyinkronkan perilaku langsung dan historis. |
| Metadata tidak ada | Deteksi muncul di dasbor dengan kolom GeoIP atau File Path yang kosong. |
Hal ini sudah diperkirakan untuk proses T0. Untuk memperbaikinya, sertakan pemeriksaan field != "" atau tingkatkan offset run pertama dalam jadwal run Anda untuk memberikan lebih banyak waktu untuk penyerapan.
|
Validasi dan pengujian
Untuk memverifikasi bahwa aturan menangani pengayaan yang tertunda dengan benar, lakukan hal berikut:
Identifikasi keterlambatan: Temukan deteksi yang Anda yakini sebagai positif palsu. Di kolom Detection Type, periksa ikon
<span class="material-icons">lightbulb</span>. Peringatan tanpa ikon ini berasal dari proses awal saat keterlambatan pengayaan paling sering terjadi.Perbarui logika aturan: Tambahkan pemeriksaan
field != ""untuk semua titik data yang diperkaya yang digunakan dalam logika Anda.
Contoh (jalur file):
$e.target.process.parent_process.file.full_path != ""Uji dan verifikasi:
- Gunakan fitur Jalankan Pengujian untuk memastikan logika Anda masih cocok dengan data historis yang dimaksud.
- Verifikasi bahwa aturan kini hanya dipicu (atau dikecualikan dengan benar) selama proses penyesuaian berjalan setelah kolom pengayaan diisi.
Untuk mengetahui detail selengkapnya, lihat Mengelola jadwal eksekusi aturan dan Mengonfigurasi jadwal yang disesuaikan untuk aturan.
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.