Scanarea de malware prin WP-CLI este o metodă esențială pentru situațiile în care un plugin…

Script Python pentru detectarea modificărilor de fișiere
Script Python pentru detectarea modificărilor de fișiere. Monitorizarea integrității fișierelor WordPress este una dintre cele mai eficiente metode de detectare a compromiterilor, deoarece orice atac reușit implică modificarea, adăugarea sau ștergerea de fișiere pe server.
Un script Python dedicat calculează hash-urile fișierelor și le compară cu valorile de referință, alertându-vă imediat când detectează modificări neautorizate.
Script Python pentru detectarea modificărilor de fișiere
Monitorizarea integrității fișierelor (File Integrity Monitoring, FIM) funcționează prin crearea unui inventar de referință al tuturor fișierelor cu hash-urile lor. La fiecare verificare ulterioară, hash-urile actuale sunt comparate cu referința pentru a detecta modificări.
Vom construi un sistem FIM complet care detectează fișiere modificate, adăugate și șterse din instalarea WordPress.
Crearea inventarului de referință
import hashlib
import os
import json
import time
from datetime import datetime
from pathlib import Path
class FileIntegrityMonitor:
"""Monitor integritate fișiere WordPress."""
def __init__(self, wp_path, db_file='fim_baseline.json'):
self.wp_path = wp_path
self.db_file = db_file
self.baseline = {}
self.ignore_patterns = [
'wp-content/cache',
'wp-content/upgrade',
'wp-content/backup',
'wp-content/wflogs',
'*.log',
'*.tmp',
'error_log'
]
def should_ignore(self, filepath):
"""Verifică dacă fișierul trebuie ignorat."""
rel_path = os.path.relpath(filepath, self.wp_path)
for pattern in self.ignore_patterns:
if pattern.startswith('*'):
if filepath.endswith(pattern[1:]):
return True
elif pattern in rel_path:
return True
return False
def calculate_hash(self, filepath):
"""Calculează hash SHA-256 al unui fișier."""
sha256 = hashlib.sha256()
try:
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''):
sha256.update(chunk)
return sha256.hexdigest()
except (PermissionError, OSError):
return None
def create_baseline(self):
"""Creează inventarul de referință al tuturor fișierelor."""
print(f"Creare inventar referință: {self.wp_path}")
start_time = time.time()
file_count = 0
self.baseline = {
'created': datetime.now().isoformat(),
'wp_path': self.wp_path,
'files': {}
}
for root, dirs, files in os.walk(self.wp_path):
for filename in files:
filepath = os.path.join(root, filename)
if self.should_ignore(filepath):
continue
file_hash = self.calculate_hash(filepath)
if file_hash:
stat = os.stat(filepath)
rel_path = os.path.relpath(filepath, self.wp_path)
self.baseline['files'][rel_path] = {
'hash': file_hash,
'size': stat.st_size,
'mtime': stat.st_mtime,
'permissions': oct(stat.st_mode)[-3:]
}
file_count += 1
# Salvare pe disc
with open(self.db_file, 'w') as f:
json.dump(self.baseline, f, indent=2)
elapsed = round(time.time() - start_time, 2)
print(f"Inventar creat: {file_count} fișiere în {elapsed}s")
print(f"Salvat: {self.db_file}")
return file_count- SHA-256 oferă securitate criptografică pentru detectarea oricărei modificări
- Ignorarea directoarelor de cache previne alerte false frecvente
- Inventarul include hash-ul, dimensiunea, data modificării și permisiunile
- Procesarea pe blocuri de 8KB permite scanarea eficientă a fișierelor mari
Verificarea modificărilor
def load_baseline(self):
"""Încarcă inventarul de referință."""
try:
with open(self.db_file, 'r') as f:
self.baseline = json.load(f)
print(f"Inventar încărcat: {len(self.baseline['files'])} fișiere")
print(f"Creat la: {self.baseline['created']}")
return True
except FileNotFoundError:
print("EROARE: Inventar de referință nu există. Rulați create_baseline() mai întâi.")
return False
def check_integrity(self):
"""Verifică integritatea fișierelor contra inventarului."""
if not self.baseline:
if not self.load_baseline():
return None
report = {
'check_date': datetime.now().isoformat(),
'modified': [],
'added': [],
'deleted': [],
'permission_changed': []
}
baseline_files = set(self.baseline['files'].keys())
current_files = set()
# Verificare fișiere existente
for root, dirs, files in os.walk(self.wp_path):
for filename in files:
filepath = os.path.join(root, filename)
if self.should_ignore(filepath):
continue
rel_path = os.path.relpath(filepath, self.wp_path)
current_files.add(rel_path)
current_hash = self.calculate_hash(filepath)
if not current_hash:
continue
stat = os.stat(filepath)
current_perms = oct(stat.st_mode)[-3:]
if rel_path in self.baseline['files']:
baseline_info = self.baseline['files'][rel_path]
# Verificare hash (conținut modificat)
if current_hash != baseline_info['hash']:
report['modified'].append({
'file': rel_path,
'old_hash': baseline_info['hash'][:16] + '...',
'new_hash': current_hash[:16] + '...',
'old_size': baseline_info['size'],
'new_size': stat.st_size
})
# Verificare permisiuni
if current_perms != baseline_info['permissions']:
report['permission_changed'].append({
'file': rel_path,
'old_perms': baseline_info['permissions'],
'new_perms': current_perms
})
else:
# Fișier nou
report['added'].append({
'file': rel_path,
'size': stat.st_size,
'is_php': rel_path.endswith('.php')
})
# Fișiere șterse
deleted = baseline_files - current_files
for rel_path in deleted:
report['deleted'].append({'file': rel_path})
return report- Detectează patru categorii de modificări: conținut, fișiere noi, fișiere șterse, permisiuni
- Fișierele PHP noi în directorul uploads sunt un indicator puternic de compromitere
- Modificările de permisiuni pot indica activitate malițioasă
- Compararea hash-urilor detectează chiar și modificări de un singur octet
Generarea raportului și alertelor
def print_report(self, report):
"""Afișează raportul de integritate."""
sep = "=" * 60
print("n" + sep)
print(f"RAPORT INTEGRITATE FIȘIERE - {report['check_date']}")
print(sep)
total_changes = (len(report['modified']) + len(report['added']) +
len(report['deleted']) + len(report['permission_changed']))
if total_changes == 0:
print("nNicio modificare detectată. Toate fișierele sunt integre.")
return
print(f"nTOTAL MODIFICĂRI: {total_changes}")
if report['modified']:
print(f"nFIȘIERE MODIFICATE ({len(report['modified'])}):")
for item in report['modified']:
print(f" [MODIFICAT] {item['file']}")
print(f" Dimensiune: {item['old_size']} -> {item['new_size']} bytes")
if report['added']:
print(f"nFIȘIERE NOI ({len(report['added'])}):")
for item in report['added']:
indicator = " [PHP!]" if item['is_php'] else ""
print(f" [NOU{indicator}] {item['file']} ({item['size']} bytes)")
if report['deleted']:
print(f"nFIȘIERE ȘTERSE ({len(report['deleted'])}):")
for item in report['deleted']:
print(f" [ȘTERS] {item['file']}")
if report['permission_changed']:
print(f"nPERMISIUNI MODIFICATE ({len(report['permission_changed'])}):")
for item in report['permission_changed']:
print(f" [PERM] {item['file']}: {item['old_perms']} -> {item['new_perms']}")
def save_report(self, report, filename=None):
"""Salvează raportul în format JSON."""
if not filename:
filename = f"fim_report_{datetime.now().strftime('%Y%m%d_%H%M')}.json"
with open(filename, 'w') as f:
json.dump(report, f, indent=2)
print(f"nRaport salvat: {filename}")
# Utilizare
fim = FileIntegrityMonitor('/var/www/wpsecurity.ro')
# Prima rulare: creare inventar de referință
fim.create_baseline()
# Verificări ulterioare
report = fim.check_integrity()
fim.print_report(report)
fim.save_report(report)- Creați inventarul de referință imediat după o instalare curată sau verificare de securitate
- Actualizați inventarul după fiecare actualizare legitimă WordPress
- Programați verificarea la fiecare oră prin cron pentru detectare rapidă
- Fișierele PHP noi în orice director sunt cel mai important indicator de compromitere
Automatizarea verificării și alertării
#!/usr/bin/env python3
"""Script de verificare automată, rulat prin cron."""
import smtplib
from email.mime.text import MIMEText
def send_alert_email(report, to_email):
"""Trimite alertă email cu modificările detectate."""
total = (len(report['modified']) + len(report['added']) +
len(report['deleted']) + len(report['permission_changed']))
if total == 0:
return
body = f"Modificări detectate: {total}nn"
for item in report['modified']:
body += f"MODIFICAT: {item['file']}n"
for item in report['added']:
php = " [PHP!]" if item['is_php'] else ""
body += f"NOU{php}: {item['file']}n"
for item in report['deleted']:
body += f"ȘTERS: {item['file']}n"
msg = MIMEText(body)
msg['Subject'] = f'[FIM ALERTĂ] {total} modificări detectate pe WordPress'
msg['From'] = 'fim@wpsecurity.ro'
msg['To'] = to_email
with smtplib.SMTP('localhost') as server:
server.send_message(msg)
# Rulare automată
fim = FileIntegrityMonitor('/var/www/wpsecurity.ro')
report = fim.check_integrity()
if report:
fim.print_report(report)
send_alert_email(report, 'admin@wpsecurity.ro')# Adăugare în crontab - verificare la fiecare oră
0 * * * * /usr/bin/python3 /home/user/scripts/fim_check.py >> /home/user/logs/fim.log 2>&1Monitorizarea integrității fișierelor cu Python oferă detecție rapidă a compromiterilor WordPress. Pentru strategii avansate de securitate, consultați securitate cibernetică și blogul nostru. Echipa WPSecurity oferă servicii speciale de monitorizare continuă, contactați-ne pentru implementare.
Despre autor
Dorel Tănase este specialist în optimizarea site-urilor pentru motoarele de căutare. Lucrează în online din 1997 și în SEO din 2007, iar activitatea se desfășoară prin GO SEO MARKETING S.R.L. din Alba Iulia. Se ocupă de audit tehnic, arhitectura site-urilor, conținut și construirea legăturilor.