Ekspresi, operator, dan konstruksi lainnya

Didukung di:

Dokumen ini berisi informasi untuk membantu Anda membuat aturan dan kueri YARA-L menggunakan ekspresi.

Ekspresi Boolean

Ekspresi Boolean adalah ekspresi dengan jenis boolean, yang mencakup ekspresi perbandingan, ekspresi fungsi, dan ekspresi daftar referensi atau tabel data. Anda dapat menggunakan ekspresi boolean di bagian events dan outcome dalam aturan atau kueri YARA-L.

Ekspresi perbandingan

Ekspresi perbandingan adalah ekspresi yang menerapkan operator perbandingan ke dua ekspresi. Ekspresi dapat berupa kolom peristiwa, variabel, literal, atau ekspresi fungsi.

Contoh: Ekspresi perbandingan

$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")

Ekspresi fungsi

Beberapa ekspresi fungsi menampilkan nilai boolean, yang dapat digunakan sebagai predikat individual di bagian events, seperti:

re.regex()

net.ip_in_range_cidr()

Contoh: Ekspresi fungsi

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

Daftar referensi atau tabel data

Anda dapat menggunakan daftar referensi atau tabel data di bagian events atau outcome. Lihat Daftar referensi dan Menggunakan tabel data untuk mengetahui informasi selengkapnya tentang perilaku dan sintaksis daftar referensi dan tabel data.

Contoh: Sintaksis untuk daftar referensi

Contoh berikut menunjukkan sintaksis untuk berbagai jenis daftar referensi dalam kueri:

// 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

Contoh: Sintaks untuk tabel data

// STRING data table
$e.target.hostname in %data_table_name.column_name

// REGEX data table
$e.target.hostname in regex %regex_table_name.column_name

// CIDR data table
$e.principal.ip in cidr %cidr_table_name.column_name

Contoh: Menggunakan not dan nocase dalam sintaksis daftar referensi

// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list

// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase

Operator nocase kompatibel dengan daftar STRING dan daftar REGEX.

Untuk alasan performa, penggunaan daftar referensi dan tabel data memiliki batasan berikut:

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

Ekspresi logis

Anda dapat menggunakan operator logis and dan or di bagian events.

Contoh: Ekspresi logis

$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 tertinggi ke terendah adalah not, and, or. Misalnya, "a or b and c" dievaluasi sebagai "a or (b and c)" saat 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. Pertimbangkan ekspresi perbandingan berikut yang or-nya ditentukan secara eksplisit dan operator and-nya tersirat.

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

Hal ini ditafsirkan sebagai berikut:

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

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

Jenis yang di-enum

Anda dapat menggunakan operator dengan jenis yang di-enum. Dapat diterapkan ke aturan untuk menyederhanakan dan mengoptimalkan (menggunakan 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"

Pengubah Nocase

Untuk mengabaikan kapitalisasi dalam ekspresi perbandingan antara nilai string atau ekspresi reguler, tambahkan nocase di akhir ekspresi seperti yang ditunjukkan dalam contoh berikut.

Contoh: pengubah nocase

$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

Pengubah nocase tidak dapat digunakan jika jenis kolom adalah nilai yang di-enum. Contoh berikut tidak valid dan akan menghasilkan error kompilasi:

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

Komentar

Komentar dapat digunakan dalam kueri untuk memberikan informasi lebih lanjut. Anda menggunakan karakter garis miring untuk menunjukkan komentar:

  • Untuk komentar satu baris, gunakan dua karakter garis miring (// comment).
  • Untuk komentar multi-baris, gunakan satu karakter garis miring dan karakter tanda bintang (/* comment */).

Literal

YARA-L mendukung bilangan bulat dan float non-negatif, string, boolean, dan literal ekspresi reguler. Literal adalah nilai tetap yang digunakan dalam kondisi kueri. YARA-L juga menggunakan konstruksi seperti literal lainnya, seperti ekspresi reguler (yang diapit garis miring) untuk pencocokan pola dan boolean (benar/salah) untuk logika.

Literal string

Literal string adalah urutan karakter yang diapit dalam tanda kutip ganda (") atau tanda kutip terbalik (`). String ditafsirkan secara berbeda, bergantung pada jenis tanda kutip yang Anda gunakan:

  • Tanda petik ganda ("hello\tworld"): Gunakan untuk string normal; karakter escape harus disertakan, dengan \t diinterpretasikan sebagai tab.
  • Kutip balik (`hello\tworld`): Gunakan saat semua karakter harus diinterpretasikan secara harfiah, dengan \t tidak diinterpretasikan sebagai tab.

Literal ekspresi reguler

Untuk literal ekspresi reguler, Anda memiliki dua opsi:

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

  • Jika Anda ingin menggunakan literal string sebagai literal ekspresi reguler, gunakan 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 mungkin terlihat aneh.

Contoh berikut menunjukkan ekspresi reguler yang 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 kutipan terbalik untuk string dalam ekspresi reguler agar lebih mudah dibaca.

Operator

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

Variabel

Di YARA-L, semua variabel menggunakan sintaksis $<variable name>. Jenis variabel berikut dapat digunakan di YARA-L.

Variabel peristiwa

Variabel peristiwa mewakili grup peristiwa atau peristiwa entitas. Anda menentukan kondisi untuk variabel peristiwa di bagian events menggunakan nama, sumber peristiwa, dan kolom peristiwa.

  • Sumber peristiwa adalah udm (untuk peristiwa yang dinormalisasi) dan graph (untuk peristiwa entitas). Jika sumber tidak disertakan, udm akan ditetapkan sebagai sumber default.

  • Kolom peristiwa ditampilkan sebagai rangkaian .<field name> (misalnya, $e.field1.field2) dan rangkaian kolom selalu dimulai dari sumber tingkat teratas (UDM atau Entitas).

Variabel kecocokan

Variabel kecocokan digunakan di bagian match untuk mengelompokkan peristiwa berdasarkan nilai umum dalam jangka waktu yang ditentukan.

Kolom tersebut menjadi kolom pengelompokan untuk kueri, karena satu baris ditampilkan untuk setiap set unik variabel kecocokan (dan untuk setiap jangka waktu). Jika kueri menemukan kecocokan, nilai variabel kecocokan akan ditampilkan.

Anda menentukan apa yang diwakili oleh setiap variabel kecocokan di bagian events.

Variabel placeholder

Variabel placeholder digunakan untuk mengambil dan menyimpan nilai tertentu dari kolom peristiwa UDM yang akan dirujuk dan digunakan di seluruh kueri. ID ini digunakan untuk menautkan peristiwa yang berbeda, terutama dalam kueri multi-peristiwa. Dengan menetapkan nilai umum (misalnya, userid atau hostname) ke placeholder, Anda kemudian dapat menggunakan placeholder ini di bagian match untuk mengelompokkan peristiwa yang memiliki nilai tersebut dalam jangka waktu tertentu.

Anda menentukan variabel placeholder di bagian events dengan menetapkan nilai kolom UDM ke nama variabel yang diawali dengan $ (misalnya: $targetUser = $e.target.user.userid).

Anda juga dapat menentukan variabel placeholder di bagian berikut:

  • condition untuk menentukan kondisi pencocokan.
  • outcome untuk melakukan penghitungan, menentukan metrik, atau mengekstrak titik data tertentu dari peristiwa yang cocok.
  • Bagian match untuk mengelompokkan peristiwa menurut nilai umum.

Kata kunci

Di YARA-L, kata kunci adalah kata-kata khusus yang menentukan struktur dan logika kueri deteksi. Bagian ini digunakan untuk menentukan berbagai bagian kueri, melakukan operasi logis dan matematika, serta menentukan kondisi untuk mencocokkan peristiwa. Kata kunci ini tidak dapat digunakan sebagai ID untuk kueri, string, atau variabel.

Kata kunci tidak peka huruf besar/kecil (misalnya, and atau AND adalah sama).

Kategori utama kata kunci YARA-L 2.0

Daftar ini tidak lengkap, tetapi mencakup kata kunci utama yang digunakan di YARA-L 2.0 untuk membuat kueri deteksi yang andal.

  • Definisi kueri:
    • rule: Memulai definisi kueri YARA-L baru.
    • private: Menetapkan kueri sebagai pribadi, sehingga tidak dapat diekspos atau dipicu secara langsung dari luar.
    • global: Menandai kueri sebagai global, yang menunjukkan bahwa kueri tersebut harus diterapkan secara luas.
  • Bagian kueri:
    • meta: Memperkenalkan bagian metadata untuk informasi deskriptif tentang kueri.
    • strings: Menunjukkan bagian tempat pola string ditentukan.
    • condition: Menentukan bagian yang berisi logika boolean untuk pemicuan kueri.
    • events: Menentukan bagian untuk menentukan variabel peristiwa dan kondisinya.
    • match: Memperkenalkan bagian untuk menggabungkan nilai selama jangka waktu tertentu.
    • outcome: Menentukan bagian untuk menambahkan konteks dan pemberian skor ke kueri yang dipicu.
  • Pengubah string:
    • ascii: Menentukan bahwa string harus dicocokkan sebagai teks ASCII.
    • wide: Menunjukkan bahwa string harus dicocokkan sebagai karakter lebar (UTF-16).
    • nocase: Melakukan pencocokan string yang tidak peka huruf besar/kecil.
    • fullword: Mewajibkan string cocok sebagai kata lengkap.
    • xor: Menerapkan transformasi XOR ke string sebelum mencocokkan.
    • base64, base64wide: Menerapkan encoding Base64 sebelum mencocokkan.
  • Operator logika:
    • and, or, not: Operator logika boolean standar untuk menggabungkan kondisi.
    • all of, any of: Digunakan untuk mengevaluasi beberapa ekspresi dalam suatu kondisi.
  • Operator perbandingan dan relasional:
    • at: Menentukan offset yang tepat untuk pencocokan string.
    • contains: Memeriksa apakah string berisi substring.
    • startswith, endswith: Memeriksa apakah string diawali atau diakhiri dengan substring.
    • icontains, istartswith, iendswith, iequals: Versi yang tidak peka huruf besar/kecil.
    • matches: Digunakan untuk pencocokan ekspresi reguler.
  • Jenis data dan penentu ukuran:
    • int8, uint8, int16, uint16, int32, uint32: Jenis bilangan bulat dengan ukuran yang ditentukan.
    • int8be, uint8be, int16be, uint16be, int32be, uint32be: Versi big-endian dari jenis bilangan bulat.
    • filesize: Merepresentasikan ukuran file yang sedang dianalisis.
    • entrypoint: Merujuk ke titik entri yang dapat dieksekusi.

Maps

YARA-L mendukung peta untuk jenis data Struct dan Label, yang digunakan di beberapa kolom UDM.

Untuk menelusuri pasangan nilai kunci tertentu dalam jenis data Struct dan Label, gunakan sintaks peta standar:

  • Sintaksis kolom struct: $e.udm.additional.fields["pod_name"] = "kube-scheduler"
  • Sintaksis kolom label: $e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

Contoh: Penggunaan peta yang valid dan tidak valid

Contoh berikut menunjukkan penggunaan peta yang valid dan tidak valid.

Penggunaan peta yang valid

Menggunakan kolom Struct di bagian peristiwa:

events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"
  

Menggunakan kolom Label di bagian hasil:

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"]

Penggunaan peta yang tidak didukung

Menggabungkan kata kunci any atau all dengan peta

all $e.udm.additional.fields["pod_name"] = "kube-scheduler"

Jenis nilai lainnya

Sintaks peta hanya dapat menampilkan nilai string. Dalam kasus jenis data [Struct](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct), sintaksis peta hanya dapat mengakses kunci yang nilainya berupa string. Mengakses kunci yang nilainya berupa jenis primitif lain seperti bilangan bulat tidak dapat dilakukan.

Penanganan nilai duplikat dalam peta

Akses peta dimaksudkan untuk mengambil satu nilai yang terkait dengan kunci tertentu. Ini adalah perilaku standar dan yang diharapkan. Namun, dalam situasi yang jarang terjadi, konteks map access mungkin secara tidak sengaja mengarah ke beberapa nilai. Dalam kasus ekstrem yang tidak umum ketika akses peta merujuk ke beberapa nilai, map access akan secara deterministik menampilkan nilai pertama. Hal ini dapat terjadi jika label memiliki kunci duplikat atau label memiliki kolom berulang ancestor.

Label memiliki kunci duplikat

Struktur label merepresentasikan peta, tetapi tidak menerapkan keunikan kunci. Menurut konvensi, peta harus memiliki kunci unik, sehingga Google SecOps tidak merekomendasikan pengisian label dengan kunci duplikat.

Contoh: Label dengan kunci duplikat

Teks kueri $e.metadata.ingestion_labels["dupe-key"] akan menampilkan nilai pertama yang mungkin, 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 dapat berisi label sebagai kolom turunan. Dua entri berbeda dalam kolom berulang tingkat teratas dapat berisi label yang memiliki kunci yang sama.

Contoh: Label dengan kolom berulang ancestor

Teks kueri $e.security_result.rule_labels["key"] akan menampilkan nilai pertama yang mungkin, `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"
        }
      }
    }
  

Mengakses variabel hasil dalam peta

Bagian ini menjelaskan cara mengakses variabel hasil dalam peta sebagai jenis data aslinya (misalnya, bilangan bulat, boolean, atau daftar jenis ini), bukan hanya string. Anda dapat menggunakan fungsi ini untuk mendapatkan fleksibilitas dan akurasi yang lebih baik untuk logika kueri Anda.

Data hasil tersedia di kolom berikut:

  • Nilai hasil mempertahankan jenis aslinya di kolom variables.
  • Kolom outcomes menyimpan versi string untuk kompatibilitas mundur.

Anda dapat mengakses nilai hasil ini menggunakan peta variables untuk mengambil jenis tertentu atau mengakses elemen dalam urutan menggunakan pengindeksan array. Anda dapat mengakses item tertentu dalam urutan berdasarkan indeksnya atau memilih seluruh urutan untuk mengevaluasi setiap nilai satu per satu.

Sintaksis:

$d.detection.detection.variables[OUTCOME_NAME].TYPE_SUFFIX

Sintaksis untuk urutan:

$d.detection.detection.variables[OUTCOME_NAME].SEQUENCE_TYPE_SUFFIX.TYPE_VALS_SUFFIX

Contoh: Mengakses variabel hasil dalam peta

Mengakses hasil string:

    $my_string_outcome = $d.detection.detection.variables["outcome_ip"].string_val
   

Contoh ini mengambil nilai string secara langsung (misalnya, "1.1.1.1" jika outcome_ip adalah string tunggal).

Mengakses hasil bilangan bulat

    $my_int_outcome = $d.detection.detection.variables["outcome_port"].int64_value
    

Contoh ini mengambil nilai bilangan bulat (misalnya, 30).

Mengakses daftar bilangan bulat menggunakan Int64Sequence

   $my_int_list = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals
   

Contoh ini mengambil daftar bilangan bulat lengkap dan membatalkan nest-nya seperti kolom berulang (misalnya, [2, 3, 4]).

Mengakses elemen tertentu dari daftar bilangan bulat

    $first_int = $d.detection.detection.variables["outcome_ports"].int64_seq.int64_vals[0]
    

Contoh ini mengambil bilangan bulat pertama dari daftar (misalnya, 2).

Mengakses daftar string (StringSequence)

    $my_string_list = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals
    

Contoh ini mengambil daftar lengkap string dan membatalkan nest-nya seperti kolom berulang (misalnya, ["1.1.1.1", "2.2.2.2"]).

Mengakses elemen tertentu dari daftar string

    $first_ip = $d.detection.detection.variables["outcome_ips"].string_seq.string_vals[0]
    

Contoh ini mengambil alamat IP pertama dari daftar (misalnya, "1.1.1.1").

Sufiks jenis yang tersedia untuk variables

Untuk mengetahui daftar lengkap akhiran yang didukung, lihat FindingVariable.

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