Python ile Anti-Spyware yazımı.

Python ile Anti-Spyware Yazımı: Temelden Modüler Bir Güvenlik Aracına
Giriş
Spyware, kullanıcının bilgisi veya açık onayı dışında cihaz üzerindeki faaliyetleri izlemeye, bilgi toplamaya veya bu bilgileri başka sistemlere aktarmaya çalışan zararlı yazılım kategorilerinden biridir.
Bir spyware örneği farklı amaçlarla tasarlanabilir. Örneğin sistem hakkında bilgi toplayabilir, belirli dosyaları araştırabilir, kullanıcı oturumlarında kalıcılık sağlamaya çalışabilir veya uzak bir sunucuyla iletişim kurabilir.
Bu eğitimde Python kullanarak temel seviyede bir anti-spyware aracının nasıl tasarlanabileceğini inceleyeceğiz.
Amaç ticari antivirüs ürünleriyle yarışan bir sistem geliştirmek değildir. Böyle bir ürün; kernel seviyesinde görünürlük, sürücüler, davranış analizi motorları, bulut tabanlı tehdit istihbaratı, sandbox sistemleri, makine öğrenmesi modelleri ve büyük miktarda zararlı yazılım verisi gerektirir.
Buradaki hedef daha temeldir:
Çalışan süreçleri incelemek
Süreçlerin çalıştırılabilir dosya yollarını analiz etmek
Dosyaların hash değerlerini hesaplamak
Başlangıçta çalışan programları kontrol etmek
Aktif ağ bağlantılarını incelemek
Belirli dizinlerde dosya değişikliklerini takip etmek
Basit bir risk puanlama sistemi oluşturmak
Modüler bir güvenlik aracı mimarisi kurmak
Bu proje sayesinde yalnızca Python değil, aynı zamanda endpoint security mantığı hakkında da önemli bilgiler öğrenilebilir.
1. Anti-Spyware Nasıl Çalışır?
Bir anti-spyware sistemi tek bir yöntem kullanmaz.
Gerçek güvenlik ürünlerinde genellikle birden fazla tespit yaklaşımı birlikte kullanılır.
Bunları temel olarak şu kategorilere ayırabiliriz.
1.1 İmza Tabanlı Tespit
Bilinen zararlı dosyaların hash değerleri veya belirli karakteristik özellikleri bir veritabanında tutulabilir.
Örneğin:
SHA-256(Dosya) -> Bilinen zararlı mı?
Bir dosyanın SHA-256 değeri bilinen bir zararlı örneğinin hash değeriyle eşleşirse dosya şüpheli olarak işaretlenebilir.
Avantajı hızlı olmasıdır.
Dezavantajı ise dosyada yapılan küçük bir değişikliğin hash değerini tamamen değiştirebilmesidir.
Bu nedenle modern güvenlik sistemleri yalnızca hash kontrolüne güvenmez.
1.2 Davranış Tabanlı Tespit
Burada programın ne olduğundan çok ne yaptığı incelenir.
Örneğin bir süreç:
Kullanıcı oturumu açıldığında otomatik çalışıyorsa,
Alışılmadık bir dizinden çalışıyorsa,
Sürekli dış bağlantılar kuruyorsa,
Kısa süre içerisinde birçok dosyaya erişiyorsa,
bu davranışların kombinasyonu riskli kabul edilebilir.
Tek bir davranış her zaman zararlı anlamına gelmez.
Örneğin bir programın internet bağlantısı kurması normaldir. Bir tarayıcı, oyun istemcisi veya mesajlaşma uygulaması da ağ bağlantısı kurar.
Önemli olan bağlamdır.
1.3 Sezgisel Analiz
Heuristic analysis olarak da bilinir.
Bir dosya veya süreç hakkında farklı sinyaller toplanır ve bunlardan bir risk puanı oluşturulur.
Örnek:
Şüpheli dizinden çalışma: +20
Başlangıç girdisinde bulunma: +15
İmzasız veya bilinmeyen dosya: +15
Çok sayıda uzak bağlantı: +10
Bilinen zararlı hash eşleşmesi: +100
Toplam puan belirli bir sınırı geçerse alarm oluşturulabilir.
Bu yaklaşımın en önemli problemi false positive, yani yanlış pozitif sonuçlardır.
Bu nedenle anti-spyware geliştirirken şu prensip unutulmamalıdır:
Şüpheli davranış ile zararlı davranış aynı şey değildir.
2. Proje Mimarisi
Projeyi tek bir dev Python dosyasına yazmak mümkündür ancak iyi bir yaklaşım değildir.
Daha düzenli bir mimari şöyle olabilir:
anti_spyware/ main.py scanner/ process_scanner.py startup_scanner.py network_scanner.py file_scanner.py core/ hashing.py risk_engine.py logger.py data/ known_hashes.json logs/ scan.log
Bu yapı sayesinde her modül tek bir görevden sorumlu olur.
Örneğin:
process_scanner.py
Sistemde çalışan süreçleri inceler.
startup_scanner.py
Otomatik başlangıç girdilerini inceler.
network_scanner.py
Aktif bağlantıları listeler.
file_scanner.py
Belirlenen klasörlerdeki dosyaları tarar.
risk_engine.py
Toplanan bulgulara puan verir.
Bu yaklaşım yazılım mühendisliğinde separation of concerns prensibine yakındır.
3. Gerekli Python Kütüphaneleri
Bu projede temel olarak şu modüllerden yararlanabiliriz:
pathlib
hashlib
json
logging
time
os
psutil
psutil, çalışan süreçler ve ağ bağlantıları gibi sistem bilgilerine erişmek için oldukça kullanışlıdır.
Kurulum:
pip install psutil
Şimdi ilk modülümüzü yazmaya başlayabiliriz.
4. Dosya Hash Hesaplama Sistemi
Bir dosyanın kimliğini belirlemek için kriptografik hash fonksiyonlarından yararlanabiliriz.
Bu projede SHA-256 kullanacağız.
hashing.py:
import hashlib
from pathlib import Path


def calculate_sha256(file_path, chunk_size=8192):
path = Path(file_path)

if not path.is_file():
return None

sha256 = hashlib.sha256()

try:
with path.open("rb") as file:
while True:
chunk = file.read(chunk_size)

if not chunk:
break

sha256.update(chunk)

return sha256.hexdigest()

except (PermissionError, OSError):
return None
Burada dosyanın tamamını tek seferde belleğe yüklemiyoruz.
Bunun yerine dosyayı parçalar halinde okuyoruz.
Neden?
Çünkü 5 GB büyüklüğünde bir dosyayı:
file.read()
ile tamamen belleğe almaya çalışmak gereksiz RAM kullanımına neden olabilir.
Chunk tabanlı okuma daha güvenlidir.
Algoritma şu şekildedir:
Dosyayı binary modda aç.
Belirli büyüklükte veri oku.
Hash nesnesini güncelle.
Dosyanın sonuna kadar devam et.
Hexadecimal hash değerini döndür.
5. Basit Hash Veritabanı
Örnek JSON yapısı:
{
"hashes": [
"example_sha256_hash_1",
"example_sha256_hash_2"
]
}
Python tarafında:
import json


def load_hash_database(database_path):
try:
with open(database_path, "r", encoding="utf-8") as file:
data = json.load(file)

return set(data.get("hashes", []))

except (FileNotFoundError, json.JSONDecodeError):
return set()
Burada list yerine set kullanmak önemlidir.
Çünkü üyelik kontrolünde:
file_hash in hash_set
işlemi ortalama durumda oldukça hızlıdır.
Büyük veri kümelerinde veri yapısı seçimi performansı ciddi şekilde etkiler.
6. Çalışan Süreçlerin Taranması
Spyware tespiti için önemli veri kaynaklarından biri çalışan süreçlerdir.
psutil ile süreçleri inceleyebiliriz.
import psutil


def scan_processes():
processes = []

for process in psutil.process_iter(
["pid", "name", "exe", "username"]
):
try:
info = process.info

processes.append({
"pid": info.get("pid"),
"name": info.get("name"),
"exe": info.get("exe"),
"username": info.get("username")
})

except (
psutil.NoSuchProcess,
psutil.AccessDenied,
psutil.ZombieProcess
):
continue

return processes
Burada önemli bir nokta vardır.
Sistem üzerindeki her sürece erişim iznimiz olmayabilir.
Bu nedenle güvenlik araçlarında hata yönetimi kritik öneme sahiptir.
Şu yaklaşım kötü bir yaklaşımdır:
for process in psutil.process_iter():
print(process.exe())
Çünkü tek bir AccessDenied hatası bütün taramayı durdurabilir.
Bunun yerine her süreç bağımsız olarak işlenmelidir.
7. Süreç Dosyalarının Hash Kontrolü
Şimdi çalışan süreçlerin executable dosyalarını hash veritabanıyla karşılaştıralım.
def check_process_hashes(processes, known_hashes):
detections = []

for process in processes:
exe_path = process.get("exe")

if not exe_path:
continue

file_hash = calculate_sha256(exe_path)

if file_hash and file_hash in known_hashes:
detections.append({
"pid": process["pid"],
"name": process["name"],
"path": exe_path,
"hash": file_hash,
"reason": "Known hash match"
})

return detections
Buradaki akış:
Process Enumeration | v Executable Path | v SHA-256 Calculation | v Hash Database Lookup | v Match? /
YES NO | | Alert Continue
Bu basit bir signature detection pipeline örneğidir.
8. Şüpheli Çalışma Dizinlerinin Analizi
Bir uygulamanın çalıştığı konum risk değerlendirmesinde sinyal olarak kullanılabilir.
Örneğin geçici klasörlerden veya kullanıcı tarafından yazılabilir bazı klasörlerden çalışan programlar daha dikkatli incelenebilir.
Ancak burada önemli bir uyarı vardır:
Bu klasörlerden çalışan her yazılım zararlı değildir.
Bu nedenle doğrudan "malware" etiketi koymak yerine risk puanı artırılmalıdır.
from pathlib import Path


SUSPICIOUS_DIRECTORY_NAMES = {
"temp",
"tmp"
}


def path_risk_score(file_path):
if not file_path:
return 0

path = Path(file_path)

parts = {part.lower() for part in path.parts}

score = 0

if parts.intersection(SUSPICIOUS_DIRECTORY_NAMES):
score += 20

return score
Bu çok temel bir örnektir.
Gerçek sistemlerde:
Dosyanın dijital imzası
Dosyanın yaşı
Dosyanın oluşturulma zamanı
Parent process
Child process
Dosyanın yaygınlığı
Reputation bilgisi
gibi birçok sinyal birlikte değerlendirilir.
9. Parent-Child Process İlişkisi
Süreç analizinde yalnızca process adına bakmak yeterli değildir.
Bir sürecin kim tarafından başlatıldığı da önemlidir.
Örneğin süreç ağacı şöyle olabilir:
explorer.exe | +-- application.exe | +-- helper.exe
Bu normal olabilir.
Süreç ilişkilerini toplamak için:
import psutil


def get_process_tree_info():
results = []

for process in psutil.process_iter(
["pid", "ppid", "name", "exe"]
):
try:
info = process.info

results.append({
"pid": info["pid"],
"ppid": info["ppid"],
"name": info["name"],
"exe": info["exe"]
})

except (
psutil.NoSuchProcess,
psutil.AccessDenied,
psutil.ZombieProcess
):
continue

return results
Burada:
PID = Process ID
PPID = Parent Process ID
anlamına gelir.
Daha gelişmiş bir analiz motoru parent-child ilişkilerine ayrı puanlar verebilir.
Ancak sadece süreç isimlerine bakarak kesin karar vermek doğru değildir. Aynı isim farklı yazılımlar tarafından kullanılabilir ve meşru sistem davranışları bilgisayarlar arasında değişebilir.
10. Ağ Bağlantılarının İncelenmesi
Spyware türlerinin önemli bir bölümü topladığı veriyi başka bir sisteme göndermeye çalışabilir.
Bu nedenle aktif bağlantılar önemli bir telemetry kaynağıdır.
import psutil


def scan_network_connections():
results = []

try:
connections = psutil.net_connections(kind="inet")

except psutil.AccessDenied:
return results

for connection in connections:
remote_address = None

if connection.raddr:
remote_address = {
"ip": connection.raddr.ip,
"port": connection.raddr.port
}

results.append({
"pid": connection.pid,
"status": connection.status,
"remote": remote_address
})

return results
Burada önemli bir ayrım vardır:
Bir programın internet bağlantısı kurması tek başına zararlı davranış değildir.
Örneğin:
Tarayıcılar
Oyun istemcileri
Mesajlaşma uygulamaları
Güncelleme servisleri
Bulut senkronizasyon yazılımları
normal olarak dış sistemlerle bağlantı kurar.
Bu nedenle bağlantı verisi diğer sinyallerle birleştirilmelidir.
11. PID ile Ağ Bağlantısını Süreçle Eşleştirme
Bir ağ bağlantısının hangi süreç tarafından oluşturulduğunu incelemek faydalıdır.
def enrich_connection(connection):
pid = connection.get("pid")

if pid is None:
return connection

try:
process = psutil.Process(pid)

connection["process_name"] = process.name()
connection["process_path"] = process.exe()

except (
psutil.NoSuchProcess,
psutil.AccessDenied
):
connection["process_name"] = None
connection["process_path"] = None

return connection
Artık bağlantı çıktısı şöyle olabilir:
PID: 4820
Process: example.exe
Remote IP: 203.0.113.10
Remote Port: 443
Status: ESTABLISHED
Buradaki örnek IP dokümantasyon amacıyla kullanılan örnek adres alanındandır.
12. Başlangıç Programlarının İncelenmesi
Kalıcılık mekanizmaları endpoint güvenliğinde önemli bir inceleme alanıdır.
Windows sistemlerinde başlangıç girdilerinin bir kısmı Registry içerisinde bulunabilir.
Python'un standart kütüphanesinde bulunan winreg modülüyle belirli kullanıcı başlangıç girdileri okunabilir.
import winreg


def read_user_run_entries():
entries = []

registry_path = (
r"Software\Microsoft\Windows\CurrentVersion\Run"
)

try:
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
registry_path,
0,
winreg.KEY_READ
)

index = 0

while True:
try:
name, value, _ = winreg.EnumValue(key, index)

entries.append({
"name": name,
"command": value
})

index += 1

except OSError:
break

winreg.CloseKey(key)

except OSError:
pass

return entries
Bu kod yalnızca mevcut kullanıcı bağlamındaki belirli bir başlangıç konumunu okur.
Gerçek bir persistence scanner çok daha geniş bir yüzeyi incelemelidir.
Örneğin:
Kullanıcı başlangıç girdileri
Sistem başlangıç girdileri
Startup klasörleri
Scheduled tasks
Services
Browser extensions
WMI tabanlı kalıcılık mekanizmaları
Ancak bu eğitim kapsamında önce temel ve okunabilir bir yapı kuruyoruz.
13. Startup Komutlarının Analizi
Registry'den aldığımız değer her zaman doğrudan temiz bir dosya yolu olmayabilir.
Örneğin:
"C:\Program Files\Example\app.exe" --background
Burada executable yolunu komut satırından ayırmak gerekir.
Bu işlem ilk bakışta kolay görünse de Windows komut satırı ayrıştırma kuralları nedeniyle üretim seviyesinde dikkatli yapılmalıdır.
Basit eğitim örneği:
import shlex


def parse_command(command):
try:
parts = shlex.split(command, posix=False)

if not parts:
return None

return parts[0].strip('"')

except ValueError:
return None
Daha gelişmiş bir sürümde Windows'a özgü command-line parsing davranışları ayrıca ele alınmalıdır.
14. Dosya Sistemi Taraması
Belirli bir klasördeki dosyaları tarayan temel bir scanner yazabiliriz.
from pathlib import Path


def scan_directory(directory, known_hashes):
detections = []

root = Path(directory)

if not root.exists():
return detections

for path in root.rglob("*"):
if not path.is_file():
continue

file_hash = calculate_sha256(path)

if file_hash and file_hash in known_hashes:
detections.append({
"path": str(path),
"hash": file_hash
})

return detections
Buradaki:
root.rglob("*")
ifadesi alt klasörler dahil recursive tarama yapar.
Ancak büyük disklerde her dosyanın hash değerini hesaplamak maliyetlidir.
Bu nedenle gerçek ürünlerde optimizasyon yapılır.
Örneğin:
Dosya türünü kontrol et.
Dosya boyutunu kontrol et.
Metadata incele.
Reputation kontrolü yap.
Gerekiyorsa hash hesapla.
Daha derin analiz gerekiyorsa sandbox veya statik analiz sistemine gönder.
Her dosyaya aynı maliyetli işlemi uygulamak ölçeklenebilir değildir.
15. Dosya Değişikliklerini İzlemek
Anti-spyware aracımızın yalnızca manuel tarama yapması yerine belirli dizinlerdeki değişiklikleri fark etmesini isteyebiliriz.
Basit bir yöntem snapshot karşılaştırmasıdır.
from pathlib import Path


def create_snapshot(directory):
snapshot = {}

root = Path(directory)

if not root.exists():
return snapshot

for path in root.rglob("*"):
if not path.is_file():
continue

try:
stat = path.stat()

snapshot[str(path)] = {
"size": stat.st_size,
"mtime": stat.st_mtime
}

except OSError:
continue

return snapshot
İki snapshot karşılaştırılabilir:
def compare_snapshots(old, new):
old_paths = set(old)
new_paths = set(new)

created = new_paths - old_paths
deleted = old_paths - new_paths

modified = set()

for path in old_paths & new_paths:
if old[path] != new[path]:
modified.add(path)

return {
"created": created,
"deleted": deleted,
"modified": modified
}
Bu yöntem eğitim açısından anlaşılırdır ancak çok büyük dizinlerde sürekli tam tarama yapmak verimsiz olabilir.
Üretim seviyesinde işletim sisteminin sunduğu dosya sistemi olay mekanizmalarından yararlanmak daha mantıklıdır.
16. Risk Puanlama Motoru
Şimdi projenin önemli kısmına gelelim.
Her sinyali tek başına kesin karar olarak kullanmak yerine puanlayabiliriz.
Örnek:
def calculate_risk_score(
hash_match=False,
suspicious_path=False,
startup_entry=False,
active_remote_connections=0
):
score = 0
reasons = []

if hash_match:
score += 100
reasons.append("Known malicious hash match")

if suspicious_path:
score += 20
reasons.append("Suspicious execution path")

if startup_entry:
score += 15
reasons.append("Startup persistence entry")

if active_remote_connections >= 5:
score += 10
reasons.append("Multiple active remote connections")

return {
"score": score,
"reasons": reasons
}
Sonuç:
Risk Score: 45

Reasons:
- Suspicious execution path
- Startup persistence entry
- Multiple active remote connections
Bu noktada program:
if score >= 100:
verdict = "HIGH RISK"

elif score >= 50:
verdict = "SUSPICIOUS"

else:
verdict = "LOW RISK"
şeklinde sınıflandırma yapabilir.
Ancak bu eşikler tamamen örnektir.
Gerçek bir tespit motorunda eşikler test verileriyle ayarlanmalıdır.
17. Neden Risk Puanlama Kullanıyoruz?
Şöyle bir süreç düşünelim:
Program A:
Temp klasöründen çalışıyor.
Bu tek başına zararlı olduğunu kanıtlamaz.
Program B:
Temp klasöründen çalışıyor.
Startup girdisinde bulunuyor.
Bilinmeyen uzak sistemlerle sürekli bağlantı kuruyor.
Dosya hash değeri tehdit veritabanında eşleşiyor.
Burada sinyallerin birleşimi çok daha güçlüdür.
Güvenlik analizi çoğu zaman tek bir kanıttan değil, farklı telemetry kaynaklarının korelasyonundan oluşur.
Bu yaklaşım SIEM, EDR ve XDR sistemlerinde de önemlidir.
18. Logging Sistemi
Bir güvenlik aracında bulguların kaydedilmesi gerekir.
Python logging modülü kullanılabilir.
import logging


logging.basicConfig(
filename="scan.log",
level=logging.INFO,
format=(
"%(asctime)s | "
"%(levelname)s | "
"%(message)s"
)
)


def log_detection(message):
logging.warning(message)


def log_info(message):
logging.info(message)
Örneğin:
log_detection(
"Suspicious process detected: example.exe"
)
Log çıktısı:
2026-07-05 14:32:18 | WARNING | Suspicious process detected: example.exe
Loglar olay inceleme sırasında son derece değerlidir.
Çünkü güvenlik analizinde yalnızca:
"Şu anda ne oluyor?"
sorusu değil,
"Daha önce ne oldu?"
sorusu da önemlidir.
19. JSON Raporlama
Sonuçları JSON formatında kaydetmek daha sonra başka sistemlerle entegrasyonu kolaylaştırabilir.
import json
from datetime import datetime


def save_report(results, output_file):
report = {
"scan_time": datetime.now().isoformat(),
"results": results
}

with open(output_file, "w", encoding="utf-8") as file:
json.dump(
report,

🔒 Bu içeriği görmek için giriş yapın

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
133,663Konular
3,288,262Mesajlar
324,335Kullanıcılar
hbi14Son Üye
Üst Alt