Sintaksis bagian hasil

Didukung di:

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_score akan ditetapkan ke 40.

  • Jika kueri tidak dikonfigurasi untuk menghasilkan pemberitahuan, $risk_score akan 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_event

Variabel 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 any atau all

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 outcome tidak dapat mereferensikan variabel placeholder baru yang belum ditentukan di bagian events atau di bagian outcome.

  • Bagian outcome tidak dapat menggunakan variabel peristiwa yang belum ditentukan di bagian events.

  • Bagian outcome dapat menggunakan kolom peristiwa yang tidak digunakan di bagian events, mengingat variabel peristiwa yang menjadi bagian dari kolom peristiwa tersebut telah ditentukan di bagian events.

  • Bagian outcome hanya dapat mengorelasikan variabel peristiwa yang telah dikorelasikan di bagian events. 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

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