Wazuh ve YARA ile Zararlı Tespit ve Karantina
Berra Söyler · @berriesyl
Wazuh ve YARA birlikte kullanıldığında yeni veya değişen dosyalar event-driven olarak taranabilir. Bu çalışmada Wazuh File Integrity Monitoring (FIM) ile değişikliği yakalıyor, Active Response üzerinden YARA taramasını başlatıyor, sonucu alerta dönüştürüyor ve pozitif eşleşen dosyayı kontrollü bir dizine taşıyoruz.
Bileşenler
| Bileşen | Görevi |
|---|---|
| Wazuh FIM | İzlenen dizindeki dosya ekleme ve değişikliklerini algılar |
| Wazuh Active Response | Belirli bir rule eşleştiğinde endpoint üzerinde script çalıştırır |
| YARA | Dosyayı tanımlı metin veya binary kalıplarıyla eşleştirir |
| Decoder ve local rules | YARA çıktısını parse eder ve alerta dönüştürür |
| Karantina dizini | YARA rule'u ile eşleşen dosyayı normal çalışma yolundan ayırır |
1. Endpoint Hazırlığı
Ubuntu üzerinde Wazuh agent'ın kurulu ve manager'a bağlı olduğu bir lab kullanıyoruz. Gerekli paketleri kurup çalışma dizinlerini hazırlıyoruz:
sudo apt update
sudo apt install -y yara jq
sudo install -d -m 0750 /tmp/yara/rules
sudo install -d -m 0750 /tmp/yara/malware
sudo install -d -m 0700 /var/ossec/quarantine
yara --versionYARA rule'larını sürümlüyor, imza ve hash değerlerini doğruluyoruz.
Zararsız test rule'u
Akışı gerçek zararlı örnek indirmeden sınamak için yalnızca belirli bir test işaretini arayan local bir YARA rule'u kullanıyoruz:
rule Altay_Yara_Lab_Test
{
meta:
description = "Wazuh-YARA entegrasyonu icin zararsiz test kurali"
author = "Altay"
strings:
$marker = "ALTAY_YARA_TEST_2026" ascii wide
condition:
$marker
}Rule'u /tmp/yara/rules/altay-lab.yar olarak kaydedip syntax'ı doğruluyoruz:
sudo yara -w /tmp/yara/rules/altay-lab.yar /dev/null2. FIM Event'ini Active Response'a Bağlama
Wazuh agent üzerindeki /var/ossec/etc/ossec.conf dosyasının <syscheck> bölümüne izleyeceğimiz dizini ekliyoruz:
<directories realtime="yes">/tmp/yara/malware</directories>
Ardından agent'ı yeniden başlatıyoruz:
sudo systemctl restart wazuh-agentManager üzerindeki /var/ossec/etc/rules/local_rules.xml dosyasına lab dizinini izleyen iki local rule ekliyoruz:
<group name="syscheck,">
<rule id="100300" level="7">
<if_sid>550</if_sid>
<field name="file" type="pcre2">^/tmp/yara/malware/</field>
<description>File modified in /tmp/yara/malware.</description>
</rule>
<rule id="100301" level="7">
<if_sid>554</if_sid>
<field name="file" type="pcre2">^/tmp/yara/malware/</field>
<description>File added to /tmp/yara/malware.</description>
</rule>
</group>
Rule ID'lerin başka local rule'larla çakışmadığını kontrol ediyoruz. 100300 veya 100301 zaten kullanılıyorsa boş bir custom rule aralığı seçiyoruz.
3. YARA Active Response Betiği
Aşağıdaki betik Wazuh'un gönderdiği JSON içinden dosya yolunu ve YARA parametrelerini alır. Dosyanın yalnızca lab dizini altında olduğunu doğrular, YARA'yı çalıştırır ve eşleşme varsa dosyayı root erişimli karantina dizinine taşır.
Betiği /var/ossec/active-response/bin/yara.sh yolunda oluşturuyoruz:
#!/usr/bin/env bash
set -u
LOG_FILE="/var/ossec/logs/active-responses.log"
QUARANTINE_PATH="/var/ossec/quarantine"
MONITORED_PREFIX="/tmp/yara/malware/"
read -r INPUT_JSON
YARA_PATH=$(jq -er '.parameters.extra_args[1]' <<<"$INPUT_JSON") || exit 1
YARA_RULES=$(jq -er '.parameters.extra_args[3]' <<<"$INPUT_JSON") || exit 1
FILENAME=$(jq -er '.parameters.alert.syscheck.path' <<<"$INPUT_JSON") || exit 1
case "$FILENAME" in
"$MONITORED_PREFIX"*) ;;
*)
printf 'wazuh-yara: ERROR - Path outside monitored directory: %s\n' \
"$FILENAME" >>"$LOG_FILE"
exit 1
;;
esac
if [[ ! -x "$YARA_PATH/yara" || ! -r "$YARA_RULES" || ! -f "$FILENAME" ]]; then
printf 'wazuh-yara: ERROR - Invalid executable, rules, or target file.\n' \
>>"$LOG_FILE"
exit 1
fi
# Yazımı süren dosyanın boyutu sabitlenene kadar en fazla 10 saniye bekle.
previous_size=-1
for _ in {1..10}; do
current_size=$(stat -c '%s' -- "$FILENAME") || exit 1
[[ "$current_size" == "$previous_size" ]] && break
previous_size="$current_size"
sleep 1
done
yara_output=$("$YARA_PATH/yara" -w -r "$YARA_RULES" "$FILENAME" 2>&1)
yara_status=$?
if (( yara_status > 1 )); then
printf 'wazuh-yara: ERROR - Scan failed: %s\n' "$yara_output" >>"$LOG_FILE"
exit "$yara_status"
fi
if [[ -n "$yara_output" ]]; then
while IFS= read -r line; do
printf 'wazuh-yara: INFO - Scan result: %s\n' "$line" >>"$LOG_FILE"
done <<<"$yara_output"
install -d -m 0700 "$QUARANTINE_PATH"
destination="$QUARANTINE_PATH/$(date -u +%Y%m%dT%H%M%SZ)-$(basename -- "$FILENAME")"
mv -- "$FILENAME" "$destination"
chmod 000 "$destination"
printf 'wazuh-yara: INFO - File quarantined: %s -> %s\n' \
"$FILENAME" "$destination" >>"$LOG_FILE"
fi
exit 0Betik izinlerini ayarlıyoruz:
sudo chown root:wazuh /var/ossec/active-response/bin/yara.sh
sudo chmod 750 /var/ossec/active-response/bin/yara.sh4. Manager Active Response Yapılandırması
Wazuh manager üzerindeki /var/ossec/etc/ossec.conf dosyasına komut ve onu çalıştıracak Rule ID'leri ekliyoruz:
<command>
<name>yara_linux</name>
<executable>yara.sh</executable>
<extra_args>-yara_path /usr/bin -yara_rules /tmp/yara/rules/altay-lab.yar</extra_args>
<timeout_allowed>no</timeout_allowed>
</command>
<active-response>
<command>yara_linux</command>
<location>local</location>
<rules_id>100300,100301</rules_id>
</active-response>
location değerini local vererek komutun olayı üreten agent üzerinde çalışmasını sağlıyoruz.
5. Decoder ve Alert Kuralı
Manager üzerindeki /var/ossec/etc/decoders/local_decoder.xml dosyasına şu decoder'ları ekliyoruz:
<decoder name="yara_decoder">
<prematch>wazuh-yara:</prematch>
</decoder>
<decoder name="yara_decoder1">
<parent>yara_decoder</parent>
<regex>wazuh-yara: (\S+) - Scan result: (\S+) (\S+)</regex>
<order>log_type, yara_rule, yara_scanned_file</order>
</decoder>Manager üzerindeki /var/ossec/etc/rules/local_rules.xml dosyasına alert kurallarını ekliyoruz:
<group name="yara,">
<rule id="108000" level="0">
<decoded_as>yara_decoder</decoded_as>
<description>YARA grouping rule</description>
</rule>
<rule id="108001" level="12">
<if_sid>108000</if_sid>
<match type="pcre2">wazuh-yara: INFO - Scan result: </match>
<description>File "$(yara_scanned_file)" matched YARA rule "$(yara_rule)".</description>
</rule>
</group>
Bu basit decoder boşluk içermeyen lab yolları için uygundur. Üretimde boşluk, Unicode ve farklı YARA çıktı biçimleri içeren gerçek loglarla test edilerek regex ifadesini genişletiyoruz.
Değişiklikleri doğrulayıp manager'ı yeniden başlatıyoruz:
sudo /var/ossec/bin/wazuh-analysisd -t
sudo systemctl restart wazuh-manager6. Zararsız Test
Gerçek zararlı indirmek yerine YARA rule'undaki işareti taşıyan plain text dosyası oluşturuyoruz:
printf '%s\n' 'ALTAY_YARA_TEST_2026' | \
sudo tee /tmp/yara/malware/altay-test.txt >/dev/nullBeklenen zincir:
- FIM yeni dosyayı görür ve event
100301numaralı local rule ile eşleşir. - Active Response, endpoint üzerindeki
yara.shbetiğini çalıştırır. - Dosya
Altay_Yara_Lab_Testrule'u ile eşleşir. - Sonuç
active-responses.logdosyasına yazılır. - Dosya
/var/ossec/quarantinealtına taşınır ve erişim izinleri kapatılır. - Manager
108001seviyesinde alert üretir.
Endpoint üzerinde:
sudo tail -n 20 /var/ossec/logs/active-responses.log
sudo ls -la /var/ossec/quarantineTest bittikten sonra karantinadaki dosyayı silmeden veya geri yüklemeden önce hash ve alert kaydını saklıyoruz.
Üretimde Uyguladığımız Kontroller
- YARA kural paketini sürüm ve hash ile sabitliyoruz.
- Kural güncellemelerini ayrı bir CI ve onay akışından geçiriyoruz.
- Karantina dizinini ayrı disk kotası ve yalnızca root erişimiyle koruyoruz.
- Yanlış pozitifler için allowlist ve geri yükleme adımlarını tanımlıyoruz.
- Active Response olaylarını ayrıca izliyor, beklenmeyen betik çalıştırmalarını kritik alert olarak ele alıyoruz.
- Kuralları önce gözlem, sonra manuel onay, en son kontrollü otomasyon aşamasında devreye alıyoruz.

