Merhaba arkadaslar,
Sunucularda en sik gozden kacan savunma katmanlarindan biri dosya butunlugu izlemesi (File Integrity Monitoring, FIM). Pahali bir urun almadan, standart kutuphanelerle kendi basit FIM aracinizi yazabilirsiniz. Bu konuda hashlib ile calisan, harici bagimliligi olmayan kucuk bir script uzerinden mantigi anlatacagim.
Konuda Anlatilacaklar
- FIM nedir, neden onemlidir?
- Hangi dizinleri izlemeli?
- Baseline (referans) olusturma
- Degisiklik tespiti ve raporlama
- Zamanlama (cron) ve sinirlar
1) FIM Nedir, Neden Onemli?
FIM, kritik dosyalarin icerik ozetini (hash) belirli araliklarla hesaplayip referans degerle karsilastirir. Bir saldirgan /etc/passwd, bir web uygulamasinin index dosyasi veya bir systemd servis dosyasini degistirdiginde fark aninda ortaya cikar. Mantik basit: once temiz bir referans al, sonra duzenli olarak karsilastir. Kurumsal dunyada AIDE veya Tripwire bu isi yapar; buradaki amac mantigi ogrenmek.
2) Baseline Olusturma
Once izlenecek dizinleri tarayip her dosyanin SHA-256 ozetini bir JSON dosyasina yaziyoruz.
import hashlib, os, json, sys, time
def sha256(path, chunk=65536):
h = hashlib.sha256()
with open(path, "rb") as f:
for block in iter(lambda: f.read(chunk), b""):
h.update(block)
return h.hexdigest()
def scan(roots):
db = {}
for root in roots:
for dirpath, _, files in os.walk(root):
for name in files:
p = os.path.join(dirpath, name)
try:
db[p] = sha256(p)
except (PermissionError, FileNotFoundError):
continue
return dbBuyuk dosyalari parca parca okudugumuza dikkat edin; boylece bellek sismaz.
3) Degisiklik Tespiti
Baseline ile guncel tarama arasindaki farki uc kumeye ayiriyoruz: eklenen, silinen ve degisen dosyalar.
def diff(old, new):
old_k, new_k = set(old), set(new)
added = new_k - old_k
removed = old_k - new_k
changed = {k for k in old_k & new_k if old[k] != new[k]}
return added, removed, changed
if __name__ == "__main__":
ROOTS = ["/etc", "/var/www"]
DB = "/var/lib/fim/baseline.json"
if "--baseline" in sys.argv:
os.makedirs(os.path.dirname(DB), exist_ok=True)
json.dump(scan(ROOTS), open(DB, "w"))
print("Baseline olusturuldu.")
else:
old = json.load(open(DB))
a, r, c = diff(old, scan(ROOTS))
for tag, s in (("EKLENDI", a), ("SILINDI", r), ("DEGISTI", c)):
for p in sorted(s):
print(f"[{tag}] {p}")4) Zamanlama
Scripti saatlik calistirmak icin basit bir cron satiri:
0 * * * * /usr/bin/python3 /opt/fim/fim.py >> /var/log/fim.log 2>&1Ciktida DEGISTI satiri gorurseniz once mesru bir guncelleme mi (paket yukseltmesi, deploy) diye bakin; degilse incelemeye alin.
5) Sinirlar
Bu script bir baslangic noktasidir. Gercek ortamda baseline dosyasini salt-okunur veya ayri bir yerde tutun; saldirgan hem dosyayi hem baseline'i degistirebilir. Ayrica cok degisen dizinleri (log, cache) izleme disinda birakin, yoksa gurultu olur. Uretim icin AIDE gibi olgun araclara gecmenizi oneririm.
Kaynaklar
Alıntı:Yasal not: Scripti yalnizca kendi sunucularinizda veya yetkili oldugunuz sistemlerde calistirin.
Kolay gelsin.