Sintaksis bahasa YARA-L 2.0

Bagian ini menjelaskan elemen utama sintaksis YARA-L. Lihat juga Ringkasan bahasa YARA-L 2.0.

Struktur aturan

Untuk YARA-L 2.0, Anda harus menentukan deklarasi, definisi, dan penggunaan variabel dalam urutan berikut:

  1. meta
  2. peristiwa
  3. match (opsional)
  4. hasil (opsional)
  5. kondisi
  6. opsi (opsional)

Berikut ini ilustrasi struktur umum sebuah aturan:

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

Sintaksis bagian meta

Bagian meta terdiri dari beberapa baris, yang setiap barisnya mendefinisikan pasangan nilai kunci. Bagian kunci harus berupa string yang tidak dikutip, dan bagian nilai harus berupa string yang dikutip:

<key> = "<value>"

Berikut contoh baris bagian meta yang valid: none meta: author = "Chronicle" severity = "HIGH"

Sintaksis bagian Peristiwa

Di bagian events, cantumkan predikat untuk menentukan hal berikut:

  • Deklarasi variabel
  • Filter variabel peristiwa
  • Penggabungan variabel peristiwa

Deklarasi variabel

Untuk deklarasi variabel, gunakan sintaksis berikut:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

Keduanya setara, seperti yang ditunjukkan dalam contoh berikut:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

Deklarasi ini menunjukkan bahwa variabel ini mewakili kolom yang ditentukan untuk variabel peristiwa. Jika kolom peristiwa adalah kolom berulang, variabel pencocokan dapat mewakili nilai apa pun dalam array. Anda juga dapat menetapkan beberapa kolom peristiwa ke variabel placeholder atau pencocokan tunggal. Ini adalah kondisi gabungan transitif.

Misalnya:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

Setara dengan:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

Saat variabel digunakan, variabel harus dideklarasikan melalui deklarasi variabel. Jika variabel digunakan tanpa deklarasi, variabel ini dianggap sebagai error kompilasi.

Filter variabel peristiwa

Ekspresi boolean yang bertindak pada variabel peristiwa tunggal dianggap sebagai filter.

Penggabungan variabel peristiwa

Semua variabel peristiwa yang digunakan dalam aturan harus digabungkan dengan setiap variabel peristiwa lainnya menggunakan salah satu cara berikut:

  • Langsung melalui perbandingan kesetaraan antara kolom peristiwa dari dua variabel peristiwa yang digabungkan, misalnya: $e1.field = $e2.field. Ekspresi tidak boleh berisi aritmetika.

  • Secara tidak langsung melalui gabungan transitif yang hanya melibatkan kolom peristiwa (lihat deklarasi variabel untuk mengetahui definisi "gabungan transitif"). Ekspresi tidak boleh berisi aritmetika.

Misalnya, dengan asumsi $e1, $e2, dan $e3 digunakan dalam aturan, bagian events berikut adalah valid.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

Namun, berikut ini contoh bagian events yang tidak valid.

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

Sintaksis bagian pencocokan

Di bagian match, cantumkan variabel pencocokan untuk peristiwa grup sebelum memeriksa kondisi pencocokan. Kolom tersebut ditampilkan dengan setiap kecocokan.

  • Tentukan apa yang diwakili oleh setiap variabel pencocokan di bagian events.
  • Tentukan durasi waktu yang akan digunakan untuk menghubungkan peristiwa setelah kata kunci over. Peristiwa di luar durasi waktu akan diabaikan.
  • Gunakan sintaksis berikut untuk menentukan durasi waktu: <number><m/h/d>

    Dengan m/h/d berarti menit, jam, dan hari.

  • Waktu minimum yang dapat Anda tentukan adalah 1 menit.

  • Waktu maksimum yang dapat Anda tentukan adalah 48 jam.

Berikut adalah contoh match yang valid:

$var1, $var2 over 5m

Pernyataan ini menampilkan $var1 dan $var2 (ditentukan di bagian events) saat aturan menemukan kecocokan. Waktu yang ditentukan adalah 5 menit. Peristiwa yang jaraknya lebih dari 5 menit tidak akan berkorelasi, sehingga akan diabaikan oleh aturan.

Berikut contoh lain bagian match yang valid:

$user over 1h

Pernyataan ini menampilkan $user jika aturan menemukan kecocokan. Periode waktu yang ditentukan adalah 1 jam. Peristiwa yang jaraknya lebih dari satu jam tidak ada korelasinya. Aturan ini tidak menganggapnya sebagai deteksi.

Berikut contoh lain bagian match yang valid:

$source_ip, $target_ip, $hostname over 2m

Pernyataan ini menampilkan $source_ip, $target_ip, dan $hostname jika aturan menemukan kecocokan. Jangka waktu yang ditentukan adalah 2 menit. Peristiwa yang jaraknya lebih dari 2 menit tidak ada hubungannya. Aturan ini tidak menganggapnya sebagai deteksi.

Contoh berikut menggambarkan bagian match yang tidak valid:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

Penanganan nilai nol di bagian pencocokan

Rules Engine secara implisit memfilter nilai nol untuk semua placeholder yang digunakan di bagian pencocokan ("" untuk string, 0 untuk angka, false untuk boolean, nilai di posisi 0 untuk jenis terenumerasi). Contoh berikut mengilustrasikan aturan yang memfilter nilai nol.

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule behaves
    // as if the following predicate was added to the events section:
    // $host != ""
    $host = $e.principal.hostname

    // Because $otherPlaceholder was not used in the match section,
    // there is no implicit filtering of zero values for $otherPlaceholder.
    $otherPlaceholder = $e.principal.ip

  match:
    $host over 5m

  condition:
    $e
}

Namun, jika placeholder ditetapkan ke suatu fungsi, aturan tidak secara implisit memfilter nilai nol placeholder yang digunakan di bagian pencocokan. Contoh berikut mengilustrasikan aturan yang memfilter nilai nol:

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

Untuk menonaktifkan pemfilteran implisit nilai nol, Anda dapat menggunakan opsi allow_zero_values di bagian opsi.

Lompat jendela

Secara default, aturan YARA-L 2.0 dengan bagian kecocokan dievaluasi menggunakan jendela hop. Rentang waktu eksekusi aturan dibagi menjadi serangkaian periode hop yang tumpang-tindih, masing-masing dengan durasi yang ditentukan di bagian match. Peristiwa kemudian dikorelasikan dalam setiap jendela hop.

Misalnya, untuk aturan yang dijalankan selama rentang waktu [1:00, 2:00], dengan bagian match pada 30m, kemungkinan rangkaian periode hop tumpang-tindih yang dapat dihasilkan adalah [1:00, 1:30], [1:03, 1:33], dan [1:06, 1:36]. Jendela ini digunakan untuk menghubungkan beberapa peristiwa.

Jendela geser

Menggunakan jendela hop bukan cara yang efektif untuk menelusuri peristiwa yang terjadi dalam urutan tertentu (misalnya, e1 terjadi hingga 2 menit setelah e2). Kejadian peristiwa e1 dan kejadian e2 berkorelasi hanya jika keduanya termasuk dalam periode hop yang sama dengan yang dihasilkan.

Cara yang lebih efektif untuk menelusuri urutan peristiwa tersebut adalah dengan menggunakan jendela geser. Jendela geser dengan durasi yang ditentukan di bagian match dihasilkan saat memulai atau mengakhiri dengan variabel peristiwa pivot yang ditentukan. Peristiwa kemudian berkorelasi dalam setiap jendela geser. Hal ini memungkinkan penelusuran peristiwa yang terjadi dalam urutan tertentu (misalnya, e1 terjadi dalam 2 menit dari e2). Kejadian e1 dan kemunculan peristiwa e2 berkorelasi jika peristiwa e1 terjadi dalam durasi jendela geser setelah peristiwa e2.

Tentukan jendela geser di bagian match aturan sebagai berikut:

<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>

Variabel peristiwa pivot adalah variabel peristiwa yang menjadi dasar jendela geser. Jika Anda menggunakan kata kunci before, jendela geser akan dihasilkan, yang diakhiri dengan setiap kemunculan peristiwa pivot. Jika kata kunci after digunakan, jendela geser akan dibuat dimulai dengan setiap kemunculan peristiwa pivot.

Berikut adalah contoh penggunaan jendela geser yang valid:

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

Lihat contoh aturan jendela geser.

Google merekomendasikan untuk tidak menggunakan jendela geser untuk aturan peristiwa tunggal karena jendela geser dirancang untuk mendeteksi beberapa peristiwa. Jika salah satu aturan Anda termasuk dalam kategori ini, Google merekomendasikan salah satu solusi berikut:

  • Konversi aturan untuk menggunakan beberapa variabel peristiwa, dan perbarui bagian kondisi jika aturan memerlukan lebih dari satu kemunculan peristiwa.
    • Secara opsional, pertimbangkan untuk menambahkan filter stempel waktu, bukan menggunakan jendela geser. Contoh, $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds
  • Hapus jendela geser.

Sintaksis bagian hasil

Di bagian outcome, Anda dapat menentukan hingga 20 variabel hasil, dengan nama arbitrer. Hasil ini akan disimpan dalam deteksi yang dihasilkan oleh aturan. Setiap deteksi dapat memiliki nilai yang berbeda untuk hasilnya.

Nama hasil, $risk_score, bersifat spesial. Secara opsional, Anda dapat menentukan hasil dengan nama ini, dan jika melakukannya, hasil harus berupa jenis bilangan bulat atau float. Jika diisi, risk_score akan ditampilkan di tampilan Enterprise Insights untuk pemberitahuan yang berasal dari deteksi aturan.

Jika Anda tidak menyertakan variabel $risk_score di bagian hasil aturan, salah satu nilai default berikut akan ditetapkan:

  • Jika aturan dikonfigurasi untuk menghasilkan notifikasi, $risk_score ditetapkan ke 40.
  • Jika aturan tidak dikonfigurasi untuk menghasilkan notifikasi, $risk_score ditetapkan ke 15.

Nilai $risk_score disimpan di kolom UDM security_result.risk_score.

Jenis data variabel hasil

Setiap variabel hasil dapat memiliki jenis data berbeda, yang ditentukan oleh ekspresi yang digunakan untuk menghitungnya. Kami mendukung jenis data hasil berikut:

  • bilangan bulat
  • {i>float<i}
  • string
  • daftar bilangan bulat
  • daftar float
  • daftar string

Logika kondisional

Anda dapat menggunakan logika bersyarat untuk menghitung nilai suatu hasil. Kondisional ditentukan menggunakan pola sintaksis berikut:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

Anda dapat membaca ekspresi kondisional seperti "jika BOOL_CLAUSE benar, lalu tampilkan THEN_CLAUSE, else tampilkan ELSE_CLAUSE".

BOOL_CLAUSE harus dievaluasi ke nilai boolean. Ekspresi BOOL_CLAUSE mengambil bentuk yang serupa dengan ekspresi di bagian events. Misalnya, tata letak ini dapat berisi:

  • Nama kolom UDM dengan operator perbandingan, misalnya:

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • variabel placeholder yang ditentukan di bagian events, misalnya:

    if($severity = "HIGH", 100, 0)

  • variabel hasil lain yang ditentukan di bagian outcome, misalnya:

    if($risk_score > 20, "HIGH", "LOW")

  • fungsi yang menampilkan boolean, misalnya:

    if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)

  • cari di daftar referensi, misalnya:

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

  • perbandingan agregasi, misalnya:

    if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)

THEN_CLAUSE dan ELSE_CLAUSE harus merupakan jenis data yang sama. Kami mendukung bilangan bulat, float, dan string.

Anda dapat menghilangkan ELSE_CLAUSE jika jenis data adalah integer atau float. Jika dihilangkan, ELSE_CLAUSE akan bernilai 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 outcome dan events dari aturan. Chronicle mendukung penambahan, pengurangan, perkalian, pembagian, dan modulus sebagai operator tingkat atas 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 aritmetika digabungkan 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 int 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 pada aturan Anda. Dalam contoh ini, asumsikan bahwa $email_sent_bytes ditentukan di bagian peristiwa pada aturan:

Contoh peristiwa tunggal:

// No match section, so this is a single-event rule.

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-peristiwa:

match:
  // This is a multi event rule 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 dengan nama variabel. Variabel hasil harus ditentukan sebelum dapat dirujuk di teks aturan. Saat digunakan dalam ekspresi tugas, variabel hasil tidak boleh digabungkan (Lihat Agregasi).

Dalam contoh berikut, variabel hasil $risk_score mendapatkan nilainya dari variabel hasil $event_count:

Contoh multi-peristiwa:

match:
  // This is a multi event rule 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 above 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 sebelah kanan tugas 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 menunjuk ke beberapa nilai. Misalnya, variabel kolom peristiwa $e.target.ip adalah kolom berulang dan dapat memiliki nol, satu, atau banyak nilai ip. Nilai 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 hasil aturan dengan jendela pencocokan adalah nilai non-skalar. Misalnya, aturan berikut mengelompokkan peristiwa menggunakan bagian pencocokan dan merujuk pada kolom peristiwa yang tidak berulang di bagian hasil:

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

Setiap periode 5 menit yang dijalankan aturan dapat berisi nol, satu, atau beberapa peristiwa. Bagian hasil beroperasi di semua peristiwa di jendela pencocokan. Setiap variabel kolom peristiwa yang dirujuk dalam bagian hasil dapat mengarah ke nol, satu, atau beberapa nilai kolom pada setiap peristiwa di jendela pencocokan. Pada aturan sebelumnya, jika periode 5 menit berisi 5 peristiwa $e, $e.principal.hostname di bagian hasil mengarah ke 5 nama host yang berbeda. Jadi, variabel kolom peristiwa $e.principal.hostname adalah nilai non-skalar di bagian hasil aturan ini.

Karena variabel hasil harus selalu menghasilkan nilai skalar tunggal, nilai non-skalar apa pun yang menjadi dependensi penetapan hasil harus digabungkan untuk menghasilkan satu nilai skalar. Di bagian hasil, berikut ini adalah nilai non-skalar dan harus diagregasi:

  • Kolom peristiwa (berulang atau tidak berulang) saat aturan menggunakan bagian pencocokan
  • Placeholder peristiwa (berulang atau tidak berulang) saat aturan menggunakan bagian pencocokan
  • Kolom peristiwa berulang saat aturan tidak menggunakan bagian pencocokan
  • Placeholder peristiwa berulang saat aturan tidak menggunakan bagian pencocokan

Kolom peristiwa skalar, placeholder peristiwa skalar, dan konstanta dapat digabungkan dalam agregasi dalam aturan yang tidak menggunakan bagian pencocokan. Namun, sebagian besar agregasi akan menghasilkan nilai gabungan dan tidak diperlukan. Pengecualiannya adalah agregasi array() yang dapat digunakan untuk mengonversi nilai skalar menjadi array.

Variabel hasil diperlakukan seperti agregasi: variabel tidak boleh digabungkan ulang saat dirujuk dalam penetapan hasil lain.

Anda dapat menggunakan fungsi agregasi berikut:

  • max(): menghasilkan output maksimum dari semua nilai yang memungkinkan. Hanya berfungsi dengan bilangan bulat dan float.
  • min(): menghasilkan output minimum dari semua nilai yang memungkinkan. Hanya berfungsi dengan bilangan bulat dan float.
  • sum(): menghasilkan jumlah dari semua nilai yang mungkin. Hanya berfungsi dengan bilangan bulat dan float.
  • count_distinct(): mengumpulkan semua nilai yang mungkin, lalu menghasilkan jumlah yang berbeda dari nilai yang memungkinkan.
  • count(): berperilaku seperti count_distinct(), tetapi menampilkan jumlah nilai yang mungkin yang tidak jelas.
  • array_distinct(): mengumpulkan semua kemungkinan nilai yang berbeda, lalu menghasilkan daftar nilai tersebut. Tindakan ini akan memotong daftar nilai yang berbeda menjadi 25 elemen acak. Penghapusan duplikat untuk mendapatkan daftar yang berbeda akan diterapkan terlebih dahulu, lalu pemotongan akan diterapkan.
  • array(): berperilaku seperti array_distinct(), tetapi menampilkan daftar nilai yang tidak jelas. Kode ini juga memotong daftar nilai menjadi 25 elemen acak.

Fungsi agregat penting jika aturan menyertakan bagian condition yang menentukan beberapa peristiwa harus ada, karena fungsi agregat akan beroperasi pada semua peristiwa yang menghasilkan deteksi.

Misalnya, jika bagian outcome dan condition 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 kondisi mengharuskan ada lebih dari satu event untuk setiap deteksi, fungsi agregat 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 dari 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"]

Hal-hal yang perlu diketahui saat menggunakan bagian hasil:

Catatan dan batasan lainnya:

  • 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 tempat kolom peristiwa tersebut telah ditentukan di bagian events.
  • Bagian outcome hanya dapat mengkorelasikan variabel peristiwa yang telah dikorelasikan di bagian events. Korelasi terjadi jika dua kolom peristiwa dari variabel peristiwa yang berbeda disamakan.

Anda dapat menemukan contohnya menggunakan bagian hasil di Ringkasan YARA-L 2.0. Lihat Membuat analisis kontekstual untuk mengetahui detail tentang penghapusan duplikat deteksi dengan bagian hasil.

Sintaksis bagian kondisi

  • menentukan kondisi pencocokan terhadap peristiwa dan placeholder yang ditentukan di bagian events. Lihat bagian berikut, Kondisional peristiwa dan placeholder untuk detail selengkapnya.
  • (opsional) gunakan kata kunci and untuk menentukan kondisi pencocokan menggunakan variabel hasil yang ditentukan di bagian outcome. Lihat bagian berikut, Kondisi hasil, untuk detail selengkapnya.

Hitung karakter

Karakter # adalah karakter khusus di bagian condition. Jika digunakan sebelum nama variabel placeholder atau peristiwa apa pun, atribut ini akan merepresentasikan jumlah peristiwa atau nilai berbeda yang memenuhi semua kondisi bagian events.

Misalnya, #c > 1 berarti variabel c harus terjadi lebih dari 1 kali.

Karakter nilai

Karakter $ adalah karakter khusus di bagian condition. Jika digunakan sebelum nama variabel hasil apa pun, variabel ini mewakili nilai hasil tersebut.

Jika digunakan sebelum peristiwa atau nama variabel placeholder apa pun (misalnya, $event), atribut tersebut mewakili #event > 0.

Kondisional peristiwa dan placeholder

Mencantumkan predikat kondisi untuk peristiwa dan variabel placeholder di sini, digabungkan dengan kata kunci and atau or. Kata kunci and dapat digunakan di antara kondisi apa pun, tetapi kata kunci or hanya dapat digunakan jika aturan hanya memiliki satu variabel peristiwa.

Contoh valid penggunaan or di antara dua placeholder pada peristiwa yang sama:

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

Contoh penggunaan or yang tidak valid di antara dua kondisi pada peristiwa yang berbeda:

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

Kondisi terikat dan tidak dibatasi

Kondisi berikut adalah kondisi terbatas. Metode tersebut memaksa adanya variabel peristiwa terkait, yang berarti bahwa setidaknya satu kemunculan peristiwa harus muncul dalam deteksi apa pun.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

Kondisi berikut adalah kondisi tidak terbatas. Atribut ini memungkinkan variabel peristiwa terkait tidak ada. Artinya, ada kemungkinan bahwa tidak ada kemunculan peristiwa yang muncul dalam deteksi dan referensi apa pun ke kolom pada variabel peristiwa akan menghasilkan nilai nol. Kondisi tak terbatas dapat digunakan untuk mendeteksi tidak adanya peristiwa selama jangka waktu tertentu. Misalnya, peristiwa ancaman tanpa peristiwa mitigasi dalam periode 10 menit. Aturan yang menggunakan kondisi tak terbatas disebut aturan ketiadaan.

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

Persyaratan untuk ketiadaan

Bagi aturan dengan ketiadaan untuk dikompilasi, aturan tersebut harus memenuhi persyaratan berikut:

  1. Setidaknya satu peristiwa UDM harus memiliki kondisi terbatas (artinya, minimal satu peristiwa UDM harus ada).
  2. Jika placeholder memiliki kondisi tidak terbatas, kondisi tersebut harus dikaitkan dengan setidaknya satu peristiwa UDM terbatas.
  3. Jika suatu entitas memiliki kondisi tidak terbatas, entitas tersebut harus dikaitkan dengan setidaknya satu peristiwa UDM terbatas.

Pertimbangkan aturan berikut dengan bagian kondisi dihilangkan:

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

Berikut adalah contoh yang valid untuk <condition_section>:

  • $u1 and !$u2 and $e1 and $e2
    • Semua peristiwa dan entity UDM ada di bagian kondisi.
    • Setidaknya satu peristiwa UDM dibatasi.
  • $u1 and !$u2 and $e1 and !$e2
    • $e2 tidak dibatasi, yang diizinkan karena terkait dengan $u1 yang dibatasi. Jika $e2 tidak dikaitkan dengan $u1, ini menjadi tidak valid.
  • #port > 50 and #ip = 0
    • Tidak ada peristiwa dan entity UDM di bagian kondisi; namun, placeholder yang ada mencakup semua peristiwa dan entity UDM.
    • $ip ditetapkan ke $u1 dan $u2, sedangkan #ip = 0 adalah kondisi tidak terbatas. Namun, kondisi terbatas lebih kuat daripada kondisi tidak terbatas. Karena $port ditetapkan ke $u1 dan #port > 50 adalah kondisi terikat, $u1 masih dibatasi.

Berikut adalah contoh yang tidak valid untuk <condition_section>:

  • $u1 and $e1
    • Setiap peristiwa dan entity UDM yang muncul di Bagian Peristiwa harus muncul di Bagian Kondisi (atau memiliki placeholder yang ditetapkan untuknya, yang muncul di Bagian Kondisi).
  • $u1, $u2, $e1, $u2, #port > 50
    • Koma tidak diizinkan sebagai pemisah kondisi.
  • !$u1 and !$u2 and $e1 and $e2
    • Melanggar persyaratan pertama bahwa minimal satu peristiwa UDM dibatasi.
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • Kata kunci or tidak didukung dengan kondisi tak terbatas.
  • ($u1 or $u2) and $e1 and $e2
    • Kata kunci or tidak didukung di antara variabel peristiwa yang berbeda.
  • not $u1 and $u2 and $e1 and $e2
    • Kata kunci not tidak diizinkan untuk kondisi peristiwa dan placeholder.
  • #port < 50 and #ip = 0
    • Placeholder yang ada mencakup semua peristiwa dan entity UDM; namun, semua kondisi tidak dibatasi. Artinya, tidak ada peristiwa UDM yang dibatasi, sehingga menyebabkan aturan gagal dikompilasi.

Kondisi hasil

Cantumkan predikat kondisi untuk variabel hasil di sini, digabungkan dengan kata kunci and atau or, atau diawali dengan kata kunci not.

Tentukan kondisional hasil secara berbeda, bergantung pada jenis variabel hasil:

  • integer: membandingkan dengan literal bilangan bulat dengan operator =, >, >=, <, <=, !=, misalnya:

    $risk_score > 10

  • float: membandingkan dengan literal float dengan operator =, >, >=, <, <=, !=, misalnya:

    $risk_score <= 5.5

  • string: membandingkan dengan literal string yang menggunakan = atau !=, misalnya:

    $severity = "HIGH"

  • daftar bilangan bulat atau array: tentukan kondisi menggunakan fungsi arrays.contains, misalnya:

    arrays.contains($event_ids, "id_1234")

Klasifikasi aturan

Menentukan kondisional hasil dalam aturan yang memiliki bagian kecocokan berarti bahwa aturan akan diklasifikasikan sebagai aturan multi-peristiwa untuk kuota aturan. Lihat aturan peristiwa tunggal dan beberapa aturan peristiwa untuk informasi selengkapnya tentang klasifikasi peristiwa tunggal dan beberapa.

Sintaksis bagian opsi

Di bagian options, Anda dapat menentukan opsi untuk aturan tersebut. Berikut adalah contoh cara menentukan bagian opsi:

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

Anda dapat menentukan opsi menggunakan sintaksis key = value, dengan key harus berupa nama opsi yang telah ditentukan sebelumnya, dan value harus berupa nilai yang valid untuk opsi tersebut, seperti yang ditentukan untuk opsi berikut:

allow_zero_values

Nilai yang valid untuk opsi ini adalah true dan false, yang menentukan apakah opsi ini diaktifkan atau tidak. Nilai defaultnya adalah false. Opsi ini dinonaktifkan jika tidak ditentukan dalam aturan.

Untuk mengaktifkan setelan ini, tambahkan opsi berikut ke bagian opsi aturan Anda: allow_zero_values = true. Tindakan ini akan mencegah aturan secara implisit memfilter nilai nol placeholder yang digunakan di bagian pencocokan, seperti yang dijelaskan dalam penanganan nilai nol di bagian pencocokan.

Ekspresi Boolean

Ekspresi Boolean adalah ekspresi dengan jenis boolean.

Perbandingan

Agar ekspresi biner sederhana dapat digunakan sebagai kondisi, gunakan sintaksis berikut:

  • <EXPR> <OP> <EXPR>

Ekspresi dapat berupa kolom peristiwa, variabel, literal, atau ekspresi fungsi.

Contoh:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

Jika kedua sisi literal, hal ini dianggap sebagai error kompilasi.

Functions

Beberapa ekspresi fungsi menampilkan nilai boolean, yang dapat digunakan sebagai predikat individual di bagian events. Fungsi tersebut adalah:

  • re.regex()
  • net.ip_in_range_cidr()

Contoh:

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Ekspresi daftar referensi

Anda dapat menggunakan daftar referensi di bagian peristiwa. Lihat bagian Daftar Referensi untuk mengetahui detail selengkapnya.

Ekspresi logika

Anda dapat menggunakan operator and yang logis dan or di bagian events seperti yang ditunjukkan dalam contoh berikut:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

Secara default, urutan prioritas dari yang tertinggi ke terendah adalah not, and, or.

Misalnya, "a atau b dan c" dievaluasi sebagai "a atau (b dan c)" jika operator or dan and ditentukan secara eksplisit dalam ekspresi.

Di bagian events, predikat digabungkan menggunakan operator and jika operator tidak ditentukan secara eksplisit.

Urutan evaluasi mungkin berbeda jika operator and tersirat dalam ekspresi.

Misalnya, pertimbangkan ekspresi perbandingan berikut dengan or ditentukan secara eksplisit. Operator and bersifat tersirat.

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

Contoh ini ditafsirkan sebagai berikut:

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

Karena or ditentukan secara eksplisit, predikat di sekitar or dikelompokkan dan dievaluasi terlebih dahulu. Predikat terakhir, $e2.field = "bar", digabungkan secara implisit menggunakan and. Hasilnya adalah urutan evaluasi berubah.

Jenis yang dihitung

Anda dapat menggunakan operator dengan jenis enumerasi. Hal ini dapat diterapkan pada aturan untuk menyederhanakan dan mengoptimalkan (gunakan operator, bukan daftar referensi) performa.

Dalam contoh berikut, 'USER_UNCATEGORIZED' dan 'USER_RESOURCE_DELETION' sesuai dengan 15000 dan 15014, sehingga aturan akan mencari semua peristiwa yang tercantum:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

Daftar peristiwa:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

Pengubah Tanpa Kasus

Jika memiliki ekspresi perbandingan antara nilai string atau ekspresi reguler, Anda dapat menambahkan nocase di akhir ekspresi untuk mengabaikan kapitalisasi.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

Parameter ini tidak dapat digunakan jika jenis kolom merupakan nilai yang dienumerasi. Contoh berikut tidak valid dan akan menghasilkan error kompilasi:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

Kolom berulang

Dalam Model Data Terpadu (UDM), beberapa kolom diberi label sebagai berulang, yang menunjukkan bahwa kolom tersebut merupakan daftar nilai atau jenis pesan lainnya.

Kolom berulang dan ekspresi boolean

Ada 2 jenis ekspresi boolean yang bekerja pada kolom berulang:

  1. Modified
  2. Tidak dimodifikasi

Pertimbangkan peristiwa berikut:

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

Ekspresi yang diubah

Bagian berikut menjelaskan tujuan dan cara menggunakan pengubah any dan all dalam ekspresi.

apa pun

Jika salah satu elemen dari kolom berulang memenuhi kondisi, peristiwa secara keseluruhan memenuhi kondisi tersebut.

  • event_original memenuhi any $e.principal.ip = "192.0.2.1".
  • event_original menggagalkan any $e.repeated_field.field_a = "9.9.9.9.
all

Jika semua elemen kolom berulang memenuhi kondisi, peristiwa secara keseluruhan memenuhi kondisi tersebut.

  • event_original memenuhi net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8").
  • event_original menggagalkan all $e.principal.ip = "192.0.2.2".

Saat menulis kondisi dengan any atau all, perhatikan bahwa meniadakan kondisi dengan not mungkin tidak memiliki arti yang sama seperti menggunakan operator yang diabaikan.

Contoh:

  • not all $e.principal.ip = "192.168.12.16" memeriksa apakah tidak semua alamat IP cocok dengan 192.168.12.16, yang berarti aturannya memeriksa apakah setidaknya satu alamat IP tidak cocok dengan 192.168.12.16.
  • all $e.principal.ip != "192.168.12.16" memeriksa apakah semua alamat IP tidak cocok dengan 192.168.12.16, yang berarti aturannya memeriksa bahwa tidak ada alamat IP yang cocok dengan 192.168.12.16.

Batasan:

  • Operator any dan all hanya kompatibel dengan kolom berulang (bukan kolom skalar).
  • any dan all tidak dapat digunakan untuk menggabungkan dua kolom berulang. Misalnya, any $e1.principal.ip = $e2.principal.ip tidak valid.
  • Operator any dan all tidak didukung dengan ekspresi daftar referensi.

Ekspresi yang tidak dimodifikasi

Dengan ekspresi yang tidak diubah, setiap elemen dalam kolom berulang diperlakukan satu per satu. Jika kolom berulang peristiwa berisi n elemen, aturan tersebut akan diterapkan pada n salinan peristiwa, dengan setiap salinan memiliki salah satu elemen dari kolom berulang. Salinan ini bersifat sementara dan tidak disimpan.

Aturan ini diterapkan pada salinan berikut:

salinan acara principal.ip principal.hostname
event_copy_1 "192.0.2.1" "host"
event_copy_2 "192.0.2.2" "host"
event_copy_3 "192.0.2.3" "host"

Jika salah satu salinan peristiwa memenuhi semua kondisi yang tidak diubah pada kolom berulang, peristiwa tersebut secara keseluruhan memenuhi semua kondisi. Artinya, jika Anda memiliki beberapa kondisi di kolom berulang, salinan peristiwa harus memenuhi semua kondisi tersebut. Contoh aturan berikut menggunakan contoh set data sebelumnya untuk menunjukkan perilaku ini.

Aturan berikut menampilkan satu kecocokan saat dijalankan terhadap set data contoh event_original, karena event_copy_1 memenuhi semua predikat peristiwa:

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

Aturan berikut tidak menampilkan kecocokan saat dijalankan terhadap set data contoh event_original, karena tidak ada salinan peristiwa di $e.principal.ip yang memenuhi semua predikat peristiwa.

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

Ekspresi yang diubah pada kolom berulang kompatibel dengan ekspresi yang tidak diubah di kolom berulang karena daftar elemen sama untuk setiap salinan peristiwa. Perhatikan aturan berikut:

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

Aturan ini diterapkan pada salinan berikut:

salinan acara principal.ip $e.Principal.ip apa pun
event_copy_1 "192.0.2.1" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_2 "192.0.2.2" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_3 "192.0.2.3" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]

Dalam hal ini, semua salinan memenuhi any $e.principal.ip = "192.0.2.1" tetapi hanya event_copy_3 yang memenuhi $e.principal.ip = "192.0.2.3". Hasilnya, peristiwa secara keseluruhan akan cocok.

Cara lain untuk mengenali jenis ekspresi ini adalah:

  • Ekspresi pada kolom berulang yang menggunakan any atau all beroperasi pada daftar di event_original.
  • Ekspresi di kolom berulang yang tidak menggunakan any atau all beroperasi pada peristiwa event_copy_n individual.

Kolom dan placeholder berulang

Kolom berulang berfungsi dengan penetapan placeholder. Serupa dengan ekspresi yang tidak dimodifikasi pada kolom berulang, salinan peristiwa dibuat untuk setiap elemen. Menggunakan contoh event_copy yang sama, placeholder mengambil nilai kolom berulang dari event_copy_n, untuk setiap salinan peristiwa dengan n sebagai nomor salinan peristiwa. Jika placeholder digunakan di bagian pencocokan, hal ini dapat menghasilkan beberapa kecocokan.

Contoh berikut menghasilkan satu kecocokan. Placeholder $ip sama dengan 192.0.2.1 untuk event_copy_1, yang memenuhi predikat dalam aturan. Contoh peristiwa pencocokan berisi satu elemen, event_original.

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

Contoh berikut menghasilkan tiga kecocokan. Placeholder $ip sama dengan nilai yang berbeda, untuk setiap salinan event_copy_n yang berbeda. Pengelompokan dilakukan di $ip karena berada di bagian pencocokan. Oleh karena itu, Anda akan mendapatkan tiga kecocokan dengan setiap kecocokan memiliki nilai berbeda untuk variabel pencocokan $ip. Setiap kecocokan memiliki contoh peristiwa yang sama: satu elemen, event_original.

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

Hasil yang menggunakan placeholder yang ditetapkan ke kolom berulang

Placeholder ditetapkan ke setiap elemen di setiap kolom berulang - bukan seluruh daftar. Oleh karena itu, ketika digunakan di bagian hasil, hasilnya dihitung hanya menggunakan elemen yang memenuhi bagian sebelumnya.

Perhatikan aturan berikut:

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

Ada 4 tahap eksekusi untuk aturan ini. Tahap pertama adalah penyalinan peristiwa:

salinan acara $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id
event_copy_3 "192.0.2.3" "host" event_id

Bagian peristiwa kemudian akan memfilter baris yang tidak cocok dengan filter:

salinan acara $ip $host $e
event_copy_1 "192.0.2.1" "host" event_id
event_copy_2 "192.0.2.2" "host" event_id

event_copy_3 difilter karena "192.0.2.3" tidak memenuhi $ip = "192.0.2.1" or $ip = "192.0.2.2".

Bagian pencocokan kemudian akan mengelompokkan menurut variabel yang cocok dan bagian hasilnya akan melakukan agregasi di setiap grup:

$host $o $e
"host" ["192.0.2.1", "192.0.2.2"] event_id

$o = array_distinct($ip) dihitung menggunakan $ip dari tahap sebelumnya dan bukan tahap penyalinan peristiwa.

Terakhir, bagian kondisi akan memfilter setiap grup. Karena aturan ini hanya memeriksa keberadaan $e, baris dari sebelumnya akan menghasilkan satu deteksi.

$o tidak berisi semua elemen dari $e.principal.ip karena tidak semua elemen memenuhi semua kondisi di bagian peristiwa. Namun, semua elemen e.principal.ip akan muncul dalam contoh peristiwa karena contoh peristiwa menggunakan event_original.

Pengindeksan array

Anda dapat melakukan pengindeksan array pada kolom berulang. Untuk mengakses elemen kolom berulang ke-n, gunakan sintaksis daftar standar (elemen diindeks 0). Elemen di luar batas menampilkan nilai default.

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" Jika ada kurang dari 1.000 elemen, nilai ini akan bernilai true.

Batasan:

  • Indeks harus berupa literal bilangan bulat non-negatif. Misalnya, $e.principal.ip[-1] tidak valid.
  • Nilai yang memiliki jenis int (misalnya, placeholder yang ditetapkan ke int) tidak dihitung.
  • Pengindeksan array tidak dapat digabungkan dengan any atau all. Misalnya, any $e.intermediary.ip[0] tidak valid.
  • Pengindeksan array tidak dapat digabungkan dengan sintaksis peta. Misalnya, $e.additional.fields[0]["key"] tidak valid.
  • Jika jalur kolom berisi beberapa kolom berulang, semua kolom berulang harus menggunakan pengindeksan array. Misalnya, $e.intermediary.ip[0] tidak valid karena intermediary dan ip adalah kolom berulang, tetapi hanya ada indeks untuk ip.

Pesan berulang

Jika kolom message diulang, efek yang tidak diinginkan adalah mengurangi kemungkinan kecocokan. Hal ini diilustrasikan dalam contoh berikut.

Pertimbangkan peristiwa berikut:

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

Seperti yang dinyatakan untuk ekspresi yang tidak diubah di kolom berulang, salinan sementara peristiwa akan dibuat untuk setiap elemen kolom berulang tersebut. Perhatikan aturan berikut:

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about.hostname = "bob"
  condition:
    $e
}

Aturan ini diterapkan pada salinan berikut:

salinan acara about.ip about.hostname
event_copy_1 "192.0.2.1" "alice"
event_copy_2 "192.0.2.2" "alice"
event_copy_3 "192.0.2.3" "alice"
event_copy_4 "" "bagus"

Peristiwa tidak cocok dengan aturan karena tidak ada salinan peristiwa yang memenuhi semua ekspresi.

Pengindeksan array dan pesan berulang

Perilaku tidak terduga lainnya dapat terjadi saat menggunakan pengindeksan array dengan ekspresi yang tidak dimodifikasi di kolom pesan berulang. Pertimbangkan contoh aturan berikut yang menggunakan pengindeksan array:

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about[1].hostname = "bob"
  condition:
    $e
}

Aturan ini diterapkan ke salinan berikut:

salinan acara about.ip about[1].nama host
event_copy_1 "192.0.2.1" "bagus"
event_copy_2 "192.0.2.2" "bagus"
event_copy_3 "192.0.2.3" "bagus"
event_copy_4 "" "bagus"

Karena event_copy_1 memenuhi semua ekspresi di repeated_message_2, peristiwa akan cocok dengan aturan.

Hal ini dapat menyebabkan perilaku yang tidak terduga karena aturan repeated_message_1 tidak memiliki pengindeksan array dan tidak menghasilkan kecocokan, sedangkan aturan repeated_message_2 menggunakan pengindeksan array dan menghasilkan kecocokan.

Komentar

Tetapkan komentar dengan dua karakter garis miring (// comment) atau komentar multi-baris yang diawali menggunakan karakter garis miring tanda bintang (/* comment */), seperti yang Anda lakukan di C.

Literal

Bilangan bulat nonnegatif dan literal float, string, boolean, dan ekspresi reguler didukung.

Literal ekspresi reguler dan string

Anda dapat menggunakan salah satu karakter kutip berikut untuk mengapit string di YARA-L 2.0. Namun, teks kutipan ditafsirkan secara berbeda bergantung pada teks yang Anda gunakan.

  1. Tanda kutip ganda (") — Gunakan untuk string normal. Harus menyertakan karakter escape.
    Misalnya: "hello\tworld" —\t diinterpretasikan sebagai tab

  2. Tanda kutip belakang (`) — Gunakan untuk menafsirkan semua karakter secara harfiah.
    Misalnya: `hello\tworld` —\t tidak diinterpretasikan sebagai tab

Untuk ekspresi reguler, Anda memiliki dua opsi.

Jika Anda ingin menggunakan ekspresi reguler secara langsung tanpa fungsi re.regex(), gunakan /regex/ untuk literal ekspresi reguler.

Anda juga dapat menggunakan literal string sebagai literal ekspresi reguler saat menggunakan fungsi re.regex(). Perhatikan bahwa untuk literal string tanda kutip ganda, Anda harus meng-escape karakter garis miring terbalik dengan karakter garis miring terbalik, yang dapat terlihat canggung.

Misalnya, ekspresi reguler berikut adalah setara:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

Google merekomendasikan penggunaan karakter tanda kutip belakang untuk string dalam ekspresi reguler agar lebih mudah dibaca.

Operator

Anda dapat menggunakan operator berikut di YARA-L:

Operator Deskripsi
= sama/deklarasi
!= tidak sama dengan
< kurang dari
<= kurang dari atau sama dengan
> lebih dari
>= lebih dari atau sama dengan

Variabel

Pada YARA-L 2.0, semua variabel direpresentasikan sebagai $<variable name>.

Anda dapat menentukan jenis variabel berikut:

  • Variabel peristiwa — Mewakili grup peristiwa dalam bentuk yang dinormalisasi (UDM) atau peristiwa entitas. Tentukan kondisi untuk variabel peristiwa di bagian events. Anda mengidentifikasi variabel peristiwa menggunakan kolom nama, sumber peristiwa, dan peristiwa. Sumber yang diizinkan adalah udm (untuk peristiwa yang dinormalkan) dan graph (untuk peristiwa entity). Jika sumber dihilangkan, udm akan ditetapkan sebagai sumber default. Kolom peristiwa direpresentasikan sebagai rantai .<nama kolom> (misalnya, $e.field1.field2). Rantai kolom peristiwa selalu dimulai dari sumber tingkat atas (UDM atau Entity).

  • Mencocokkan variabel — Deklarasikan di bagian match. Variabel pencocokan menjadi kolom pengelompokan untuk kueri, karena satu baris ditampilkan untuk setiap kumpulan variabel pencocokan yang unik (dan untuk setiap periode waktu). Jika aturan menemukan kecocokan, nilai variabel yang cocok akan ditampilkan. Tentukan apa yang diwakili oleh setiap variabel pencocokan di bagian events.

  • Variabel placeholder — Deklarasikan dan tentukan di bagian events. Variabel placeholder mirip dengan variabel pencocokan. Namun, Anda dapat menggunakan variabel placeholder di bagian condition untuk menentukan kondisi pencocokan.

Gunakan variabel pencocokan dan variabel placeholder untuk mendeklarasikan hubungan antara kolom peristiwa melalui kondisi gabungan transitif (lihat Sintaksis Bagian Peristiwa untuk detail selengkapnya).

Kata kunci

Kata kunci di YARA-L 2.0 tidak peka huruf besar/kecil. Misalnya, and atau AND setara. Nama variabel tidak boleh bertentangan dengan kata kunci. Misalnya, $AND atau $outcome tidak valid.

Berikut adalah kata kunci untuk aturan mesin deteksi: rule, meta, match, over, events, condition, outcome, options, and, or, not, nocase, in, regex, cidr, before, after, all, any, if, {2/0/}, match, match, match, {2.}maxminsumarrayarray_distinctcountcount_distinctisnull

Maps

YARA-L mendukung akses peta untuk Struct dan Label.

Struct dan Label

Beberapa kolom UDM menggunakan jenis data Struct atau Label.

Untuk menelusuri pasangan nilai kunci tertentu di Struct dan Label, gunakan sintaksis peta standar:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

Akses peta selalu menampilkan string.

Kasus yang didukung

Bagian Peristiwa dan Hasil
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Menetapkan nilai peta ke Placeholder
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Menggunakan kolom peta dalam kondisi gabungan
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

Kasus yang tidak didukung

Peta tidak didukung dalam kasus berikut.

Menggabungkan any atau all kata kunci dengan peta

Misalnya, kode berikut tidak didukung: all $e.udm.additional.fields["pod_name"] = "kube-scheduler"

Jenis nilai lainnya

Sintaksis peta hanya dapat menampilkan nilai string. Dalam kasus jenis data Struct, sintaksis peta hanya dapat mengakses kunci yang nilainya berupa string. Mengakses kunci yang nilainya adalah jenis primitif lain seperti bilangan bulat, tidak mungkin dilakukan.

Penanganan nilai duplikat

Akses peta selalu menampilkan satu nilai. Dalam kasus edge tidak umum yang dapat dirujuk oleh akses peta ke beberapa nilai, akses peta akan secara deterministik menampilkan nilai pertama.

Hal ini dapat terjadi dalam salah satu kasus berikut:

  • Label memiliki kunci duplikat.

    Struktur label mewakili peta, tetapi tidak menerapkan keunikan kunci. Berdasarkan konvensi, peta harus memiliki kunci unik, sehingga Chronicle tidak merekomendasikan pengisian label dengan kunci duplikat.

    Teks aturan $e.metadata.ingestion_labels["dupe-key"] akan menampilkan kemungkinan nilai pertama, val1, jika dijalankan pada contoh data berikut:

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • Label memiliki kolom berulang ancestor.

    Kolom berulang mungkin berisi label sebagai kolom turunan. Dua entri yang berbeda dalam kolom berulang di tingkat atas mungkin berisi label yang memiliki kunci yang sama. Teks aturan $e.security_result.rule_labels["key"] akan menampilkan kemungkinan nilai pertama, val3, jika dijalankan pada contoh data berikut:

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

Functions

Bagian ini menjelaskan fungsi YARA-L 2.0 yang didukung Chronicle di Detection Engine.

Fungsi ini dapat digunakan di area berikut dalam sebuah aturan:

arrays.length

arrays.length(repeatedField)

Deskripsi

Menampilkan jumlah elemen kolom berulang.

Jenis data parameter

LIST

Jenis hasil yang ditampilkan

NUMBER

Contoh Kode

Contoh 1

Menampilkan jumlah elemen kolom berulang.

arrays.length($e.principal.ip) = 2
Contoh 2

Jika beberapa kolom berulang berada di sepanjang jalur, menampilkan jumlah total elemen kolom berulang.

arrays.length($e.intermediary.ip) = 3

math.abs

math.abs(numericExpression)

Deskripsi

Menampilkan nilai absolut dari ekspresi bilangan bulat atau float.

Jenis data parameter

NUMBER

Jenis hasil yang ditampilkan

NUMBER

Contoh Kode

Contoh 1

Contoh ini menampilkan Benar jika peristiwa lebih dari 5 menit dari waktu yang ditentukan (dalam detik dari epoch Unix), terlepas dari apakah peristiwa terjadi sebelum atau setelah waktu yang ditentukan. Panggilan ke math.abs tidak dapat bergantung pada beberapa variabel atau placeholder. Misalnya, Anda tidak dapat mengganti nilai waktu hardcode 1643687343 dalam contoh berikut dengan $e2.metadata.event_timestamp.seconds.

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

metrics

Fungsi metrik dapat menggabungkan data historis dalam jumlah besar. Anda dapat menggunakannya pada aturan menggunakan metrics.functionName() di bagian hasil.

Untuk informasi selengkapnya, lihat Metrik YARA-L.

net.ip_in_range_cidr

net.ip_in_range_cidr(ipAddress, subnetworkRange)

Deskripsi

Menampilkan true saat alamat IP yang diberikan berada dalam subnetwork yang ditentukan.

Anda dapat menggunakan YARA-L untuk menelusuri peristiwa UDM di semua alamat IP dalam subnetwork, menggunakan pernyataan net.ip_in_range_cidr(). Mendukung IPv4 dan IPv6.

Untuk menelusuri berbagai alamat IP, tentukan kolom IP UDM dan rentang CIDR. YARA-L dapat menangani kolom alamat IP tunggal dan berulang.

Untuk melakukan penelusuran di berbagai alamat IP, tentukan kolom UDM ip dan rentang Classless Inter-Domain Routing (CIDR). YARA-L dapat menangani kolom alamat IP tunggal dan berulang.

Jenis data parameter

STRING, STRING

Jenis hasil yang ditampilkan

BOOL

Contoh kode

Contoh 1

Contoh IPv4:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Contoh 2

Contoh IPv6:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

Untuk contoh aturan yang menggunakan pernyataan net.ip_in_range_cidr(), lihat contoh aturan di Peristiwa Tunggal dalam Rentang Alamat IP.)

re.regex

Anda dapat menentukan pencocokan ekspresi reguler di YARA-L 2.0 menggunakan salah satu sintaksis berikut:

  • Menggunakan sintaksis YARA — Terkait dengan peristiwa. Berikut adalah representasi umum sintaksis ini: none $e.field = /regex/
  • Menggunakan sintaksis YARA-L — Sebagai fungsi yang mengambil parameter berikut:
    • Kolom tempat ekspresi reguler diterapkan.
    • Ekspresi reguler yang ditetapkan sebagai string. Anda dapat menggunakan pengubah nocase setelah string untuk menunjukkan bahwa penelusuran harus mengabaikan huruf besar. Berikut adalah representasi umum sintaksis ini: none re.regex($e.field, `regex`)

Deskripsi

Fungsi ini menampilkan true jika string berisi substring yang cocok dengan ekspresi reguler yang disediakan. Anda tidak perlu menambahkan .* di awal atau di akhir ekspresi reguler.

Notes
  • Agar cocok dengan string yang sama persis atau hanya awalan atau akhiran, sertakan karakter anchor ^ (awal) dan $ (akhir) dalam ekspresi reguler. Misalnya, /^full$/ sama persis dengan "full", sedangkan /full/ dapat cocok dengan "fullest", "lawfull", dan "joyfully".
  • Jika kolom UDM menyertakan karakter baris baru, regexp hanya cocok dengan baris pertama kolom UDM. Untuk menerapkan pencocokan kolom UDM penuh, tambahkan (?s) ke ekspresi reguler. Misalnya, ganti /.*allUDM.*/ dengan /(?s).*allUDM.*/.

Jenis data parameter

STRING, STRING

Jenis ekspresi parameter

ANY, ANY

Jenis hasil yang ditampilkan

BOOL

Contoh Kode

Contoh 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

re.capture(stringText, regex)

Deskripsi

Mengambil (mengekstrak) data dari string menggunakan pola ekspresi reguler yang diberikan dalam argumen.

Fungsi ini menggunakan dua argumen:

  • stringText: string asli yang akan ditelusuri.
  • regex: ekspresi reguler yang menunjukkan pola yang akan ditelusuri.

Ekspresi reguler dapat berisi 0 atau 1 grup tangkapan dalam tanda kurung. Jika ekspresi reguler berisi 0 grup tangkapan, fungsi tersebut akan menampilkan seluruh substring pertama yang cocok. Jika ekspresi reguler berisi 1 grup tangkapan, substring pertama yang cocok untuk grup tangkapan akan ditampilkan. Menentukan dua atau beberapa grup tangkapan akan menampilkan error compiler.

Jenis data parameter

STRING, STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Dalam contoh ini, jika $e.principal.hostname berisi "aaa1bbaa2", hal berikut akan berlaku karena fungsi tersebut menampilkan instance pertama. Contoh ini tidak memiliki grup tangkapan.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
Contoh 2

Contoh ini mencatat apa pun setelah simbol @ dalam email. Jika kolom $e.network.email.from adalah test@google.com, contoh akan menampilkan google.com. Contoh berikut berisi satu grup tangkapan.

"google.com" = re.capture($e.network.email.from , "@(.*)")
Contoh 3

Jika ekspresi reguler tidak cocok dengan substring apa pun dalam teks, fungsi akan menampilkan string kosong. Anda dapat menghilangkan peristiwa yang tidak memiliki kecocokan dengan mengecualikan string kosong. Hal ini akan sangat penting saat Anda menggunakan re.capture() dengan ketidaksetaraan:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

re.replace(stringText, replaceRegex, replacementText)

Deskripsi

Melakukan penggantian ekspresi reguler.

Fungsi ini menggunakan tiga argumen:

  • stringText: string asli.
  • replaceRegex: ekspresi reguler yang menunjukkan pola yang akan ditelusuri.
  • replacementText: Teks yang akan disisipkan ke setiap kecocokan.

Menampilkan string baru yang berasal dari stringText asli, dengan semua substring yang cocok dengan pola di replaceRegex diganti dengan nilai dalam replacementText. Anda dapat menggunakan digit yang di-escape garis miring terbalik (\1 hingga \9) dalam replacementText untuk menyisipkan teks yang cocok dengan grup dalam tanda kurung yang sesuai dalam pola replaceRegex. Gunakan \0 untuk merujuk ke seluruh teks yang cocok.

Fungsi ini menggantikan pencocokan yang tidak tumpang-tindih dan akan memprioritaskan penggantian kemunculan pertama yang ditemukan. Misalnya, re.replace("banana", "ana", "111") menampilkan string "b111na".

Jenis data parameter

STRING, STRING, STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Contoh ini mengambil semua objek setelah simbol @ dalam email, mengganti com dengan org, lalu menampilkan hasilnya. Perhatikan penggunaan fungsi tersarang.

"email@google.org" = re.replace($e.network.email.from, "com", "org")
Contoh 2

Contoh ini menggunakan digit yang di-escape garis miring terbalik dalam argumen replacementText untuk mereferensikan kecocokan dengan pola replaceRegex.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
Contoh 3

Perhatikan kasus berikut saat menangani string kosong dan re.replace():

Menggunakan string kosong sebagai replaceRegex:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

Untuk mengganti string kosong, Anda dapat menggunakan "^$" sebagai replaceRegex:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

strings.base64_decode

strings.base64_decode(encodedString)

Deskripsi

Menampilkan string yang berisi versi yang didekode base64 dari string yang dienkode.

Fungsi ini mengambil satu string berenkode base64 sebagai argumen. Jika encodedString bukan string berenkode base64 yang valid, fungsi akan menampilkan encodedString yang tidak berubah.

Jenis data parameter

STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

strings.coalesce(a, b, c, ...)

Deskripsi

Fungsi ini mengambil argumen dalam jumlah yang tidak terbatas dan menampilkan nilai ekspresi pertama yang tidak dievaluasi ke string kosong (misalnya, "nilai bukan nol"). Jika semua argumen dievaluasi ke string kosong, panggilan fungsi akan mengembalikan string kosong.

Argumen bisa berupa literal, kolom peristiwa, atau panggilan fungsi. Semua argumen harus berjenis STRING. Jika ada argumen yang berupa kolom peristiwa, atributnya harus berasal dari peristiwa yang sama.

Jenis data parameter

STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Contoh berikut menyertakan variabel string sebagai argumen. Kondisi ini dievaluasi ke benar (true) jika (1) $e.network.email.from adalah suspicious@gmail.com atau (2) $e.network.email.from kosong dan $e.network.email.to adalah suspicious@gmail.com.

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
Contoh 2

Contoh berikut memanggil fungsi coalesce dengan lebih dari dua argumen. Kondisi ini membandingkan alamat IP non-null pertama dari peristiwa $e dengan nilai dalam daftar referensi ip_watchlist. Urutan argumen yang digabungkan dalam panggilan ini sama dengan urutan enumerasinya dalam kondisi aturan:

  1. $e.principal.ip dievaluasi terlebih dahulu.
  2. $e.src.ip akan dievaluasi berikutnya.
  3. $e.target.ip akan dievaluasi berikutnya.
  4. Terakhir, string "Tidak ada IP" akan ditampilkan sebagai nilai default jika kolom ip sebelumnya tidak disetel.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
Contoh 3

Contoh berikut mencoba menggabungkan principal.hostname dari peristiwa $e1 dan peristiwa $e2. Error compiler akan ditampilkan karena argumennya adalah variabel peristiwa yang berbeda.

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

strings.concat(a, b, c, ...)

Deskripsi

Menampilkan penyambungan item dengan jumlah yang tidak terbatas, yang masing-masing dapat berupa string, bilangan bulat, atau float.

Jika ada argumen yang berupa kolom peristiwa, atributnya harus berasal dari peristiwa yang sama.

Jenis data parameter

STRING, FLOAT, INT

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Contoh berikut menyertakan variabel string dan variabel bilangan bulat sebagai argumen. principal.hostname dan principal.port berasal dari peristiwa yang sama, $e, dan digabungkan untuk menampilkan string.

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
Contoh 2

Contoh berikut menyertakan variabel string dan literal string sebagai argumen.

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
Contoh 3

Contoh berikut menyertakan variabel string dan literal float sebagai argumen. Jika direpresentasikan sebagai string, float yang merupakan bilangan bulat diformat tanpa titik desimal (misalnya, 1,0 direpresentasikan sebagai "1"). Selain itu, float yang melebihi enam belas digit desimal terpotong ke tempat desimal keenam belas.

"google2.5" = strings.concat($e.principal.hostname, 2.5)
Contoh 4

Contoh berikut mencakup variabel string, literal string, variabel bilangan bulat, dan literal float sebagai argumen. Semua variabel berasal dari peristiwa yang sama, $e, dan digabungkan dengan literal untuk menampilkan string.

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
Contoh 5

Contoh berikut mencoba menyambungkan principal.port dari peristiwa $e1, dengan principal.hostname dari peristiwa $e2. Error compiler akan ditampilkan karena argumennya adalah variabel peristiwa yang berbeda.

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.to_lower

strings.to_lower(stringText)

Deskripsi

Fungsi ini mengambil string input dan menampilkan string setelah mengubah semua karakter menjadi huruf kecil

Jenis data parameter

STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Contoh berikut menampilkan true.

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

strings.to_upper(stringText)

Deskripsi

Fungsi ini mengambil string input dan menampilkan string setelah mengubah semua karakter menjadi huruf kapital

Jenis data parameter

STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Contoh berikut menampilkan true.

"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

timestamp.current_seconds

timestamp.current_seconds()

Deskripsi

Menampilkan bilangan bulat yang mewakili waktu saat ini dalam detik Unix. Waktu ini kira-kira sama dengan stempel waktu deteksi dan didasarkan pada waktu aturan dijalankan.

Jenis data parameter

NONE

Jenis hasil yang ditampilkan

INT

Contoh Kode

Contoh 1

Contoh berikut menampilkan true jika masa berlaku sertifikat telah berakhir selama lebih dari 24 jam. Metode ini menghitung perbedaan waktu dengan mengurangi detik Unix saat ini, lalu membandingkan menggunakan operator lebih besar dari.

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

timestamp.get_date(unix_seconds [, time_zone])

Deskripsi

Fungsi ini menampilkan string dalam format YYYY-MM-DD, yang mewakili hari saat stempel waktu berada.

  • unix_seconds adalah bilangan bulat yang mewakili jumlah detik setelah epoch Unix, seperti $e.metadata.event_timestamp.seconds, atau placeholder yang berisi nilai tersebut.
  • time_zone bersifat opsional dan merupakan string yang mewakili zona waktu. Jika dihapus, setelan defaultnya adalah "GMT". Anda dapat menentukan zona waktu menggunakan literal string. Opsinya adalah:
    • Nama database TZ, misalnya "America/Los_Angeles". Untuk informasi selengkapnya, lihat kolom"TZ Database Name" dari halaman ini
    • Offset zona waktu dari UTC, dalam format (+|-)H[H][:M[M]], misalnya: "-08:00".

Berikut adalah contoh penentu time_zone yang valid, yang dapat Anda teruskan sebagai argumen kedua ke fungsi ekstraksi waktu:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Jenis data parameter

INT, STRING

Jenis hasil yang ditampilkan

STRING

Contoh Kode

Contoh 1

Dalam contoh ini, argumen time_zone dihilangkan, sehingga default-nya adalah "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
Contoh 2

Contoh ini menggunakan literal string untuk menentukan time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

timestamp.get_minute(unix_seconds [, time_zone])

Deskripsi

Fungsi ini menampilkan bilangan bulat dalam rentang [0, 59] yang mewakili menit.

  • unix_seconds adalah bilangan bulat yang mewakili jumlah detik setelah epoch Unix, seperti $e.metadata.event_timestamp.seconds, atau placeholder yang berisi nilai tersebut.
  • time_zone bersifat opsional dan merupakan string yang mewakili zona waktu. Jika dihapus, setelan defaultnya adalah "GMT". Anda dapat menentukan zona waktu menggunakan literal string. Opsinya adalah:
    • Nama database TZ, misalnya "America/Los_Angeles". Untuk informasi selengkapnya, lihat kolom"TZ Database Name" dari halaman ini
    • Offset zona waktu dari UTC, dalam format (+|-)H[H][:M[M]], misalnya: "-08:00".

Berikut adalah contoh penentu time_zone yang valid, yang dapat Anda teruskan sebagai argumen kedua ke fungsi ekstraksi waktu:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Jenis data parameter

INT, STRING

Jenis hasil yang ditampilkan

INT

Contoh Kode

Contoh 1

Dalam contoh ini, argumen time_zone dihilangkan, sehingga default-nya adalah "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Contoh 2

Contoh ini menggunakan literal string untuk menentukan time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

timestamp.get_hour(unix_seconds [, time_zone])

Deskripsi

Fungsi ini menampilkan bilangan bulat dalam rentang [0, 23] yang mewakili jam.

  • unix_seconds adalah bilangan bulat yang mewakili jumlah detik setelah epoch Unix, seperti $e.metadata.event_timestamp.seconds, atau placeholder yang berisi nilai tersebut.
  • time_zone bersifat opsional dan merupakan string yang mewakili zona waktu. Jika dihapus, setelan defaultnya adalah "GMT". Anda dapat menentukan zona waktu menggunakan literal string. Opsinya adalah:
    • Nama database TZ, misalnya "America/Los_Angeles". Untuk informasi selengkapnya, lihat kolom"TZ Database Name" dari halaman ini
    • Offset zona waktu dari UTC, dalam format (+|-)H[H][:M[M]], misalnya: "-08:00".

Berikut adalah contoh penentu time_zone yang valid, yang dapat Anda teruskan sebagai argumen kedua ke fungsi ekstraksi waktu:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Jenis data parameter

INT, STRING

Jenis hasil yang ditampilkan

INT

Contoh Kode

Contoh 1

Dalam contoh ini, argumen time_zone dihilangkan, sehingga default-nya adalah "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Contoh 2

Contoh ini menggunakan literal string untuk menentukan time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

timestamp.get_day_of_week(unix_seconds [, time_zone])

Deskripsi

Fungsi ini menampilkan bilangan bulat dalam rentang [1, 7] yang mewakili hari dalam seminggu yang dimulai pada hari Minggu. Misalnya, 1 = Minggu dan 2 = Senin.

  • unix_seconds adalah bilangan bulat yang mewakili jumlah detik setelah epoch Unix, seperti $e.metadata.event_timestamp.seconds, atau placeholder yang berisi nilai tersebut.
  • time_zone bersifat opsional dan merupakan string yang mewakili zona waktu. Jika dihapus, setelan defaultnya adalah "GMT". Anda dapat menentukan zona waktu menggunakan literal string. Opsinya adalah:
    • Nama database TZ, misalnya "America/Los_Angeles". Untuk informasi selengkapnya, lihat kolom"TZ Database Name" dari halaman ini
    • Offset zona waktu dari UTC, dalam format (+|-)H[H][:M[M]], misalnya: "-08:00".

Berikut adalah contoh penentu time_zone yang valid, yang dapat Anda teruskan sebagai argumen kedua ke fungsi ekstraksi waktu:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Jenis data parameter

INT, STRING

Jenis hasil yang ditampilkan

INT

Contoh Kode

Contoh 1

Dalam contoh ini, argumen time_zone dihilangkan, sehingga default-nya adalah "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
Contoh 2

Contoh ini menggunakan literal string untuk menentukan time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_week

timestamp.get_week(unix_seconds [, time_zone])

Deskripsi

Fungsi ini menampilkan bilangan bulat dalam rentang [0, 53] yang mewakili minggu dalam setahun. Minggu dimulai pada hari Minggu. Tanggal sebelum hari Minggu pertama setiap tahun adalah minggu 0.

  • unix_seconds adalah bilangan bulat yang mewakili jumlah detik setelah epoch Unix, seperti $e.metadata.event_timestamp.seconds, atau placeholder yang berisi nilai tersebut.
  • time_zone bersifat opsional dan merupakan string yang mewakili zona waktu. Jika dihapus, setelan defaultnya adalah "GMT". Anda dapat menentukan zona waktu menggunakan literal string. Opsinya adalah:
    • Nama database TZ, misalnya "America/Los_Angeles". Untuk informasi selengkapnya, lihat kolom"TZ Database Name" dari halaman ini
    • Offset zona waktu dari UTC, dalam format (+|-)H[H][:M[M]], misalnya: "-08:00".

Berikut adalah contoh penentu time_zone yang valid, yang dapat Anda teruskan sebagai argumen kedua ke fungsi ekstraksi waktu:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Jenis data parameter

INT, STRING

Jenis hasil yang ditampilkan

INT

Contoh Kode

Contoh 1

Dalam contoh ini, argumen time_zone dihilangkan, sehingga default-nya adalah "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
Contoh 2

Contoh ini menggunakan literal string untuk menentukan time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

Fungsi ke penetapan placeholder

Anda dapat menetapkan hasil panggilan fungsi ke placeholder di bagian events. Contoh:

$placeholder = strings.concat($e.principal.hostname, "my-string").

Anda kemudian dapat menggunakan variabel placeholder di bagian match, condition, dan outcome. Namun, ada dua batasan fungsi untuk penetapan placeholder:

  1. Setiap placeholder dalam fungsi untuk penetapan placeholder harus ditetapkan ke ekspresi yang berisi kolom peristiwa. Misalnya, contoh berikut ini valid:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    Namun, contoh berikut tidak valid:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. Panggilan fungsi harus bergantung pada satu dan satu peristiwa. Namun, lebih dari satu kolom dari peristiwa yang sama dapat digunakan dalam argumen panggilan fungsi. Misalnya, nilai berikut ini valid:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    Namun, hal berikut tidak valid:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

Sintaksis Daftar Referensi

Lihat halaman tentang Daftar Referensi untuk mengetahui informasi lebih lanjut tentang perilaku daftar referensi dan sintaksis daftar referensi.

Anda dapat menggunakan daftar referensi di bagian events atau outcome. Berikut adalah sintaksis untuk menggunakan berbagai jenis daftar referensi dalam aturan:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

Anda juga dapat menggunakan operator not dan operator nocase dengan daftar referensi seperti yang ditampilkan di sini: ```none // Kecualikan peristiwa yang nama hostnya cocok dengan substring di my_regex_list. bukan $e.principal.Hostname di ekspresi reguler %my_regex_list

// Nama host peristiwa harus cocok dengan minimal 1 string di my_string_list (tidak peka huruf besar/kecil). $e.principal.nama host di %my_string_list nocase ```

Operator nocase kompatibel dengan daftar STRING dan daftar REGEX.

Untuk alasan performa, Detection Engine membatasi penggunaan daftar referensi.

  • Maksimum pernyataan in dalam aturan, dengan atau tanpa operator khusus: 7
  • Pernyataan in maksimum dengan operator regex: 4
  • Pernyataan in maksimum dengan operator cidr: 2

Pemeriksaan jenis

Chronicle melakukan pemeriksaan jenis terhadap sintaksis YARA-L saat Anda membuat aturan dalam antarmuka. Kesalahan pemeriksaan jenis yang ditampilkan membantu Anda merevisi aturan sedemikian rupa untuk memastikan bahwa aturan akan berfungsi seperti yang diharapkan.

Berikut adalah contoh predikat tidak valid:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

Pengambilan Sampel Peristiwa Deteksi

Deteksi dari aturan multi-peristiwa berisi sampel peristiwa untuk memberikan konteks tentang peristiwa yang menyebabkan deteksi. Ada batas maksimal 10 contoh peristiwa untuk setiap variabel peristiwa yang ditentukan dalam aturan. Misalnya, jika aturan menentukan 2 variabel peristiwa, setiap deteksi dapat memiliki hingga 20 sampel peristiwa. Batas ini berlaku untuk setiap variabel peristiwa secara terpisah. Jika satu variabel peristiwa memiliki 2 peristiwa yang berlaku dalam deteksi ini, dan variabel peristiwa lainnya memiliki 15 peristiwa yang berlaku, deteksi yang dihasilkan akan berisi 12 sampel peristiwa (2 + 10).

Sampel peristiwa apa pun yang melebihi batas akan dihilangkan dari deteksi.

Jika ingin mengetahui informasi selengkapnya tentang peristiwa yang menyebabkan deteksi, Anda dapat menggunakan agregasi di bagian hasil untuk menghasilkan informasi tambahan dalam deteksi Anda.

Jika melihat deteksi di UI, Anda dapat mendownload semua contoh peristiwa untuk dideteksi. Untuk informasi selengkapnya, lihat Mendownload peristiwa.