Aturan peristiwa tunggal dan multiperistiwa di YARA-L

Didukung di:

Dokumen ini menampilkan kueri yang ditulis dalam YARA-L 2.0. Setiap contoh menunjukkan cara menghubungkan peristiwa dalam bahasa aturan kueri untuk mengidentifikasi ancaman keamanan, memantau perilaku entity, dan memperkaya deteksi dengan logika bisnis.

Gunakan contoh sebagai elemen penyusun YARA-L 2.0, termasuk deteksi peristiwa tunggal, pencocokan ekspresi reguler, dan pemfilteran rentang jaringan. Contoh-contoh ini diatur ke dalam kategori fungsional untuk membantu Anda beralih dari logika dasar ke korelasi multi-peristiwa lanjutan dan deteksi gabungan.

Sintaksis dasar dan dasar-dasar

Contoh dalam bagian ini menunjukkan cara mengorelasikan peristiwa UDM secara efektif dan menyusun kueri dalam bahasa aturan.

Topik Contoh
Kueri peristiwa tunggal Penelusuran login pengguna awal; Deteksi login 5 menit
Membuat kueri dan melakukan penyesuaian Deteksi proses berbasis pengecualian
Rentang dan logika jaringan Pencocokan peristiwa tunggal (rentang IP)
Ekspresi reguler dalam kueri Pemfilteran email; Regex nama host; Penelusuran log mentah
Kolom berulang dengan kondisi universal Validasi IP login yang mencurigakan

Kueri peristiwa tunggal

Kasus penggunaan: Deteksi dasar jenis peristiwa tertentu (misalnya, USER_LOGIN) tanpa perlu mengorelasikan di seluruh periode waktu.

Logika utama: Hanya menggunakan bagian peristiwa dan kondisi untuk mengidentifikasi satu kejadian. Aturan peristiwa tunggal dapat berupa:

  • Aturan apa pun tanpa bagian match.
  • Aturan dengan bagian match dan bagian condition hanya memeriksa keberadaan satu peristiwa (misalnya, $e, #e > 0, #e >= 1, 1 <= #e, 0 < #e).

Aturan

Contoh aturan berikut menelusuri peristiwa login pengguna (USER_LOGIN) dan menampilkan peristiwa pertama yang ditemui dalam data perusahaan yang disimpan di akun Google SecOps Anda:

rule SingleEventRule {
meta:
  author = "noone@altostrat.com"

events:
  $e.metadata.event_type = "USER_LOGIN"

condition:
  $e
}

Contoh penelusuran yang tidak digabungkan ini menghasilkan peristiwa individual secara langsung. Karena kueri ini tidak memerlukan korelasi peristiwa, variabel peristiwa, seperti $e1, tidak disertakan.

metadata.event_type = "USER_LOGIN"

Dasbor

Karena logika kueri ini berfokus pada menampilkan peristiwa spesifik yang tidak berkorelasi dalam keadaan mentahnya, kueri ini tidak menggunakan bagian match atau outcome yang diperlukan untuk visualisasi dasbor.

Contoh: Deteksi login lima menit

Aturan

Contoh berikut menunjukkan aturan peristiwa tunggal yang menggunakan bagian match untuk menemukan pengguna yang memiliki setidaknya satu peristiwa login yang terjadi dalam jangka waktu 5 menit (5m). Skrip ini memeriksa keberadaan peristiwa login pengguna.

rule SingleEventRule {
meta:
  author = "alice@example.com"
  description = "windowed single event example rule"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $user

match:
  $user over 5m

condition:
  #e > 0
}

Telusuri

Contoh penelusuran statistik ini menggabungkan aktivitas ke dalam jendela bergulir lima menit (5m), dengan output satu baris per pengguna per jendela. Karena kueri berfokus pada jumlah volumetrik per periode, variabel event dan bagian condition dihilangkan, karena hasilnya secara inheren mencakup satu atau beberapa peristiwa. Versi ini menggunakan periode tumbling, bukan periode hopping, untuk memastikan hasil dirender dengan benar dalam platform.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

Dasbor

Contoh berikut menggabungkan bagian outcome untuk menghitung total jumlah peristiwa per pengguna, yang membantu memetakan data sebagai nilai statistik dari waktu ke waktu. Kueri menggunakan periode tumbling, bukan periode hopping untuk memastikan titik data dipetakan ke bucket diskrit yang tidak tumpang-tindih, dan memberikan visualisasi yang lebih jelas untuk tren dasbor.

metadata.event_type = "USER_LOGIN"
principal.user.userid = $user

match:
  $user by 5m

outcome:
  $event_count = count(metadata.id)

Membuat kueri dan menyesuaikan

Kasus penggunaan: Mendeteksi Windows svchost.exeyang diluncurkan dari direktori non-standar.

Logika utama: Negasi (not) yang digabungkan dengan pencocokan ekspresi reguler.

Contoh: Deteksi proses berbasis pengecualian

Aturan

Aturan berikut memeriksa pola tertentu dalam data peristiwa dan membuat deteksi jika menemukan pola tersebut. Aturan ini mencakup variabel $e1 untuk melacak jenis peristiwa dan kolom UDM metadata.event_type. Aturan ini memeriksa kemunculan spesifik kecocokan ekspresi reguler dengan e1. Saat peristiwa $e1 terjadi, deteksi akan dibuat. Kondisi not disertakan dalam aturan untuk mengecualikan jalur tertentu yang tidak berbahaya. Anda dapat menambahkan not kondisi untuk mencegah positif palsu.

rule suspicious_unusual_location_svchost_execution
{
meta:
  author = "Google Cloud Security"
  description = "Windows 'svchost' executed from an unusual location"
  yara_version = "YL2.0"
  rule_version = "1.0"

events:
  $e1.metadata.event_type = "PROCESS_LAUNCH"
  re.regex($e1.principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
  not re.regex($e1.principal.process.command_line, `\\Windows\\System32\\`) nocase

condition:
  $e1
}

Telusuri

Contoh ini melakukan penelusuran tanpa agregasi untuk menghasilkan peristiwa individual. Karena penelusuran ini tidak memerlukan korelasi peristiwa di beberapa instance, variabel peristiwa seperti $e1 tidak diperlukan.

metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase

Dasbor

Sintaksis ini menggabungkan bagian match dan outcome untuk menghitung volume peristiwa dari waktu ke waktu. Fungsi timestamp.get_timestamp() mengelompokkan hasil menurut hari untuk visualisasi tren.

metadata.event_type = "PROCESS_LAUNCH"
re.regex(principal.process.command_line, `\bsvchost(\.exe)?\b`) nocase
not re.regex(principal.process.command_line, `\\Windows\\System32\\`) nocase
$date = timestamp.get_timestamp(metadata.event_timestamp.seconds)

match:
  $date

outcome:
  $event_count = count(metadata.id)

Rentang dan logika jaringan

Kasus penggunaan: Memfilter aktivitas berdasarkan subnet IP (CIDR) tertentu dan mencocokkan dengan beberapa kemungkinan nama host.

Logika kunci: Gunakan fungsi net.ip_in_range_cidr() untuk pencocokan subnet dan operator OR untuk memeriksa beberapa kemungkinan nama host.

  • net.ip_in_range_cidr(): Fungsi ini memeriksa apakah alamat IP tertentu ada dalam subnet Classless Inter-Domain Routing (CIDR) tertentu.
  • Operator logika OR: Digunakan untuk menggabungkan beberapa kondisi. Kondisi dalam bagian peristiwa digabungkan secara implisit dengan AND. Operator OR memeriksa beberapa kemungkinan nama host.

Contoh: Pencocokan peristiwa tunggal (rentang IP)

Aturan

Contoh berikut menunjukkan aturan peristiwa tunggal yang menelusuri kecocokan antara dua nama host tertentu dan rentang alamat IP tertentu:

rule OrsAndNetworkRange {
meta:
  author = "noone@altostrat.com"

events:
  // Checks CIDR ranges.
  net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")

  // Detection when the hostname field matches either value using or.
  $e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/

condition:
  $e
}

Telusuri

Contoh kueri berikut mengidentifikasi peristiwa saat alamat IP tertentu berada dalam rentang CIDR yang ditentukan dan nama host cocok dengan pola pengguna tertentu:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

Karena ini adalah kueri penelusuran, bukan aturan deteksi, seluruh peristiwa akan ditampilkan secara otomatis jika filter terpenuhi. Bagian match mengelompokkan data menurut principal.ip dan principal.hostname. Bagian condition tidak diperlukan, dan variabel peristiwa ($e) dihilangkan karena tidak ada korelasi peristiwa yang dilakukan.

Dasbor

Contoh kueri berikut menggabungkan hasil dengan mengelompokkan pasangan IP dan nama host yang unik:

net.ip_in_range_cidr(principal.ip, "203.0.113.0/24")

principal.hostname = /pbateman/ or principal.hostname = /sspade/

match:
  principal.ip, principal.hostname

Ekspresi reguler dalam kueri

Kasus penggunaan: Menelusuri pola string yang fleksibel (misalnya, domain tertentu dalam email) sambil mengabaikan kapitalisasi. Ini paling umum digunakan di Penelusuran dan Aturan.

Logika utama: Menggunakan /regex/ nocase untuk kecocokan dasar dan fungsi re.regex() untuk analisis kolom yang kompleks.

Contoh: Pemfilteran email

Aturan

Contoh ekspresi reguler YARA-L 2.0 berikut menelusuri peristiwa dengan email yang diterima dari domain altostrat.com. Karena nocase telah ditambahkan ke perbandingan regex variabel $host dan fungsi regex, perbandingan ini tidak peka huruf besar/kecil.

rule RegexRuleExample {
meta:
  author = "noone@altostrat.com"

events:
  $e.principal.hostname = $host
  $host = /.*HoSt.*/ nocase
  re.regex($e.network.email.from, `.*altostrat\.com`) nocase

match:
  $host over 10m

condition:
  #e > 10
}

Telusuri

Di antarmuka Penelusuran, logika ini digunakan untuk perburuan ancaman dan eksplorasi data dengan fidelitas tinggi. Daripada menunggu pemberitahuan otomatis, analis dapat membuat kueri UDM secara manual untuk menemukan instance spesifik nama host yang cocok dengan konvensi penamaan bersama dengan domain email yang ditargetkan. Ini adalah metode utama untuk memvalidasi volume peristiwa ini sebelum mempromosikannya ke dalam aturan deteksi persisten.

principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase
match:
 $host over 10m

Dasbor

Logika berikut mengidentifikasi pola yang menarik dengan menggabungkan telemetri hostname dan email ke dalam bucket 10 menit (10m). Jika digunakan dalam Dasbor, logika ini memungkinkan analis memvisualisasikan frekuensi komunikasi dari aset tertentu (yang cocok dengan host) ke domain altostrat.com. Tampilan ini penting untuk memantau tren pergerakan data internal dan mengidentifikasi top talker di seluruh infrastruktur penting.

principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex(network.email.from, `.*altostrat\.com`) nocase

match:
  $host over 10m

Contoh: Ekspresi reguler nama host

Aturan

Contoh berikut mengidentifikasi catat aktivitas apa pun yang mengidentifikasi entitas utama hostname sebagai server web (webserver) atau pengembangan (devserver). Detektor ini menggunakan ekspresi reguler yang tidak peka huruf besar/kecil untuk memastikan bahwa variasi dalam konvensi penamaan tidak menyebabkan deteksi terlewat.

rule WebServerOrDevServerActivity {
meta:
 author = "Alex"
 description = "Detects events where the principal hostname is 'webserver' or 'devserver', ignoring case."
 severity = "Informational"

events:
 $e.principal.hostname = /webserver|devserver/ nocase

condition:
 $e
}

Telusuri

Dalam contoh berikut, principal.hostname = /webserver|devserver/ nocase cocok dengan nama host seperti "WebServer01", "devserver-test", "MyWebServers". Ini adalah kasus penggunaan umum untuk menemukan peristiwa tertentu.

// Use /regex/ followed by nocase for a case-insensitive match
principal.hostname = /webserver|devserver/ nocase

Dasbor

Meskipun contoh spesifik ini tidak divisualisasikan dalam dasbor, aturan ini memberikan notifikasi aktivitas aktif dan deteksi persisten. Tidak seperti dasbor, yang memerlukan peninjauan manual, hal ini memastikan bahwa setiap instance aktivitas di server ini secara otomatis ditandai dan dicatat dalam mesin deteksi agar dapat langsung ditelusuri.

Aturan

Saat Anda menggunakan penelusuran manual untuk penyelidikan pada satu titik waktu, aturan deteksi memberikan pemantauan telemetri berkelanjutan 24/7. Anda dapat mengonversi kueri penelusuran yang berhasil menjadi aturan YARA-L untuk mengotomatiskan proses pemberitahuan.

Manfaat utama aturan:

  • Peringatan real-time: Secara otomatis menandai kecocokan saat kecocokan tersebut masuk ke dalam sistem.
  • Persistensi: Tidak perlu lagi memasukkan kembali istilah penelusuran secara manual.
  • Tindakan hasil: Langsung dimasukkan ke tampilan deteksi untuk triase analis dan respons insiden.

Telusuri

Analis keamanan sering menggunakan regex untuk menelusuri log mentah yang belum diurai dalam Google SecOps. Tindakan ini memungkinkan pencocokan pola yang fleksibel untuk menemukan artefak tertentu, meskipun artefak tersebut tidak sepenuhnya terstruktur atau diindeks. Sintaksisnya menggunakan garis miring:

raw = /host/

Kueri ini menampilkan baris log mentah yang berisi urutan karakter "host". Contoh konten log mentah yang cocok dapat mencakup "hostname": "myhost123".

Dasbor

Tidak ada varian dasbor khusus untuk jenis peristiwa tertentu ini. Untuk memvisualisasikan deteksi ini dalam skala besar, Anda dapat:

  • Petakan metadata.event_type ke diagram batang atau diagram lingkaran dalam Pembuat dasbor.
  • Lacak frekuensi peristiwa ini selama periode 7, 30, atau 90 hari untuk mengidentifikasi anomali dalam perilaku pengguna.

Kolom berulang dengan kondisi universal

Kasus penggunaan: Mengaudit peristiwa yang berisi daftar data (kolom berulang) untuk memastikan tidak ada pengecualian tepercaya, misalnya, memverifikasi bahwa setiap alamat IP yang terkait dengan login berada di luar rentang aman yang diketahui.

Logika utama: Menggunakan operator all untuk mengevaluasi setiap elemen dalam kolom berulang terhadap kondisi tertentu dan menunjukkan cara menetapkan kolom berulang ke variabel placeholder (misalnya, $ip) untuk membuat deteksi yang berbeda untuk setiap nilai unik dalam daftar.

Contoh: Validasi IP login mencurigakan

Aturan

Aturan berikut menelusuri peristiwa login saat semua alamat IP sumber tidak cocok dengan alamat IP yang diketahui aman dalam rentang waktu lima menit (5m).

rule SuspiciousIPLogins {
meta:
  author = "alice@example.com"

events:
  $e.metadata.event_type = "USER_LOGIN"

  // Detects if all source IP addresses in an event do not match "100.97.16.0"
  // For example, if an event has source IP addresses
  // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
  // it will be detected since "100.97.16.1", "100.97.16.2",
  // and "100.97.16.3" all do not match "100.97.16.0".

  all $e.principal.ip != "100.97.16.0"

  // Assigns placeholder variable $ip to the $e.principal.ip repeated field.
  // There will be one detection per source IP address.
  // For example, if an event has source IP addresses
  // ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
  // there will be one detection per address.

  $e.principal.ip = $ip

match:
  $ip over 5m

condition:
  $e
}

Telusuri

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Dasbor

metadata.event_type = "USER_LOGIN"

// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".

all principal.ip != "100.97.16.0"

// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.

principal.ip = $ip

match:
  $ip over 5m

Pembuatan periode lanjutan

Bagian ini membahas pola multi-tahap dan deteksi yang dipicu oleh aktivitas dari aturan lain.

Topik Contoh
Korelasi multi-peristiwa Deteksi login dari beberapa kota; Pembuatan dan penghapusan pengguna yang cepat
Periode sliding dalam kueri Deteksi peristiwa berurutan yang tidak ada
Kueri multi-peristiwa Deteksi login frekuensi tinggi
Kueri multi-peristiwa dengan hasil yang dihitung Brute force diikuti dengan login yang berhasil; Pencocokan host dengan jendela waktu

Korelasi multi-peristiwa

Bagian ini menunjukkan contoh cara melacak entitas (pengguna atau host) di beberapa peristiwa atau jangka waktu untuk mengidentifikasi pola perilaku.

Kasus penggunaan: Mendeteksi perjalanan yang tidak mungkin terjadi ketika satu pengguna login dari dua kota atau lebih dalam waktu kurang dari lima (5m) menit.

Logika utama: Gunakan bagian match untuk mengelompokkan menurut $user dan #city > 1 guna menemukan nilai lokasi yang berbeda.

Contoh: Deteksi login beberapa kota

Aturan

Aturan berikut menelusuri pengguna yang telah login ke perusahaan Anda dari dua kota atau lebih dalam waktu kurang dari 5 (5m) menit, dengan $user adalah variabel match, $udm adalah variabel peristiwa, serta $city dan $user adalah variabel placeholder:

rule DifferentCityLogin {
meta:

events:
  $udm.metadata.event_type = "USER_LOGIN"
  $udm.principal.user.userid = $user
  $udm.principal.location.city = $city

match:
  $user over 5m

condition:
  $udm and #city > 1
}

Penjelasan berikut menjelaskan cara kerja aturan ini:

  • Mengelompokkan peristiwa dengan nama pengguna ($user) dan menampilkannya ($user) saat kecocokan ditemukan.
  • Rentang waktu adalah lima menit (5m); hanya peristiwa yang berjarak kurang dari 5 menit (5m) yang dikorelasikan.
  • Menelusuri grup acara ($udm) yang jenis acaranya adalah USER_LOGIN.
  • Untuk grup peristiwa tersebut, aturan memanggil ID pengguna sebagai $user dan kota login sebagai $city.
  • Menampilkan kecocokan jika jumlah nilai city yang berbeda (dilambangkan dengan #city) lebih besar dari 1 dalam grup peristiwa ($udm) dalam rentang waktu 5 menit (5m).

Telusuri

Contoh kueri berikut menjalankan penelusuran statistik yang setara untuk mengidentifikasi pola perjalanan yang mustahil. Fitur ini mengelompokkan peristiwa USER_LOGIN menurut pengguna dalam jangka waktu lima menit (5m) dan memfilter hasilnya untuk menampilkan hanya instance saat beberapa kota berbeda terdeteksi untuk satu identitas.

events:
  metadata.event_type = "USER_LOGIN"
  principal.user.userid = $user
  principal.location.city = $city

match:
  $user over 5m

condition:
  #city > 1

Dasbor

Contoh kueri berikut memberikan visualisasi dasbor yang setara untuk melacak potensi pembobolan akun. Laporan ini menggabungkan peristiwa USER_LOGIN menurut pengguna selama periode lima menit (5m) dan memfilter instance saat satu identitas dikaitkan dengan lebih dari satu kota yang berbeda (#city), sehingga Anda dapat memetakan anomali geografis berisiko tinggi ini dari waktu ke waktu.

events:
  metadata.event_type = "USER_LOGIN"
  principal.user.userid = $user
  principal.location.city = $city

match:
  $user over 5m

condition:
  #city > 1

Pembuatan dan penghapusan pengguna yang cepat

Kasus penggunaan: Mengidentifikasi akun sementara yang dibuat lalu dihapus dalam jangka waktu 4 jam.

Logika utama: Gabungkan dua jenis peristiwa (USER_CREATION dan USER_DELETION) pada variabel $user bersama dan bandingkan stempel waktunya.

Contoh: Pembuatan dan penghapusan pengguna yang cepat

Aturan

Contoh aturan berikut menelusuri pengguna yang telah dibuat lalu dihapus dalam waktu 4 jam (4h) dengan $create dan $delete adalah variabel peristiwa, $user adalah variabel match, dan tidak ada variabel placeholder:

rule UserCreationThenDeletion {
meta:

events:
  $create.target.user.userid = $user
  $create.metadata.event_type = "USER_CREATION"

  $delete.target.user.userid = $user
  $delete.metadata.event_type = "USER_DELETION"

  $create.metadata.event_timestamp.seconds <=
     $delete.metadata.event_timestamp.seconds

match:
  $user over 4h

condition:
  $create and $delete
}

Telusuri

Contoh berikut menunjukkan penelusuran statistik multi-peristiwa yang digunakan untuk mengidentifikasi perubahan siklus proses akun yang cepat. Kueri ini menghasilkan satu baris per pengguna dalam periode empat jam, yang mengorelasikan pembuatan dan penghapusan identitas.

Karena penelusuran secara default menampilkan jendela apa pun yang berisi peristiwa yang ditentukan, bagian condition tidak diperlukan.

$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"

$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"

$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds

match:
  $user over 4h

Dasbor

Contoh berikut menunjukkan penelusuran dasbor multi-peristiwa yang dirancang untuk memetakan tren siklus proses akun dari waktu ke waktu. Dengan menggunakan periode tumbling (by 4h), hasilnya dipetakan ke bucket waktu yang terpisah dan tidak tumpang-tindih, yang ideal untuk visualisasi.

Variasi ini mencakup bagian outcome untuk menghitung jumlah unik peristiwa pembuatan dalam setiap periode. Tidak seperti penelusuran sebelumnya, versi ini tidak memerlukan variabel peristiwa tertentu untuk ditampilkan, karena fokusnya adalah pada nilai statistik gabungan, bukan baris log individual.

$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"

$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"

$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds

match:
  $user by 4h

outcome:
  $event_count = count_distinct($create.metadata.id)

Periode geser dalam kueri

Kasus penggunaan: Untuk mendeteksi potensi masalah keamanan saat peristiwa awal (dari firewall_1) tidak diikuti oleh peristiwa berikutnya yang diharapkan (dari firewall_2) di host yang sama dalam jangka waktu tertentu.

Logika kunci:

  • Peristiwa pivot: Aturan ini berpusat pada peristiwa dari firewall_1, yang ditetapkan sebagai $e1. Setiap kali peristiwa $e1 terjadi, peristiwa tersebut bertindak sebagai titik pivot.
  • Jangka waktu: Bagian match ($host over 10m after $e1) menentukan jangka waktu 10 menit yang dimulai segera setelah setiap peristiwa $e1. Jendela ini bergeser dengan setiap peristiwa $e1 baru.
  • Korelasi: Peristiwa dikelompokkan menurut nama host ($host).
  • Kondisi untuk deteksi ($e1 dan $e2): Deteksi dipicu untuk host tertentu jika:
    • Ada peristiwa dari firewall_1 ($e1).
    • AND, dalam jangka waktu 10 menit setelah peristiwa $e1 tertentu, peristiwa NO dari firewall_2 ($e2) ditemukan untuk host yang sama.

Contoh: Deteksi peristiwa berurutan yang hilang

Aturan

Contoh berikut mengidentifikasi peristiwa sekunder yang gagal terjadi setelah pemicu utama. Dengan menggunakan kondisi !$e2 dalam jangka waktu 10 menit, aturan ini menandai telemetri yang tidak ada—khususnya saat log firewall terlihat di satu lokasi, tetapi tidak muncul di hop berikutnya yang diharapkan, yang menunjukkan potensi kesenjangan visibilitas atau penurunan traffic.

rule MissingSequentialEvent {
meta:
  author = "alice@example.com"

events:
  $e1.metadata.product_name = "firewall_1"
  $e1.principal.hostname = $host

  $e2.metadata.product_name = "firewall_2"
  $e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2
}

Telusuri

Contoh berikut menunjukkan penelusuran berurutan yang digunakan untuk mengidentifikasi kesenjangan dalam telemetri antara dua sumber. Dengan menggunakan $e1 sebagai pivot, penelusuran akan mencari peristiwa firewall utama yang tidak diikuti oleh peristiwa yang sesuai di firewall kedua dalam waktu 10 menit. Cara ini sangat efektif untuk memburu "black hole" secara manual dalam traffic jaringan atau kegagalan logging selama penyelidikan.

$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host

$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Dasbor

Contoh berikut memberikan analisis kesenjangan visibilitas yang dirancang untuk tampilan dasbor. Dengan menggabungkan instance saat peristiwa sekunder gagal mengikuti peristiwa utama, Anda dapat memvisualisasikan keandalan pipeline logging dari waktu ke waktu. Memetakan peristiwa "hilang" ini membantu mengidentifikasi zona mati yang persisten dalam visibilitas jaringan atau masalah konfigurasi di seluruh nama host tertentu.

$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host

$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host

match:
// $e1 is the pivot; the 10-minute window starts at the $e1 timestamp
  $host over 10m after $e1

condition:
  $e1 and !$e2

Kueri multi-peristiwa

  • Kasus penggunaan: Mengidentifikasi aktivitas frekuensi tinggi atau brute force dengan melacak satu entitas (misalnya, pengguna atau host) di beberapa kemunculan peristiwa dalam jangka waktu tertentu.

  • Logika utama: Menggunakan bagian match untuk mengelompokkan peristiwa berdasarkan variabel tertentu dan bagian condition untuk memeriksa jumlah minimum (misalnya, #e >= 10) dalam rentang waktu yang ditentukan.

Aturan multi-peristiwa yang umum mencakup:

  • Variabel peristiwa untuk membedakan peristiwa.
  • Bagian match yang menentukan rentang waktu pengelompokan peristiwa.
  • Bagian condition yang menentukan kondisi yang harus memicu deteksi dan memeriksa keberadaan beberapa peristiwa.

Dalam Penelusuran, kueri multi-peristiwa ditentukan oleh lebih dari satu peristiwa dalam kueri. Untuk Aturan, ada dua cara untuk menentukannya:

  • Beberapa acara: (misalnya, event1 = successful login, event2 = failed login).

  • Pemicu berbasis kondisi: Kondisi dinyatakan untuk dipicu hanya jika beberapa peristiwa memenuhi kriteria (misalnya, event1 > 10). Jenis aturan ini juga perlu menyertakan bagian outcome.

Contoh: Deteksi login frekuensi tinggi

Aturan

Aturan berikut menelusuri pengguna yang telah login setidaknya 10 kali dalam waktu kurang dari 10 menit:

rule MultiEventRule {
meta:
  author = "noone@altostrat.com"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $user

match:
  $user over 10m

condition:
  #e >= 10
}

Telusuri

Contoh berikut menggunakan penelusuran statistik multi-peristiwa untuk mengidentifikasi aktivitas login berfrekuensi tinggi. Aturan ini menandai setiap instance saat satu pengguna menghasilkan 10 atau lebih peristiwa login dalam jangka waktu 10 menit (10m).

$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user

match:
  $user by 10m

condition:
  #e >= 10

Dasbor

Contoh berikut menggunakan penelusuran multi-peristiwa untuk memantau potensi penyusupan akun. Dengan mengorelasikan upaya login dalam jangka waktu 10 menit, fitur ini mengidentifikasi instance saat pengguna dan host tertentu mengalami beberapa kali login yang gagal, diikuti dengan login yang berhasil, sehingga Anda dapat memvisualisasikan pola autentikasi berisiko tinggi secara real time.

$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user

match:
  $user by 10m

condition:
  #e >= 10

Kueri multi-peristiwa dengan hasil yang dihitung

  • Kasus penggunaan: Terapkan logika kondisional untuk menetapkan risk_score berdasarkan tingkat keparahan aset atau volume jaringan.

  • Logika utama: Menggunakan bagian outcome untuk menghitung variabel dan bagian kondisi untuk memfilter menurut variabel tersebut.

Contoh: Serangan brute force diikuti dengan login yang berhasil

Contoh berikut menggunakan bagian outcome untuk menghitung peristiwa dalam jangka waktu match. Kueri ini menghasilkan output yang sama dengan kueri multi-peristiwa standar, tetapi menunjukkan cara menggabungkan variabel yang dihitung ke dalam logika deteksi Anda.

Aturan

rule PossibleBruteForceThenSuccessfulLogin {
meta:
  author = "Alex"
  description = "Detects multiple failed login attempts followed by a successful login for the same user and host within a 10-minute window."
  severity = "High"
  tactic = "Credential Access"

events:
  // Define the first type of event: Failed Login
  // We use $failed to represent any event matching these criteria.
  $failed.metadata.event_type = "USER_LOGIN"
  $failed.security_result.action = "FAIL"
  // Extract common fields to correlate on
  $failed.target.user.userid = $user
  $failed.principal.hostname = $hostname

  // Define the second type of event: Successful Login
  // We use $success to represent any event matching these criteria.
  $success.metadata.event_type = "USER_LOGIN"
  $success.security_result.action = "ALLOW"
  // Correlate using the same user and hostname placeholders
  $success.target.user.userid = $user
  $success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a time window: by 10m.
  // The rule will evaluate all events matching $failed or $success that share the same $user and $hostname within any given 10-minute period.
  $user, $hostname by 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

condition:
  // The conditions that must be met *within each matched group* ($user, $hostname over 10m).
  // - #failed >= 5: There must be 5 or more events matching the $failed criteria.
  // - #success >= 1: There must be at least 1 event matching the $success criteria.
  #failed >= 5 and #success >= 1
}

Telusuri

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Dasbor

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
  // This section is key for multi-event rules. It groups events:
  // - By the common placeholder variables: $user and $hostname.
  // - Within a sliding time window: over 10m.
  // The rule will evaluate all events matching $failed or $success that share
  // the same $user and $hostname within any given 10-minute period.
  $user, $hostname over 10m

Contoh: Pencocokan host dengan periode waktu

Aturan

Aturan berikut melihat dua peristiwa untuk mendapatkan nilai $hostname. Jika nilai $hostname cocok selama periode 5 menit (5m), skor tingkat keparahan akan diterapkan. Saat menyertakan jangka waktu di bagian match, aturan akan memeriksa dalam jangka waktu yang ditentukan.

rule OutcomeRuleMultiEvent {
meta:
  author = "Google Cloud Security"
events:
  $u.udm.principal.hostname = $hostname
  $asset_context.graph.entity.hostname = $hostname

  $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $risk_score =
    max(
        100
      + if($hostname = "my-hostname", 100, 50)
      + if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
          "Empty asset id",
          $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

Telusuri

 // Define the first type of event: Failed Login
 // We use $failed to represent any event matching these criteria.
 $failed.metadata.event_type = "USER_LOGIN"
 $failed.security_result.action = "FAIL"
 // Extract common fields to correlate on
 $failed.target.user.userid = $user
 $failed.principal.hostname = $hostname

 // Define the second type of event: Successful Login
 // We use $success to represent any event matching these criteria.
 $success.metadata.event_type = "USER_LOGIN"
 $success.security_result.action = "ALLOW"
 // Correlate using the same user and hostname placeholders
 $success.target.user.userid = $user
 $success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
 // Calculate aggregate values from the events within the match window.
 $failed_login_count = count($failed.metadata.id)
 $successful_login_count = count($success.metadata.id)
 ```

Dasbor

// Define the first type of event: Failed Login
// We use $failed to represent any event matching these criteria.
$failed.metadata.event_type = "USER_LOGIN"
$failed.security_result.action = "FAIL"
// Extract common fields to correlate on
$failed.target.user.userid = $user
$failed.principal.hostname = $hostname

// Define the second type of event: Successful Login
// We use $success to represent any event matching these criteria.
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
// Correlate using the same user and hostname placeholders
$success.target.user.userid = $user
$success.principal.hostname = $hostname

match:
 // This section is key for multi-event rules. It groups events:
 // - By the common placeholder variables: $user and $hostname.
 // - Within a sliding time window: over 10m.
 // The rule will evaluate all events matching $failed or $success that share
 // the same $user and $hostname within any given 10-minute period.
 $user, $hostname over 10m

outcome:
  // Calculate aggregate values from the events within the match window.
  $failed_login_count = count($failed.metadata.id)
  $successful_login_count = count($success.metadata.id)

Analisis kontekstual

Anda dapat menggunakan aturan YARA-L untuk mengevaluasi data peristiwa UDM terhadap data konteks indikator penyusupan (IOC). Data konteks ini disimpan sebagai konteks entity di Google SecOps.

Contoh di bagian ini menunjukkan cara membuat analisis yang memahami konteks dengan menggabungkan kolom peristiwa dengan feed IOC, seperti Google Safe Browsing dan feed kustom.

Topik Contoh
Pencocokan hash file dengan indikator penyusupan Peluncuran proses yang mencurigakan; Daftar ancaman Safe Browsing
Pencocokan alamat IP dengan indikator penyusupan Deteksi node keluar Tor; Beberapa upaya login yang gagal dari jaringan Tor
Pencocokan domain dengan indikator penyusupan Domain dengan prevalensi rendah
Pencocokan URL dengan indikator penyusupan URL berbahaya cocok dari feed ancaman
Pencocokan multi-feed serentak Deteksi Remote Access Tool dan node keluar Tor

Pencocokan hash file dengan indikator penyusupan

Kasus penggunaan: Mendeteksi eksekusi atau keberadaan file yang diidentifikasi sebagai Indikator Penyusupan (IOC) dalam feed ancaman.

Logika utama: Gabungkan peristiwa file atau proses UDM dengan entity file (hash) dari feed IOC di Entity Graph.

Contoh: Peluncuran proses yang mencurigakan

Aturan

Aturan berikut mengevaluasi data proses UDM terhadap data konteks IOC generik. Deteksi ini menelusuri peristiwa peluncuran proses dan menggabungkan hash file dari peristiwa dengan hash file yang ditemukan dalam grafik entitas IOC.

rule ProcessLaunch {
  meta:
  events:
    $ioc.graph.metadata.vendor_name = "ACME"
    $ioc.graph.metadata.product_name = "IOCs"
    $ioc.graph.metadata.entity_type = "FILE"
    $ioc.graph.entity.file.sha256 = $hash

    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.principal.hostname = $hostname
    (
        not $process.target.process.file.sha256 = "" and
        $process.target.process.file.sha256 = $hash
    )

  match:
    $hash over 15m

  condition:
    $ioc and $process
}

Contoh: Daftar ancaman Safe Browsing

Aturan

Google SecOps menyerap data dari daftar ancaman yang terkait dengan hash file, yang disimpan sebagai entitas. Aturan berikut mendeteksi eksekusi file yang dianggap berbahaya oleh Google Safe Browsing.

rule safe_browsing_file_execution {
    meta:
        author = "Google Security Operations"
        description = "Example usage of Safe Browsing data, to detect execution of a file that's been deemed malicious"
        severity = "LOW"

    events:
        // find a process launch event, match on hostname
        $execution.metadata.event_type = "PROCESS_LAUNCH"
        $execution.principal.hostname = $hostname

        // join execution event with Safe Browsing graph
        $sb.graph.entity.file.sha256 = $execution.target.process.file.sha256

        // look for files deemed malicious
        $sb.graph.metadata.entity_type = "FILE"
        $sb.graph.metadata.threat_intel.severity = "SEVERITY_HIGH"
        $sb.graph.metadata.product_name = "Google Safe Browsing"
        $sb.graph.metadata.source_type = "GLOBAL_CONTEXT"

    match:
        $hostname over 1h

    outcome:
        $risk_score = max(if($sb.graph.metadata.threat_intel.severity = "SEVERITY_HIGH", 90, 0))

    condition:
        $execution and $sb
}

Pencocokan alamat IP dengan indikator penyusupan

Kasus penggunaan: Mendeteksi komunikasi jaringan dengan alamat IP berbahaya yang diketahui dan disimpan dalam feed ancaman.

Logika utama: Gabungkan peristiwa jaringan UDM dengan entitas alamat IP dari feed IOC di Entity Graph.

Contoh: Deteksi node keluar Tor

Aturan

Mengidentifikasi traffic jaringan yang berasal dari atau terhubung ke node keluar Tor yang diketahui. Contoh ini menggabungkan peristiwa UDM dengan feed Tor Exit Nodes dari GCTI Feed, yang tersedia untuk semua pelanggan.

rule TorExitNodeMatch {
  meta:
    author = "Google Security Operations"
    description = "Detects traffic from known Tor exit nodes."
    severity = "MEDIUM"

  events:
    // Event based on IP
    $principal_ip = $e.principal.ip

    // Filter Entity Graph to extract feed specific details
    $gcti.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti.graph.metadata.feed = "Tor Exit Nodes"
    $gcti.graph.metadata.product_name = "GCTI Feed"

    // Join the IP data
    $principal_ip = $gcti.graph.entity.ip

  match:
    $principal_ip over 30m

  outcome:
    $threat_feed = array_distinct($gcti.graph.metadata.feed)

  condition:
    $e and $gcti
}

Contoh: Beberapa upaya login yang gagal dari jaringan Tor

Aturan

Mendeteksi beberapa upaya login yang gagal dari jaringan Tor. Contoh ini mengorelasikan peristiwa login_failure dengan feed Tor Exit Nodes dan menerapkan nilai minimum frekuensi menggunakan sintaksis jumlah (#).

rule TorMultiLoginFailure {
  meta:
    author = "Google Security Operations"
    description = "Detects multiple failed logins from a Tor network."
    severity = "HIGH"

  events:
    $failed_login_event.metadata.product_name = "login"
    $failed_login_event.metadata.product_event_type = "login_failure"
    $failed_login_event.metadata.vendor_name = "Google Workspace"
    $sus_ip = $failed_login_event.principal.ip
    $sus_target_account = $failed_login_event.target.user.email_addresses
    $sus_target_account != ""

    $gcti.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti.graph.metadata.feed = "Tor Exit Nodes"
    $gcti.graph.metadata.product_name = "GCTI Feed"

    // Join the IP data
    $sus_ip = $gcti.graph.entity.ip

  match:
    $sus_ip over 1h

  outcome:
    $event_count = count_distinct($failed_login_event.metadata.id)

  condition:
    $failed_login_event and #failed_login_event >= 10 and $gcti
}

Mencocokkan domain dengan indikator penyusupan

Kasus penggunaan: Mendeteksi aktivitas jaringan ke domain yang ditandai sebagai indikator penyusupan (IOC) atau domain dengan prevalensi rendah.

Logika utama: Gabungkan peristiwa jaringan UDM dengan entitas domain dari feed IOC atau data prevalensi di Entity Graph menggunakan nama domain atau nama host.

Contoh: Domain dengan prevalensi rendah

Aturan

Aturan berikut menghasilkan pemberitahuan deteksi dengan membandingkan domain dengan prevalensi rendah dengan IOC yang diketahui. Fitur ini menggabungkan peristiwa kueri DNS dengan data prevalensi dan entitas IOC dari feed ET_PRO_IOC.

rule network_prevalence_uncommon_domain_ioc_match {

  meta:
    author = "Google Security Operations"
    description = "Lookup Network DNS queries against Entity Graph for low prevalence domains with a matching IOC entry."
    severity = "MEDIUM"

  events:
    $e.metadata.event_type = "NETWORK_DNS"
    $e.network.dns.questions.name = $hostname

    //only match FQDNs, such as: exclude chrome dns access tests and other internal hosts
    $e.network.dns.questions.name = /(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/

    //prevalence entity graph lookup
    $p.graph.metadata.entity_type = "DOMAIN_NAME"
    $p.graph.entity.domain.prevalence.rolling_max > 0
    $p.graph.entity.domain.prevalence.rolling_max <= 3
    $p.graph.entity.domain.name = $hostname

    //ioc entity graph lookup
    $i.graph.metadata.vendor_name = "ET_PRO_IOC"
    $i.graph.metadata.entity_type = "DOMAIN_NAME"
    $i.graph.entity.hostname = $hostname

  match:
    $hostname over 10m

  outcome:
    $risk_score = max(
        //increment risk score based upon rolling_max prevalence
        if ( $p.graph.entity.domain.prevalence.rolling_max = 3, 50) +
        if ( $p.graph.entity.domain.prevalence.rolling_max = 2, 70) +
        if ( $p.graph.entity.domain.prevalence.rolling_max = 1, 90)
    )

  condition:
    $e and $p and $i
}

Pencocokan URL dengan indikator penyusupan

Kasus penggunaan: Mendeteksi aktivitas jaringan yang melibatkan URL berbahaya yang disimpan dalam feed ancaman.

Logika utama: Gabungkan peristiwa jaringan UDM yang berisi data URL dengan entitas URL dari feed IOC di Entity Graph.

Contoh: Pencocokan URL berbahaya dari feed ancaman

Aturan

Aturan berikut mendeteksi peristiwa jaringan saat URL yang diminta cocok dengan URL berbahaya yang diketahui dari feed threat intelligence. Hal ini mengorelasikan target.url peristiwa dengan entity URL dalam Grafik Entity.

rule ioc_url_threat_feed_match {
  meta:
    author = "Google Security Operations"
    description = "Matches network events against known malicious URLs from threat intelligence feeds."
    severity = "HIGH"

  events:
    // Filter for network traffic containing URL information
    $network_event.metadata.event_type = "NETWORK_HTTP" or $network_event.metadata.event_type = "NETWORK_CONNECTION"
    $url = $network_event.target.url

    // Entity Graph Join: URL Indicators
    $ioc.graph.metadata.entity_type = "URL"
    $ioc.graph.metadata.product_name = "GCTI Feed"
    $ioc.graph.metadata.feed = "Malicious URLs"
    $ioc.graph.entity.url = $url

  match:
    $url over 5m

  outcome:
    $risk_score = 85
    $threat_feed = array_distinct($ioc.graph.metadata.feed)
    $principal_ip = array_distinct($network_event.principal.ip)
    $principal_user = array_distinct($network_event.principal.user.userid)

  condition:
    $network_event and $ioc
}

Pencocokan multi-feed serentak

Kasus penggunaan: Korelasikan ancaman lanjutan dengan mencocokkan beberapa atribut (misalnya, alamat IP dan hash file) dengan feed ancaman terpisah dalam satu kueri peristiwa.

Logika utama: Gabungkan satu peristiwa UDM dengan beberapa placeholder Entity Graph, yang masing-masing memfilter threat_feed_name tertentu (misalnya, Google Cloud feed Threat Intelligence).

Contoh: Deteksi node keluar Tor dan Alat Akses Jarak Jauh

Aturan

Aturan berikut menandai traffic jaringan yang tampaknya terkait dengan Pemantauan dan Pengelolaan Jarak Jauh (RMM) dan berasal dari atau terhubung ke node keluar Tor. Fitur ini menggabungkan peristiwa NETWORK_CONNECTION ke feed IP (Tor Exit Nodes) dan feed Hash File (Alat Akses Jarak Jauh).

rule tor_and_remote_access_tool_match {
  meta:
    author = "Google Security Operations"
    description = "Matches network connections involving both a Tor exit node and Remote Access Tool malware hashes."
    severity = "CRITICAL"

  events:
    // Filter for network connection events, often recorded by EDR agents
    $e.metadata.event_type = "NETWORK_CONNECTION"
    $target_ip = $e.target.ip
    $process_hash = $e.principal.process.file.sha256

    // IP Feed Join: Tor Exit Nodes
    $gcti_ip.graph.metadata.entity_type = "IP_ADDRESS"
    $gcti_ip.graph.metadata.product_name = "GCTI Feed"
    $gcti_ip.graph.metadata.feed = "Tor Exit Nodes"
    $gcti_ip.graph.entity.ip = $target_ip

    // Hash Feed Join: Remote Access Tools
    $gcti_hash.graph.metadata.entity_type = "FILE"
    $gcti_hash.graph.metadata.product_name = "GCTI Feed"
    $gcti_hash.graph.metadata.feed = "Remote Access Tools"
    $gcti_hash.graph.entity.file.sha256 = $process_hash

  match:
    $target_ip over 10m

  outcome:
    $risk_score = 95
    $ip_feed = array_distinct($gcti_ip.graph.metadata.feed)
    $hash_feed = array_distinct($gcti_hash.graph.metadata.feed)

  condition:
    $e and $gcti_ip and $gcti_hash
}

Deteksi gabungan

Deteksi gabungan meningkatkan deteksi ancaman dengan menggunakan aturan gabungan. Aturan gabungan ini menggunakan deteksi dari aturan lain sebagai inputnya. Hal ini memungkinkan deteksi ancaman kompleks yang mungkin tidak terdeteksi oleh aturan individual. Untuk informasi selengkapnya, lihat Ringkasan deteksi komposit.

Topik Contoh
Pemfilteran berisiko tinggi Deteksi pengguna administratif
Agregasi dan penentuan nilai minimum Agregasi risiko
Agregasi taktik Agregasi Taktik MITRE
Deteksi komposit berurutan Upaya brute force yang diikuti dengan login yang berhasil
Deteksi kontekstual Pengayaan threat intelligence
Deteksi kemunculan bersama Terjadinya bersamaan eskalasi akses dan eksfiltrasi

Pemfilteran berisiko tinggi

Kasus penggunaan: Memfilter deteksi yang ada untuk atribut berisiko tinggi, seperti aktivitas yang melibatkan akun administratif.

Logika utama: Beroperasi pada hasil atau kolom metadata dalam temuan yang ada.

Deteksi gabungan pemfilteran berisiko tinggi adalah bentuk deteksi gabungan paling sederhana yang beroperasi pada kolom dalam temuan deteksi, seperti variabel hasil atau metadata aturan. Kondisi ini membantu memfilter deteksi untuk kondisi yang mungkin menunjukkan risiko lebih tinggi, seperti pengguna administrator atau lingkungan produksi.

Contoh: Deteksi pengguna administratif

Aturan

Aturan gabungan berikut menelusuri deteksi yang ada dengan aktor yang diidentifikasi sebagai pengguna administratif dan menerapkan penilaian risiko standar.

rule composite_admin_detection {
meta:
  rule_name = "Detection with Admin User"
  author = "Google Cloud Security"
  description = "Composite rule that looks for any detections where the actor is an admin user"
  severity = "Medium"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.variables["principal_users"]
  $principal_user = /admin|root/ nocase

match:
  $principal_user over 1h
outcome:
  $risk_score = 75
  $upstream_rules = array_distinct($rule_name)

condition:
  $d
}

Telusuri

Penelusuran statistik berikut mengidentifikasi dan menggabungkan aktivitas untuk akun dengan hak istimewa tinggi. Dirancang untuk menemukan semua nama aturan unik yang telah memicu deteksi yang melibatkan pengguna "admin" atau "root".

Dalam kueri khusus ini, periode waktu dihapus untuk melakukan analisis statistik tunggal di semua deteksi dalam jangka waktu yang dipilih. Selain itu, karena ini adalah penelusuran yang tidak digabungkan dan berfokus pada data deteksi yang ada, bagian peristiwa, variabel peristiwa, dan bagian kondisi tidak diperlukan.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $principal_user

outcome:
  $upstream_rules = array_distinct($rule_name)

Dasbor

Kueri dasbor ini memungkinkan Anda memvisualisasikan aturan spesifik mana yang paling sering mendeteksi aktivitas terkait admin. Dasbor ini dirancang untuk memberikan ringkasan tingkat tinggi tentang tren deteksi di seluruh lingkungan Anda.

Perhatikan perubahan pada variabel match dan agregasi outcome dibandingkan dengan contoh sebelumnya. Kueri ini mengelompokkan hasil menurut nama aturan dan menghitung jumlah pengguna admin yang terdeteksi untuk setiap aturan.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_users"]
$principal_user = /admin|root/ nocase

match:
  $rule_name

outcome:
  $admin_detections = count($principal_user)

Agregasi dan penentuan nilai minimum

Kasus penggunaan: Mengidentifikasi pengguna atau host yang menghasilkan volume pemberitahuan yang tinggi atau mengumpulkan skor penilaian risiko yang signifikan dari waktu ke waktu.

Logika utama: Menggunakan sum() atau count_distinct() untuk menganalisis data deteksi gabungan.

Aturan deteksi komposit agregasi memungkinkan Anda mengelompokkan temuan deteksi berdasarkan atribut bersama, seperti nama host atau nama pengguna, dan menganalisis data gabungan. Berikut adalah kasus penggunaan umum:

  • Mengidentifikasi pengguna yang menghasilkan banyak notifikasi keamanan atau risiko gabungan.
  • Mendeteksi host dengan pola aktivitas yang tidak biasa dengan menggabungkan deteksi terkait.

Contoh: Agregasi risiko

Aturan

Aturan ini menggabungkan penilaian risiko satu pengguna selama periode 48 jam. Fitur ini mengidentifikasi pengguna yang risiko kumulatifnya di beberapa deteksi melebihi nilai minimum tertentu.

Dalam logika yang diperbarui ini, detection.detection.outcomes diganti dengan variabel kolom peta, yang menyimpan variabel match dan outcome. Selain itu, variabel hasil $principal_users dihapus karena setiap deteksi berisi tepat satu nilai variabel kecocokan, yang sudah dicatat.

rule composite_risk_aggregation {
meta:
  rule_name = "Risk Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that aggregates risk of a user over 48 hours"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $risk = $d.detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $cumulative_risk > 500
}

Telusuri

Penelusuran statistik ini menggabungkan data deteksi untuk menghitung total risiko pengguna selama periode 48 jam. Tabel ini menghasilkan satu baris per pengguna utama untuk setiap periode, sehingga memberikan gambaran umum risiko akun di berbagai jenis deteksi.

Dalam variasi ini, variabel peristiwa tidak diperlukan. Meskipun mesin aturan otomatis memfilter deteksi tanpa pengguna utama, penelusuran ini memerlukan filter eksplisit ($principal_user != "") untuk memastikan hasilnya hanya menyertakan data yang terisi. Secara default, kueri hanya menampilkan hasil jika satu atau beberapa deteksi ada untuk pengguna tertentu.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user over 48h

outcome:
  $risk_score = 90
  $cumulative_risk = sum($risk)
  $upstream_rules = array_distinct($rule_name)

condition:
  $cumulative_risk > 500

Dasbor

Variasi ini dirancang khusus untuk dasbor guna memetakan risiko pengguna dan aktivitas deteksi dari waktu ke waktu. Diagram ini menggabungkan data ke dalam bucket terpisah, sehingga ideal untuk memvisualisasikan tren seperti volume aturan unik yang dipicu atau jumlah total deteksi per pengguna.

Dalam kueri ini, jendela diubah dari jendela geser (hop) ke jendela bergulir (by 48h). Hal ini memastikan bahwa titik data dipetakan ke segmen waktu yang tidak tumpang-tindih, yang memberikan visualisasi yang lebih bersih untuk diagram deret waktu. Seperti penelusuran lain yang tidak digabungkan, variabel peristiwa tidak diperlukan, dan bagian outcome diperluas untuk menyertakan jumlah yang berbeda untuk nama aturan dan ID deteksi.

$rule_name = detection.detection.rule_name
$principal_user = detection.detection.variables["principal_user"]
$principal_user != ""
$risk = detection.detection.risk_score

match:
  $principal_user by 48h

outcome:
  $cumulative_risk = sum($risk)
  $rule_count = count_distinct($rule_name)
  $detection_count = count_distinct(detection.id)

condition:
  $cumulative_risk > 500

Agregasi taktik

Kasus penggunaan: Mengidentifikasi pengguna yang aktivitasnya telah memicu deteksi di beberapa taktik MITRE ATT&CK yang berbeda, yang menunjukkan siklus proses serangan yang sedang berlangsung (misalnya, beralih dari Akses Awal ke Pemindahan yang tidak sah).

Logika utama: Menggunakan count_distinct($tactic) untuk memicu hanya saat pengguna melewati nilai minimum tertentu dari berbagai taktik dalam jangka waktu 48 jam.

Contoh: Agregasi taktik MITRE

Aturan

rule composite_tactic_aggregation {
meta:
  rule_name = "MITRE Tactic Aggregation Composite"
  author = "Google Cloud Security"
  description = "Composite detection that detects if a user has triggered detections over multiple mitre tactics."
  severity = "Medium"

events:
  $principal_user = $d.detection.detection.outcomes["principal_users"]
  $tactic = $d.detection.detection.outcomes["mitre_tactic"]
  $rule_name = $d.detection.detection.rule_name

match:
  $principal_user over 48h

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $upstream_rules = array_distinct($rule_name)

condition:
  $d and $mitre_tactics_count > 1 }

Telusuri

Contoh berikut menunjukkan varian penelusuran yang dirancang untuk developer keamanan yang perlu mengorelasikan deteksi yang ada dan menerapkan pembobotan risiko dinamis. Logika kueri ini mengekstrak taktik MITRE ATT&CK dan informasi pengguna dari sumber data detection, mengelompokkan aktivitas berdasarkan pengguna utama, dan menghitung penilaian risiko kustom berdasarkan keragaman taktik yang diamati.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)

Dasbor

Contoh berikut menggambarkan varian Dasbor dari logika analisis deteksi yang sama. Saat digunakan dalam Dasbor Google SecOps, kueri ini memungkinkan developer memvisualisasikan pengguna berisiko tinggi dengan menghubungkan hasil deteksi di berbagai aturan. Logika ini mengekstrak pengguna utama dan taktik MITRE, menggabungkan temuan, dan menerapkan skor risiko yang dibatasi untuk membantu memprioritaskan upaya investigasi langsung dalam widget dasbor.

detection.detection.outcomes.key = "principal_users"
detection.detection.outcomes.key = "mitre_tactic"
$principal_user = detection.detection.outcomes["principal_users"]
$tactic = detection.detection.outcomes["mitre_tactic"]
$rule_name = detection.detection.rule_name

match:
  $principal_user

outcome:
  $mitre_tactics_count = count_distinct($tactic)
  $mitre_tactics = array_distinct($tactic)
  $upstream_rules = array_distinct($rule_name)
  $calculated_risk = 50 + (15 * $mitre_tactics_count)
  $risk_score = if($calculated_risk > 100, 100,   $calculated_risk)
  ```

Deteksi gabungan berurutan

Kasus penggunaan: Mengidentifikasi pola serangan penting yang urutan operasinya sangat penting, misalnya, mendeteksi login akun yang berhasil yang hanya terjadi setelah serangkaian pemberitahuan upaya brute force dari alamat IP yang sama.

Logika utama: Menghubungkan deteksi sebelumnya dengan peristiwa UDM mentah berikutnya dengan menggabungkannya pada variabel umum (misalnya, $bruteforce_ip) dan menggunakan perbandingan stempel waktu untuk memastikan peristiwa terjadi dalam urutan yang benar.

Deteksi komposit berurutan mengidentifikasi pola peristiwa terkait yang urutan deteksinya penting, seperti deteksi upaya login brute force, diikuti dengan login yang berhasil. Pola ini dapat melibatkan beberapa deteksi dasar atau kombinasi deteksi dasar dan peristiwa.

Contoh: Upaya brute-force yang diikuti dengan login yang berhasil

Aturan

Aturan gabungan berikut mengidentifikasi pola peristiwa terkait yang urutannya penting. Deteksi ini secara khusus mencari deteksi serangan brute force Google Workspace yang diikuti dengan peristiwa login yang berhasil dari IP sumber yang sama dalam jangka waktu 24 jam.

rule composite_bruteforce_login {
meta:
  rule_name = "Bruteforce Login Composite"
  author = "Google Cloud Security"
  description = "Detects when an IP address associated with a Workspace brute force attempt successfully logs in"
  severity = "High"

events:
  $bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
  $bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

  $login_event.metadata.product_name = "login"
  $login_event.metadata.product_event_type = "login_success"
  $login_event.metadata.vendor_name = "Google Workspace"
  $login_ip = $login_event.principal.ip

  // Ensure the brute force detection and successful login occurred from the same IP
  $login_ip = $bruteforce_ip

  $target_account = $login_event.target.user.email_addresses

  // Ensure the brute force detection occurred before the successful login
  $bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $risk_score = 90
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event
}

Telusuri

$bruteforce_detection.detection.detection.rule_name = /Workspace Anomalous Failed Logins/
$bruteforce_ip = $bruteforce_detection.detection.detection.variables["principal_ips"]

$login_event.metadata.product_name = "login"
$login_event.metadata.product_event_type = "login_success"
$login_event.metadata.vendor_name = "Google Workspace"
$login_ip = $login_event.principal.ip

// Ensure the brute force detection and successful login occurred from the same IP
$login_ip = $bruteforce_ip

$target_account = $login_event.target.user.email_addresses

// Ensure the brute force detection occurred before the successful login
$bruteforce_detection.detection.detection_time.seconds < $login_event.metadata.event_timestamp.seconds

match:
  $bruteforce_ip over 24h

outcome:
  $principal_users = array_distinct($target_account)

condition:
  $bruteforce_detection and $login_event

Dasbor

Dasbor berfokus pada visualisasi data peristiwa mentah, sedangkan logika deteksi gabungan mengorelasikan pemberitahuan deteksi yang ada dengan peristiwa berikutnya. Analisis multi-layer ini dioptimalkan untuk mesin deteksi, bukan widget dasbor real-time.

Deteksi kontekstual

Kasus penggunaan: Memperkaya deteksi yang ada dengan threat intelligence eksternal untuk memverifikasi apakah peringatan melibatkan entitas berbahaya yang diketahui, misalnya, memeriksa apakah alamat IP yang ditandai dalam deteksi keamanan juga tercantum dalam feed ancaman node keluar TOR global.

Logika utama: Menggunakan aturan gabungan untuk menggabungkan temuan deteksi dengan data grafik GLOBAL_CONTEXT (misalnya,feed Threat Intelligence Google Cloud ) dengan mencocokkan atribut bersama seperti alamat IP.

Deteksi gabungan kontekstual memperkaya deteksi dengan konteks tambahan, seperti alamat IP yang ditemukan dalam feed ancaman.

Contoh: Pengayaan threat intelligence

Aturan

Aturan gabungan berikut secara otomatis menambahkan konteks tambahan dari feed intel TOR ke deteksi yang ada. Fitur ini mengorelasikan alamat IP yang ditemukan dalam deteksi sebelumnya dengan feed TOR Exit Nodes untuk meningkatkan tingkat keparahan dan penilaian risiko temuan.

rule composite_tor_enrichment {
meta:
  rule_name = "Detection with IP from TOR Feed"
  author = "Google Cloud Security"
  description = "Adds additional context from the TOR intel feed to detections"
  severity = "High"

events:
  $rule_name = $d.detection.detection.rule_name

  $gcti.graph.metadata.entity_type = "IP_ADDRESS"
  $gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
  $gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
  $gcti.graph.metadata.product_name = "GCTI Feed"
  $gcti.graph.metadata.feed = "Tor Exit Nodes"

  $detection_ip = $d.detection.detection.variables["principal_ips"]
  $detection_ip = $gcti.graph.entity.ip

match:
  $detection_ip, $rule_name over 1h

outcome:
  $risk_score = 80

condition:
  $d and $gcti
}

Telusuri

$rule_name = $d.detection.detection.rule_name

$gcti.graph.metadata.entity_type = "IP_ADDRESS"
$gcti.graph.metadata.vendor_name = "Google Cloud Threat Intelligence"
$gcti.graph.metadata.source_type = "GLOBAL_CONTEXT"
$gcti.graph.metadata.product_name = "GCTI Feed"
$gcti.graph.metadata.feed = "Tor Exit Nodes"

$detection_ip = $d.detection.detection.variables["principal_ips"]
$detection_ip = $gcti.graph.entity.ip

match:
  $detection_ip, $rule_name over 1h

condition:
  $d and $gcti

Dasbor

Deteksi ko-okurrensi

Kasus penggunaan: Mendeteksi kombinasi taktik terkait yang dipicu oleh entitas yang sama dalam jangka waktu tertentu, misalnya, mengidentifikasi pengguna yang telah memicu deteksi eskalasi hak istimewa dan deteksi eksfiltrasi data dalam waktu 48 jam.

Logika utama: Menggunakan bentuk agregasi untuk mengorelasikan beberapa jenis deteksi yang berbeda dengan menggabungkannya pada variabel entitas bersama (misalnya, $pe_user) dalam bagian match.

Deteksi komposit ko-okurensi adalah bentuk agregasi yang dapat mendeteksi kombinasi peristiwa terkait, seperti kombinasi deteksi eskalasi hak istimewa dan eksfiltrasi data yang dipicu oleh pengguna.

Contoh: Ko-okurrensi eskalasi hak istimewa dan eksfiltrasi

Aturan

Aturan gabungan berikut menelusuri urutan atau kombinasi deteksi tertentu—eskalasi hak istimewa yang diikuti dengan eksfiltrasi—yang terkait dengan pengguna yang sama selama periode 48 jam.

rule composite_privesc_exfil_sequential {
meta:
  rule_name = "Privilege Escalation and Exfiltration Composite"
  author = "Google Cloud Security"
  description = "Looks for a detection sequence of privilege escalation followed by exfiltration."
  severity = "High"

events:
  $privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
  $exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

  $privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
  $exfil_user = $exfiltration.detection.detection.variables["principal_users"]

  $privesc_user = $exfil_user

  $privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $risk_score = 75
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration
}

Telusuri

$privilege_escalation.detection.detection.rule_labels["tactic"] = "TA0004"
$exfiltration.detection.detection.rule_labels["tactic"] = "TA0010"

$privesc_user = $privilege_escalation.detection.detection.variables["principal_users"]
$exfil_user = $exfiltration.detection.detection.variables["principal_users"]

$privesc_user = $exfil_user

$privilege_escalation.detection.detection_time.seconds < $exfiltration.detection.detection_time.seconds

match:
  $privesc_user over 48h

outcome:
  $privesc_rules = array_distinct($privilege_escalation.detection.detection.rule_name)
  $exfil_rules = array_distinct($exfiltration.detection.detection.rule_name)

condition:
  $privilege_escalation and $exfiltration

Dasbor

Pengelolaan hasil dan variabel

Bagian ini menunjukkan contoh penghitungan risiko dan normalisasi data untuk penggunaan hilir.

Topik Contoh
Kondisional hasil Filter menurut penilaian risiko yang dihitung
Kueri peristiwa tunggal dengan hasil Pemberian tag tingkat keparahan point-in-time
Penilaian risiko berbasis jaringan Aturan penilaian risiko berbasis jaringan
Merefaktorisasi logika multi-peristiwa (pra-refaktorisasi) Refaktorisasi hasil (pra-refaktorisasi)
Merefaktorisasi logika multi-peristiwa (setelah refaktorisasi) Refaktor hasil (pasca-refaktor)
Penetapan fungsi ke placeholder

Bagian kueri dengan outcome

Anda dapat menambahkan bagian outcome opsional dalam aturan YARA-L 2.0 untuk mengekstrak informasi tambahan dari setiap deteksi. Di bagian condition, Anda juga dapat menentukan kondisional pada variabel hasil. Anda dapat menggunakan bagian outcome dari aturan deteksi untuk menetapkan variabel untuk penggunaan hilir. Misalnya, Anda dapat menetapkan skor tingkat keparahan berdasarkan data dari peristiwa yang sedang dianalisis.

Untuk informasi selengkapnya, lihat referensi berikut:

Kondisional hasil

Kasus penggunaan: Memfilter deteksi berdasarkan penilaian risiko yang dihitung untuk mengurangi derau dan memastikan hanya peristiwa dengan tingkat keyakinan tinggi atau tingkat keparahan tinggi yang memicu pemberitahuan. Hal ini berguna untuk menekan aktivitas berisiko rendah yang tidak memenuhi nilai minimum bisnis tertentu.

Logika utama: Menentukan variabel di bagian outcome menggunakan matematika bersyarat (misalnya, menambahkan risiko berdasarkan ukuran file atau waktu) lalu mereferensikan variabel tersebut di bagian condition untuk membatasi deteksi.

Contoh: Memfilter menurut skor penilaian risiko

Aturan

Di bagian condition, Anda dapat menggunakan variabel outcome yang ditentukan di bagian outcome. Contoh berikut menunjukkan cara memfilter pada penilaian risiko untuk mengurangi derau dalam deteksi menggunakan kondisional hasil.

rule OutcomeConditionalRule {
meta:
  author = "alice@example.com"
  description = "Rule that uses outcome conditionals"

events:
  $u.metadata.event_type = "FILE_COPY"
  $u.principal.file.size = $file_size
  $u.principal.hostname = $hostname

  // 1 = Sunday, 7 = Saturday.
  $dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)

outcome:
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

condition:
  $u and $risk_score >= 10
}

Telusuri

metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname

// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)

outcome:
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

Dasbor

Kueri ini menambahkan variabel hasil $hostname untuk memvisualisasikan host mana yang terkait dengan setiap skor risiko.

metadata.event_type = "FILE_COPY"
principal.file.size = $file_size
principal.hostname = $hostname

// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.collected_timestamp.seconds)

outcome:
  $host = $hostname
  $risk_score =
      if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
      if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
      if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
      if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices

Kueri peristiwa tunggal dengan hasil

Kasus penggunaan: Memperkaya deteksi tepat waktu dengan konteks langsung, seperti menetapkan tag tingkat keparahan berdasarkan daftar pengguna atau atribut file tanpa memerlukan periode waktu atau korelasi peristiwa.

Logika utama: Menggunakan bagian outcome dalam aturan yang tidak memiliki bagian match. Dengan demikian, Anda dapat mengekstrak metadata dan melakukan logika bersyarat (misalnya, memeriksa pengguna berdasarkan daftar referensi) untuk setiap peristiwa individual yang memenuhi kriteria.

Contoh: Pemberian tag tingkat keparahan pada satu titik waktu

Aturan

Contoh berikut menunjukkan cara menggunakan bagian outcome dalam aturan peristiwa tunggal untuk menetapkan variabel untuk penggunaan hilir, seperti menetapkan skor tingkat keparahan berdasarkan pengguna dan ukuran file tertentu yang terlibat dalam peristiwa penyalinan file.

rule OutcomeRuleSingleEvent {
meta:
  author = "alice@example.com"
events:
  $u.metadata.event_type = "FILE_COPY"
  $u.principal.file.size = $file_size
  $u.principal.hostname = $hostname

outcome:
  $suspicious_host = $hostname
  $admin_severity = if($u.principal.user.userid in %admin_users, "SEVERE", "MODERATE")
  $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

condition:
  $u
}

Telusuri

Contoh berikut mengidentifikasi peristiwa pembuatan file dan menggunakan bagian outcome untuk menetapkan tingkat keparahan secara dinamis ke setiap hasil. Tidak seperti aturan multi-peristiwa, penelusuran yang tidak digabungkan ini tidak memerlukan variabel peristiwa atau bagian match. Sebagai gantinya, setiap log diproses satu per satu untuk menghasilkan 1 row per event, yang diperkaya dengan logika kustom berdasarkan ukuran file dan izin pengguna.

metadata.event_type = "FILE_CREATION"
principal.file.size = $file_size
principal.hostname = $hostname

outcome:
  $suspicious_host = $hostname
  $admin_severity = if(principal.user.userid in %a1, "SEVERE", "MODERATE")
  $severity_tag = if($file_size > 1024, $admin_severity, "LOW")

Dasbor

Varian dasbor tidak berlaku untuk contoh ini karena maksud utamanya adalah memberi tag dan memperkaya setiap peristiwa. Meskipun dasbor dapat menggabungkan peristiwa ini (misalnya, menghitung total jumlah peristiwa per tag tingkat keparahan), hal ini akan mengaburkan detail tingkat baris yang terperinci yang dirancang untuk ditemukan oleh penelusuran yang tidak digabungkan ini.

Penilaian risiko berbasis jaringan

Kasus penggunaan: Identifikasi transfer data berisiko tinggi dengan menghitung volume kumulatif traffic jaringan di seluruh grup peristiwa. Hal ini memungkinkan Anda mengidentifikasi ancaman saat total volume minimum data melebihi batas tertentu (misalnya, 1024 byte) sekaligus memperhitungkan tingkat keparahan kerentanan aset yang terlibat.

Logika utama: Menggunakan fungsi agregat sum() di bagian outcome untuk menggabungkan sent_bytes dan received_bytes di semua peristiwa dalam periode match. Untuk Aturan, kueri menggunakan pernyataan if untuk menerapkan penilaian risiko yang lebih tinggi jika jumlah tersebut melebihi nilai minimum yang ditentukan.

Contoh: Aturan penilaian risiko berbasis jaringan

Aturan

Contoh berikut menunjukkan cara menggunakan bagian outcome untuk menghitung skor risiko dinamis berdasarkan aktivitas jaringan. Dengan menjumlahkan total byte yang ditransfer di seluruh grup peristiwa, aturan ini menerapkan prioritas yang lebih tinggi pada kecocokan yang melebihi volume minimum data tertentu (1024 byte) sekaligus memperhitungkan tingkat keparahan kerentanan aset yang terlibat.

rule OutcomeRuleMultiEvent {
meta:
  author = "alice@example.com"
events:
  $u.udm.principal.hostname = $hostname
  $asset_context.graph.entity.hostname = $hostname

  $severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
          "Empty asset id",
          $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}

Telusuri

Contoh berikut menunjukkan varian penelusuran yang mengorelasikan peristiwa jaringan UDM dengan konteks aset dari Entity Context Graph (ECG). Aturan ini menggunakan periode match 5 menit untuk menggabungkan traffic jaringan berdasarkan nama host, menghitung penilaian risiko berdasarkan volume data dan tingkat keparahan kerentanan, serta menerapkan filter bersyarat untuk mengecualikan ID aset tertentu dari kumpulan hasil akhir.

$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname

$severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
        "Empty asset id",
        $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")

Dasbor

Contoh berikut mengilustrasikan varian Dasbor yang memperkaya telemetri jaringan real-time dengan data kerentanan aset. Dengan mencocokkan nama host selama periode 5 menit, kueri ini memungkinkan developer membuat widget dasbor yang memvisualisasikan tingkat risiko aset. Logika ini menyesuaikan skor risiko secara dinamis berdasarkan throughput jaringan dan kerentanan tingkat keparahan tertinggi yang ditemukan di aset, sehingga memberikan tampilan yang diprioritaskan dari sistem yang berpotensi disusupi.

$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname

$severity = $asset_context.graph.entity.asset.vulnerabilities.severity

match:
  $hostname over 5m

outcome:
  $total_network_bytes = sum($u.network.sent_bytes) + sum($u.network.received_bytes)

  $risk_score = if($total_network_bytes > 1024, 100, 50) +
    max(
      if($severity = "HIGH", 10)
      + if($severity = "MEDIUM", 5)
      + if($severity = "LOW", 1)
    )

  $asset_id_list =
    array(
      if($u.principal.asset_id = "",
        "Empty asset id",
        $u.principal.asset_id
      )
    )

  $asset_id_distinct_list = array_distinct($u.principal.asset_id)

  $asset_id_count = count($u.principal.asset_id)

  $asset_id_distinct_count = count_distinct($u.principal.asset_id)

condition:
  $u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")

Merefaktorisasi aturan outcome multi-peristiwa (pra-refaktorisasi)

Kasus penggunaan: Meningkatkan performa sistem dan mengurangi latensi pemrosesan dengan mengonversi aturan multi-peristiwa menjadi aturan peristiwa tunggal. Hal ini ideal untuk aturan yang awalnya didesain hanya dengan bagian kecocokan untuk mengaktifkan bagian hasil, tetapi sebenarnya tidak memerlukan korelasi di beberapa peristiwa berbeda.

Logika utama: Menghapus bagian match dan semua fungsi agregat (misalnya, max(), sum(), atau count()) dari bagian outcome. Transisi ini mengubah aturan dari mengelompokkan peristiwa dari waktu ke waktu menjadi mengevaluasi setiap peristiwa satu per satu saat peristiwa tersebut diterima. match), dan aturan multi-peristiwa (aturan dengan bagian match).

Anda dapat menggunakan bagian outcome untuk aturan peristiwa tunggal (aturan tanpa Jika sebelumnya Anda mendesain aturan menjadi multi-peristiwa hanya agar dapat menggunakan bagian hasil, Anda dapat secara opsional merefaktorisasi aturan tersebut dengan menghapus bagian match untuk meningkatkan performa. Perhatikan bahwa karena aturan Anda tidak lagi memiliki bagian match yang menerapkan pengelompokan, Anda mungkin menerima lebih banyak deteksi.

Contoh: Pemfaktoran ulang hasil (sebelum pemfaktoran ulang)

Aturan

Contoh berikut menunjukkan aturan hasil multi-peristiwa yang hanya menggunakan satu variabel peristiwa. Karena menggunakan bagian match, Rules Engine harus mengelompokkan peristiwa selama periode 5 menit sebelum menghitung hasilnya, yang menggunakan lebih banyak resource daripada evaluasi satu peristiwa.

rule OutcomeMultiEventPreRefactor {
meta:
  author = "alice@example.com"
  description = "Outcome refactor rule, before the refactor"

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u
}

Telusuri

Kueri statistik yang setara

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u

Dasbor

events:
  $u.udm.principal.hostname = $hostname

match:
  $hostname over 5m

outcome:
  $risk_score = max(if($hostname = "my-hostname", 100, 50))

condition:
  $u

Merefaktorisasi aturan outcome multi-peristiwa (pasca-refaktorisasi)

Kasus penggunaan: Menyelesaikan pengoptimalan kueri untuk meningkatkan kecepatan pemrosesan. Dengan menghapus persyaratan pengelompokan, kueri kini memicu deteksi segera setelah kedatangan satu peristiwa yang cocok, yang jauh lebih efisien untuk Mesin Aturan.

Logika utama: Menghapus bagian match dan menghapus fungsi aggregate (misalnya, max()) dari penetapan variabel outcome. Logika dalam pernyataan if tetap sama, tetapi kini diterapkan ke satu peristiwa, bukan grup.

Anda dapat memfaktorkan ulang kueri dengan menghapus bagian match. Catatan: Anda juga harus menghapus agregat di bagian outcome karena kueri sekarang menjadi peristiwa tunggal. Untuk mengetahui informasi selengkapnya tentang agregasi, lihat agregasi hasil.

Contoh: Refaktor hasil

Aturan

rule OutcomeSingleEventPostRefactor {
meta:
  author = "alice@example.com"
  description = "Outcome refactor rule, after the refactor"

events:
  $u.udm.principal.hostname = $hostname

// We deleted the match section.

outcome:
  // We removed the max() aggregate.
  $risk_score = if($hostname = "my-hostname", 100, 50)

condition:
  $u
}

Telusuri

events:
  $u.udm.principal.hostname = $hostname

outcome:
  $risk_score = if($hostname = "my-hostname", 100, 50)

Dasbor

events:
  $u.udm.principal.hostname = $hostname

outcome:
  $risk_score = if($hostname = "my-hostname", 100, 50)

Penetapan fungsi ke placeholder

Kasus penggunaan: Menormalisasi data (misalnya, menstandarkan domain email) untuk memverifikasi bahwa pengelompokan di bagian pertandingan akurat.

Logika utama: Menetapkan hasil re.capture() atau strings.concat() ke variabel placeholder.

Contoh: Penugasan variabel fungsi ke placeholder

Anda dapat menetapkan variabel placeholder ke hasil panggilan fungsi dan dapat menggunakan variabel placeholder di bagian lain aturan, seperti bagian match, bagian outcome, atau bagian condition.

Aturan

rule FunctionToPlaceholderRule {
meta:
  author = "alice@example.com"
  description = "Rule that uses function to placeholder assignments"

events:
  $u.metadata.event_type = "EMAIL_TRANSACTION"

  // Use function-placeholder assignment to extract the
  // address from an email.
  // address@website.com -> address
  $email_to_address_only = re.capture($u.network.email.to , "(.*)@")

  // Use function-placeholder assignment to normalize an email:
  // address@-> address@company.com
  $email_from_normalized = strings.concat(
      re.capture($u.network.email.from , "(.*)@"),
      "@company.com"
  )

  // Use function-placeholder assignment to get the day of the week of the event.
  // 1 = Sunday, 7 = Saturday.
  $dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)

match:
  // Use placeholder (from function-placeholder assignment) in match section.
  // Group by the normalized from email, and expose it in the detection.
  $email_from_normalized over 5m

outcome:
  // Use placeholder (from function-placeholder assignment) in outcome section.
  // Assign more risk if the event happened on weekend.
  $risk_score = max(
      if($dayofweek = 1 or $dayofweek = 7, 10, 0)
  )

condition:
  // Use placeholder (from function-placeholder assignment) in condition section.
  // Match if an email was sent to multiple addresses.
  #email_to_address_only > 1
}

Telusuri

metadata.event_type = "EMAIL_TRANSACTION"

// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
  re.capture(network.email.to , "(.*)@"),
  "@company.com"
  )

// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)

match:
  // Use placeholder (from function-placeholder assignment) in match section.
  // Group by the normalized from email, and expose it in the detection.
  $email_from_normalized over 5m

outcome:
  // Use placeholder (from function-placeholder assignment) in outcome section.
  // Assign more risk if the event happened on weekend.
  $risk_score = max(
    if($dayofweek = 1 or $dayofweek = 7, 10, 0)
    )

condition:
  // Use placeholder (from function-placeholder assignment) in condition section.
  // Match if an email was sent to multiple addresses.
  #email_to_address_only > 1

Dasbor

Contoh berikut menunjukkan varian Dasbor yang dioptimalkan untuk visualisasi deret waktu. Dengan menggunakan rentang waktu bergulir satu hari, bukan perincian tingkat menit, kueri ini menghasilkan titik data yang stabil dan tidak tumpang-tindih yang ideal untuk memetakan skor risiko selama jangka waktu yang lebih lama. Logika ini menormalisasi entitas email dan menerapkan bobot risiko yang lebih tinggi pada transaksi akhir pekan, sehingga memberikan tren harian yang jelas tentang aktivitas email yang mencurigakan untuk pemantauan jangka panjang.

metadata.event_type = "EMAIL_TRANSACTION"

// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture(network.email.from , "(.*)@")

// Use function-placeholder assignment to normalize an email:
// address@??? -> address@company.com
$email_from_normalized = strings.concat(
re.capture(network.email.to , "(.*)@"),
"@company.com"
)

// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week(metadata.event_timestamp.seconds)

match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m

outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
  if($dayofweek = 1 or $dayofweek = 7, 10, 0)
  )

condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1

Pengoptimalan dan pemfilteran

Pengoptimalan aturan yang efektif mengandalkan pemfilteran data yang akurat untuk memastikan mesin deteksi hanya memproses informasi yang bermakna. Dengan mengecualikan data yang "berisik" atau tidak lengkap, Anda dapat meningkatkan performa aturan secara signifikan dan memastikan bahwa pemberitahuan yang dihasilkan dapat ditindaklanjuti.

Topik Contoh
Pengecualian nilai nol Pengecualian nilai nol eksplisit dan implisit

Pengecualian nilai nol

Kasus penggunaan: Pastikan akurasi aturan dan kurangi positif palsu dengan memfilter string kosong, nilai null, atau akun placeholder generik (misalnya, "Tamu") yang tidak memberikan data keamanan yang dapat ditindaklanjuti secara eksplisit.

Logika utama: Memanfaatkan pemfilteran implisit nilai nol oleh Mesin Aturan untuk variabel yang digunakan di bagian match, sekaligus menggunakan operator ketidaksetaraan eksplisit (!= "") untuk kolom peristiwa lainnya guna memastikan hanya data yang terisi yang memicu deteksi.

Mesin Aturan secara implisit memfilter nilai nol untuk semua placeholder yang digunakan di bagian match. Gunakan opsi allow_zero_values untuk menonaktifkan. Namun, untuk kolom peristiwa lain yang direferensikan, nilai nol tidak akan dikecualikan kecuali jika Anda menentukan kondisi tersebut secara eksplisit. Untuk mengetahui informasi selengkapnya, lihat Nilai nol di bagian pencocokan.

Contoh: Pengecualian nilai nol eksplisit dan implisit

Aturan

rule ExcludeZeroValues {
meta:
  author = "alice@example.com"

events:
  $e1.metadata.event_type = "NETWORK_DNS"
  $e1.principal.hostname = $hostname

  // $e1.principal.user.userid may be empty string.
  $e1.principal.user.userid != "Guest"

  $e2.metadata.event_type = "NETWORK_HTTP"
  $e2.principal.hostname = $hostname

  // $e2.target.asset_id cannot be empty string as explicitly specified.
  $e2.target.asset_id != ""

match:
  // $hostname cannot be empty string. The rule behaves as if the
  // predicate, `$hostname != ""` was added to the events section, because
  // `$hostname` is used in the match section.
  $hostname over 1h

condition:
  $e1 and $e2
}

Telusuri

Anda harus menyatakan secara eksplisit bahwa hostname tidak boleh berupa string kosong karena tidak ada filter nilai nol implisit untuk placeholder di bagian match.

$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname

// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"

$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname

// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

Dasbor

Anda harus menyatakan secara eksplisit bahwa hostname tidak boleh berupa string kosong karena tidak ada filter nilai nol implisit untuk placeholder di bagian match.

$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname

// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"

$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname

// $e2.target.asset_id and hostname cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
$hostname != ""

match:
  $hostname over 1h

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