Sintaksis bagian hasil
Bagian outcome dari kueri YARA-L menentukan variabel hasil yang menentukan output untuk kueri penelusuran dan dasbor serta konteks dan informasi tambahan untuk deteksi saat aturan dipicu. Variabel ini dapat digunakan untuk berbagai tujuan seperti menampilkan data yang relevan di dasbor dan membuat skor risiko.
Menentukan bagian hasil
Gunakan karakter $, diikuti dengan nama variabel, untuk menentukan variabel hasil di bagian outcome dari satu kueri. Anda dapat menentukan hingga 20 variabel hasil. Nama variabel itu sendiri bersifat arbitrer. Untuk aturan, nilai hasil dihitung dan digabungkan berdasarkan setiap deteksi.
Setiap variabel hasil diberi nilai menggunakan ekspresi.
Aturan ini menelusuri upaya login yang gagal dari lokasi baru:
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
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
condition:
#e >= 5
}
Bagian outcome melakukan agregasi pada variabel peristiwa dan placeholder: menghitung upaya login yang gagal, menghitung IP unik, dan mendapatkan waktu terjadinya kegagalan.
outcome:
$failed_login_count = count($e.metadata.id)
$first_fail_time = min($e.metadata.event_timestamp.seconds)
Jika Anda menyertakan dan mengisi variabel hasil $risk_score khusus, nilainya (bilangan bulat atau float) akan ditampilkan di halaman Peringatan dan IoC untuk peringatan yang dihasilkan oleh kueri.
Jika Anda tidak menyertakan variabel $risk_score di bagian outcome kueri, salah satu nilai default berikut akan ditetapkan:
Jika kueri dikonfigurasi untuk menghasilkan pemberitahuan,
$risk_scoreakan ditetapkan ke 40.Jika kueri tidak dikonfigurasi untuk menghasilkan pemberitahuan,
$risk_scoreakan disetel ke 15.
Nilai $risk_score disimpan di kolom UDM security_result.risk_score.
Variabel hasil risk_score
Analisis Risiko Google SecOps secara otomatis mengaitkan deteksi dan pemberitahuan kembali ke entitas yang terkait dengan deteksi atau pemberitahuan tersebut. Variabel hasil risk_score digunakan untuk menetapkan jumlah risiko. Jika nilai ini tidak ditetapkan,
nilai deteksi atau pemberitahuan default akan digunakan. Anda dapat mengonfigurasi nilai default
di Setelan.
Untuk memastikan konsistensi di seluruh platform, sebaiknya gunakan rentang skor berikut saat menetapkan risk_score ke deteksi kustom Anda. Penyelarasan ini membantu menstandardisasi alur kerja respons dan prioritas pemberitahuan.
| Keparahan | Rentang skor | Deskripsi | Contoh |
|---|---|---|---|
| Pemberitahuan - Penting | 90 - 100 | Kompromi aktif yang berpotensi berdampak di luar satu akun pengguna atau endpoint. Memerlukan peninjauan segera. | Mimikatz dijalankan di Pengontrol Domain. |
| Pemberitahuan - Tinggi | 80 - 89 | Kompromi aktif pada satu endpoint atau entitas. Harus segera ditinjau. | Server produksi memanggil C2 yang baru dan diketahui. |
| Pemberitahuan - Sedang | 50 - 79 | Potensi masalah keamanan yang memerlukan penyelidikan. Tidak ada penyusupan yang dikonfirmasi, tetapi eskalasi mungkin dilakukan. | Kredensial terekspos, tidak ada tanda-tanda penyalahgunaan. |
| Tidak Memberi Peringatan - Rendah | 20 - 49 | Peristiwa keamanan berdampak rendah yang, jika digabungkan dengan indikator atau pengamatan lain, dapat menyebabkan insiden yang lebih signifikan. Umumnya tidak memerlukan peninjauan, dapat digabungkan dengan deteksi lain melalui aturan komposit untuk membuat pemberitahuan. | Pemindaian port internal. |
| Pengamatan Non-Peringatan | 1 - 19 | Umumnya, deteksi berbasis informasi dimaksudkan untuk membangun kesadaran situasional terhadap ancaman. Umumnya tidak memerlukan peninjauan; dapat digabungkan dengan deteksi lain melalui aturan gabungan untuk menghasilkan pemberitahuan. | Peristiwa login, tidak ada tanda-tanda penyalahgunaan. |
Karena risk_score adalah variabel hasil, aturan Anda dapat mengekspresikan nuansa
bergantung pada faktor seperti intelijen ancaman atau kondisi bersamaan lainnya.
Skor risiko entity dapat digunakan untuk menghasilkan pemberitahuan berbasis risiko hampir secara real time. Untuk mengetahui informasi selengkapnya, lihat Ringkasan Analisis Risiko.
Variabel hasil risk_entity_to_score
Selain variabel hasil risk_score, Anda juga dapat menentukan
variabel hasil risk_entity_to_score. Variabel ini memungkinkan Anda secara eksplisit
menentukan entitas atau entitas mana dari deteksi aturan yang harus menerapkan skor risiko
deteksi tersebut.
Anda dapat membuat beberapa variabel risk_entity_to_score dengan menambahkan string
unik ke variabel dan menetapkan skor risiko ke entity tertentu. Misalnya:
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
Variabel hasil ini menetapkan risk_score yang ditentukan di bagian
outcome aturan ke entity $e.principal.asset.hostname dan
$e.target.user.userid.
Contoh: Aturan mendeteksi login ke akun administrator
Aturan ini mendeteksi login yang berhasil ke akun administrator dengan hak istimewa tinggi. Fitur ini menggunakan kata kunci risk_entity_to_score untuk menargetkan pengguna tertentu yang login secara eksplisit. Dengan menggunakan variabel ini, deteksi memastikan bahwa skor risiko yang dihitung hanya berlaku untuk pengguna tersebut dan bukan untuk entitas lain yang terlibat dalam peristiwa, seperti alamat IP sumber.
Untuk mengetahui detail tentang cara menulis aturan multi-peristiwa, lihat Aturan multi-peristiwa.
rule suspicious_admin_privilege_escalation {
// This rule matches single events. Rules can also match multiple events within
// the same time window.
meta:
// Allows for storage of arbitrary key-value pairs of rule details, such as
// who wrote it, what it detects on, and version control.
// The "author" and "severity" fields are special, since they are used as
// columns on the rules dashboard. To sort based on these fields on the
// dashboard, add them here.
// Severity value should be "Low", "Medium", or "High"
author = "analyst123"
description = "Detects suspicious login to critical admin accounts."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.target.user.attribute.roles.name = "ADMIN"
$e.security_result.summary = "Successful login with high-privilege access"
outcome:
// Multi-event rules require an aggregation function
// For example, risk_score = max(0)
// See https://cloud.google.com/chronicle/docs/detection/yara-l-2-0-overview#outcome_conditionals_example_rule
$risk_score = 80
$risk_entity_to_score = $e.target.user.userid
$source_ip = array_distinct($e.principal.ip)
condition:
$e
}
Contoh: Aturan memantau koneksi jaringan internal
Aturan ini memeriksa pergerakan lateral dengan mengidentifikasi koneksi jaringan di antara segmen jaringan internal. Deteksi ini menggunakan $risk_entity_to_score prefix untuk menetapkan risiko ke beberapa entitas dalam satu deteksi. Skor risiko host yang memulai ($risk_entity_to_score_source_asset) dan pengguna yang menjadi target ($risk_entity_to_score_targeted_user) akan diperbarui. Mesin risiko mencatat variabel hasil lainnya yang tidak menggunakan awalan spesifik ini untuk konteks, tetapi mengabaikannya (skor risiko mereka tetap sama).
Untuk mengetahui detail tentang cara menulis aturan multi-peristiwa, lihat Aturan multi-peristiwa dan Contoh aturan kondisional hasil.
rule lateral_movement_network_connection {
// This rule matches single events. You can also match multiple events within
// the same time window.
meta:
// Allows for storage of arbitrary key-value pairs of rule details (for
// example, who wrote it, what it detects on, and version control).
// The "author" and "severity" fields are special, since they are used as
// columns on the rules dashboard. To sort based on these fields on the
// dashboard, add them here. Severity value should be "Low", "Medium" or "High"
author = "analyst123"
description = "Detects lateral movement attempts between internal segments."
severity = "MEDIUM"
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$e.principal.asset.hostname != ""
$e.target.user.userid != ""
// Can also use: $e.target.ip = /10\..*/
net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")
outcome:
// Multi-event rules require an aggregation function
// for example, risk_score = max(0)
// See https://docs.cloud.google.com/chronicle/docs/yara-l/yara-l-2-0-examples#outcome-conditionals-example-rule
$risk_score = 50
$risk_entity_to_score_source_asset = $e.principal.asset.hostname
$risk_entity_to_score_targeted_user = $e.target.user.userid
$target_ip_info = array_distinct($e.target.ip)
condition:
$e
}
Jenis data variabel hasil
Setiap variabel hasil dapat memiliki jenis data yang berbeda, yang ditentukan oleh ekspresi yang digunakan untuk menghitungnya. Jenis data hasil berikut didukung di Google SecOps:
- integer
- mengambang
- string
- daftar bilangan bulat
- daftar float
- daftar string
Logika kondisional
Anda dapat menggunakan logika bersyarat untuk menghitung nilai hasil. Kondisional ditentukan menggunakan pola sintaksis berikut:
if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)
Anda dapat membaca ekspresi kondisional sebagai "jika BOOL_CLAUSE benar, maka tampilkan THEN_CLAUSE, jika tidak, tampilkan ELSE_CLAUSE".
BOOL_CLAUSE harus dievaluasi ke nilai boolean. Ekspresi BOOL_CLAUSE memiliki
bentuk yang serupa dengan ekspresi di bagian events. Misalnya, cache dapat berisi:
Nama kolom UDM dengan operator perbandingan:
if($context.graph.entity.user.title = "Vendor", 100, 0)Variabel placeholder yang ditentukan di bagian
events:if($severity = "HIGH", 100, 0)Variabel hasil lain yang ditentukan di bagian
outcome:if($risk_score > 20, "HIGH", "LOW")Fungsi yang menampilkan boolean:
if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)Cari di daftar referensi:
if($u.principal.hostname in %my_reference_list_name, 100, 0)Perbandingan agregasi:
if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)
THEN_CLAUSE dan ELSE_CLAUSE harus memiliki jenis data yang sama. Kami mendukung bilangan bulat, float, dan string.
Anda dapat menghilangkan ELSE_CLAUSE jika jenis datanya adalah bilangan bulat atau float. Jika tidak ada, ELSE_CLAUSE akan dievaluasi menjadi 0. Contoh:
`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`
Anda harus memberikan ELSE_CLAUSE jika jenis datanya adalah string atau jika THEN_CLAUSE adalah variabel placeholder atau variabel hasil.
Operasi matematika
Anda dapat menggunakan operasi matematika untuk menghitung jenis data bilangan bulat atau float di bagian outcomedan events kueri. Google Security Operations mendukung penambahan, pengurangan, perkalian, pembagian, dan modulus sebagai operator tingkat teratas dalam komputasi.
Cuplikan berikut adalah contoh komputasi di bagian outcome:
outcome:
$risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))
Operasi matematika diizinkan pada jenis operand berikut selama setiap operand dan seluruh ekspresi aritmatika diagregasi dengan benar (Lihat Agregasi):
- Kolom peristiwa numerik
- Variabel placeholder numerik yang ditentukan di bagian
events - Variabel hasil numerik yang ditentukan di bagian
outcome - Fungsi yang menampilkan int atau float
- Agregasi yang menampilkan bilangan bulat atau float
Modulus tidak diizinkan pada float.
Variabel placeholder dalam hasil
Saat menghitung variabel hasil, Anda dapat menggunakan variabel placeholder yang
ditentukan di bagian peristiwa kueri Anda. Dalam contoh ini, asumsikan bahwa
$email_sent_bytes ditentukan di bagian peristiwa aturan:
Contoh: satu peristiwa tanpa bagian kecocokan
// No match section, so this is a single-event query. outcome: // Use placeholder directly as an outcome value. $my_outcome = $email_sent_bytes // Use placeholder in a conditional. $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE") condition: $e
Contoh: multi-event dengan bagian kecocokan
match:
// This is a multi event query with a match section.
$hostname over 5m
outcome:
// Use placeholder directly in an aggregation function.
$max_email_size = max($email_sent_bytes)
// Use placeholder in a mathematical computation.
$total_bytes_exfiltrated = sum(
1024
+ $email_sent_bytes
+ $file_event.principal.file.size
)
condition:
$email_event and $file_eventVariabel hasil dalam ekspresi penetapan hasil
Variabel hasil dapat digunakan untuk mendapatkan variabel hasil lainnya, mirip dengan
variabel placeholder yang ditentukan di bagian events. Anda dapat merujuk ke variabel
hasil dalam penetapan variabel hasil lain dengan token $ yang diikuti
oleh nama variabel. Variabel hasil harus ditentukan sebelum dapat dirujuk dalam teks kueri. Jika digunakan dalam ekspresi penetapan, variabel hasil tidak boleh diagregasi (Lihat Agregasi).
Pada contoh berikut, variabel hasil $risk_score memperoleh
nilainya dari variabel hasil $event_count:
Contoh: variabel hasil yang berasal dari variabel hasil lain
match: // This is a multi event query with a match section. $hostname over 5m outcome: // Aggregates all timestamp on login events in the 5 minute match window. $event_count = count($login.metadata.event_timestamp.seconds) // $event_count cannot be aggregated again. $risk_score = if($event_count > 5, "SEVERE", "MODERATE") // This is the equivalent of the 2 outcomes combined. $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE") condition: $e
Variabel hasil dapat digunakan dalam jenis ekspresi apa pun di sisi kanan penetapan hasil, kecuali dalam ekspresi berikut:
- Agregasi
- Panggilan fungsi
Arrays.length() - Dengan pengubah
anyatauall
Agregasi
Kolom peristiwa berulang adalah nilai non-skalar. Artinya, satu variabel mengarah ke
beberapa nilai. Misalnya, variabel kolom peristiwa $e.target.ip adalah kolom berulang
dan dapat memiliki nol, satu, atau banyak nilai ip. Ini adalah nilai non-skalar. Sedangkan variabel kolom peristiwa
$e.principal.hostname bukan kolom berulang dan hanya memiliki 1 nilai (yaitu nilai skalar).
Demikian pula, kolom peristiwa yang tidak berulang dan kolom peristiwa berulang yang digunakan di bagian outcome
dari kueri dengan jendela kecocokan adalah nilai non-skalar.
Contoh: mengelompokkan peristiwa dengan bagian kecocokan dan kolom yang tidak berulang
Kueri berikut mengelompokkan peristiwa menggunakan bagian `match` dan merujuk ke kolom peristiwa yang tidak berulang di bagian `outcome`:
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}Setiap periode 5 menit saat kueri dijalankan mungkin berisi nol, satu, atau banyak peristiwa. Bagian hasil
beroperasi pada semua peristiwa dalam jendela kecocokan. Setiap variabel kolom peristiwa yang dirujuk dalam bagian
hasil dapat mengarah ke nol, satu, atau banyak nilai kolom pada setiap peristiwa di jendela pencocokan.
Misalnya, jika periode 5 menit berisi 5 peristiwa $e, $e.principal.hostname
di bagian hasil menunjukkan lima nama host yang berbeda. Variabel kolom peristiwa
$e.principal.hostname diperlakukan sebagai nilai non-skalar di bagian outcome kueri ini.
Karena variabel hasil harus selalu menghasilkan satu nilai skalar, setiap nilai non-skalar yang bergantung pada penetapan hasil harus diagregasi untuk menghasilkan satu nilai skalar. Di bagian hasil, berikut adalah nilai non-skalar dan harus digabungkan:
- Kolom peristiwa (berulang atau tidak berulang) saat kueri menggunakan bagian
match - Placeholder peristiwa (berulang atau tidak berulang) saat kueri menggunakan bagian
match - Kolom peristiwa berulang saat kueri tidak menggunakan bagian
match - Placeholder acara berulang saat kueri tidak menggunakan bagian
match
Kolom peristiwa skalar, placeholder peristiwa skalar, dan konstanta dapat di-wrap dalam
fungsi agregasi dalam kueri yang tidak menyertakan bagian match. Namun, dalam
sebagian besar kasus, agregasi ini menampilkan nilai yang di-wrap, sehingga tidak diperlukan.
Pengecualiannya adalah agregasi array(), yang dapat Anda gunakan untuk mengonversi
nilai skalar menjadi array secara eksplisit.
Variabel hasil diperlakukan seperti agregasi: variabel tersebut tidak boleh diagregasi ulang saat dirujuk dalam penetapan hasil lain.
Anda dapat menggunakan fungsi agregasi berikut:
| Fungsi Agregasi | Deskripsi |
|---|---|
max() |
Menampilkan nilai maksimum dari semua kemungkinan nilai. Hanya berfungsi dengan bilangan bulat dan float. |
min() |
Menampilkan nilai minimum untuk semua kemungkinan nilai. Hanya berfungsi dengan bilangan bulat dan float. |
sum() |
Menampilkan jumlah semua kemungkinan nilai. Hanya berfungsi dengan bilangan bulat dan float. |
count_distinct() |
Mengumpulkan semua kemungkinan nilai, lalu menampilkan jumlah unik dari kemungkinan nilai. |
count() |
Berperilaku seperti `count_distinct()`, tetapi menampilkan jumlah nilai yang mungkin non-unik. |
array_distinct() |
Mengumpulkan semua nilai unik yang mungkin, lalu menampilkan daftar nilai ini. Fungsi ini memangkas daftar nilai berbeda menjadi 1.000 elemen acak. Penghapusan duplikat untuk mendapatkan daftar unik diterapkan terlebih dahulu, lalu pemotongan diterapkan. |
array() |
Berperilaku seperti array_distinct(), tetapi menampilkan daftar nilai yang tidak berbeda. Fungsi ini juga memangkas daftar nilai menjadi 1.000 elemen acak. |
Fungsi agregat penting saat aturan menyertakan bagian condition yang menentukan bahwa beberapa peristiwa harus ada, karena fungsi agregat akan beroperasi pada semua peristiwa yang menghasilkan deteksi.
Contoh: kondisi untuk beberapa peristiwa
Berikut adalah contoh kondisi untuk beberapa peristiwa. Jika bagian hasil dan kondisi Anda berisi:
outcome: $asset_id_count = count($event.principal.asset_id) $asset_id_distinct_count = count_distinct($event.principal.asset_id) $asset_id_list = array($event.principal.asset_id) $asset_id_distinct_list = array_distinct($event.principal.asset_id) condition: #event > 1
Karena bagian `condition` mengharuskan ada lebih dari satu `event` untuk setiap deteksi, fungsi gabungan akan beroperasi pada beberapa peristiwa. Misalkan peristiwa berikut menghasilkan satu deteksi:
event: // UDM event 1 asset_id="asset-a" event: // UDM event 2 asset_id="asset-b" event: // UDM event 3 asset_id="asset-b"
Maka nilai hasil Anda adalah:
- $asset_id_count = 3
- $asset_id_distinct_count = 2
- $asset_id_list = `["asset-a", "asset-b", "asset-b"]
- $asset_id_distinct_list = `["asset-a", "asset-b"]
Batasan
Bagian
outcometidak dapat mereferensikan variabel placeholder baru yang belum ditentukan di bagianeventsatau di bagianoutcome.Bagian
outcometidak dapat menggunakan variabel peristiwa yang belum ditentukan di bagianevents.Bagian
outcomedapat menggunakan kolom peristiwa yang tidak digunakan di bagianevents, mengingat variabel peristiwa yang menjadi bagian dari kolom peristiwa tersebut telah ditentukan di bagianevents.Bagian
outcomehanya dapat mengorelasikan variabel peristiwa yang telah dikorelasikan di bagianevents. Korelasi terjadi saat dua kolom peristiwa dari variabel peristiwa yang berbeda disamakan.
Lihat Ringkasan YARA-L 2.0 untuk contoh bagian outcome.
Lihat Membuat analisis sesuai konteks untuk mengetahui detail tentang penghapusan duplikat deteksi dengan bagian outcome.
Langkah berikutnya
Informasi tambahan
- Ekspresi, operator, dan konstruksi yang digunakan di YARA-L 2.0
- Fungsi di YARA-L 2.0
- Membangun aturan deteksi komposit
- Contoh: Kueri YARA-L 2.0
Perlu bantuan lain? Dapatkan jawaban dari anggota Komunitas dan profesional Google SecOps.