Final Submission for SecOps Exam
هذا الالتزام موجود في:
56
q4-simple-siem/dashboard.html
Normal file
56
q4-simple-siem/dashboard.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SIEM Dashboard - Ghaymah</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f4f7f6; margin: 0; padding: 20px; }
|
||||
.card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 15px; }
|
||||
th, td { padding: 12px; border-bottom: 1px solid #ddd; text-align: right; }
|
||||
th { background-color: #2c3e50; color: white; }
|
||||
.alert-high { color: #e74c3c; font-weight: bold; }
|
||||
.ip-address { font-family: monospace; background: #eee; padding: 2px 6px; border-radius: 4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🛡️ لوحة مراقبة SIEM - غيمة</h1>
|
||||
|
||||
<div class="card">
|
||||
<h2>التنبيهات الأمنية المكتشفة</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>وقت الحدث</th>
|
||||
<th>نوع التهديد</th>
|
||||
<th>عنوان IP المشبوه</th>
|
||||
<th>تفاصيل السجل</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="alerts-table">
|
||||
<!-- Data is injected via JavaScript -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// محاكاة استدعاء ملف alerts.json الذي ينتجه البايثون
|
||||
const alertsData = [
|
||||
{ timestamp: "2026-07-26 14:30:00", type: "Brute Force Attempt", source_ip: "192.168.1.50", raw_log: "[AUTH] Failed password for admin" },
|
||||
{ timestamp: "2026-07-26 14:31:15", type: "SQL Injection", source_ip: "Unknown", raw_log: "[WEB] GET /api/data?id=1' OR 1=1-- HTTP/1.1" },
|
||||
{ timestamp: "2026-07-26 14:35:10", type: "Port Scanning", source_ip: "10.0.0.9", raw_log: "[FIREWALL] BLOCK TCP SRC=10.0.0.9 DPT=22" }
|
||||
];
|
||||
|
||||
const tableBody = document.getElementById('alerts-table');
|
||||
alertsData.forEach(alert => {
|
||||
const row = `<tr>
|
||||
<td>${alert.timestamp}</td>
|
||||
<td class="alert-high">${alert.type}</td>
|
||||
<td><span class="ip-address">${alert.source_ip}</span></td>
|
||||
<td dir="ltr" style="text-align: left;"><code>${alert.raw_log}</code></td>
|
||||
</tr>`;
|
||||
tableBody.innerHTML += row;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
16
q4-simple-siem/deployment-guide.md
Normal file
16
q4-simple-siem/deployment-guide.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# SIEM Deployment Guide on Ghaymah
|
||||
|
||||
## هندسة النظام (Architecture)
|
||||
تم تصميم هذا النظام (SIEM المبسط) ليعمل بكفاءة على بنية منصة غيمة (`ghaymah.systems`)، مع ضمان السرعة وقابلية التوسع.
|
||||
|
||||
## 1. تخزين السجلات (Log Storage via Block Storage)
|
||||
* نظراً لحجم السجلات الضخم والمتزايد باستمرار من الـ Firewalls والـ Web Servers، سنستخدم **ghaymah Block Storage** كمساحة تخزين مركزية.
|
||||
* يتم ربط (Mount) هذا الـ Block Storage بشكل مباشر مع حاوية (Container) الـ SIEM الخاصة بنا. هذه الخطوة تضمن عدم استهلاك مساحة الحاوية الداخلية (Ephemeral Storage) وتسمح بالاحتفاظ بالسجلات حتى لو تم إعادة تشغيل الحاوية.
|
||||
|
||||
## 2. معالجة البيانات (Data Processing)
|
||||
* يتم نشر سكريبت بايثون `siem_parser.py` داخل حاوية مستقلة.
|
||||
* يُجدول السكريبت للعمل كل 5 دقائق (باستخدام CronJob) ليقرأ أحدث الأسطر من السجلات الموجودة في הـ Block Storage، يحللها، ويستخرج التهديدات في ملف `alerts.json`.
|
||||
|
||||
## 3. واجهة العرض (Dashboard)
|
||||
* يتم استضافة ملف `dashboard.html` كصفحة ويب ثابتة (Static Web App).
|
||||
* تقوم الواجهة بجلب التحديثات من ملف JSON وعرض عناوين الـ IP المشبوهة، ليتمكن فريق SecOps من اتخاذ قرارات سريعة مثل الحظر الفوري للـ IP عبر الـ WAF.
|
||||
44
q4-simple-siem/siem_parser.py
Normal file
44
q4-simple-siem/siem_parser.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
# الأنماط الخبيثة التي نبحث عنها في السجلات
|
||||
SUSPICIOUS_PATTERNS = {
|
||||
"Brute Force Attempt": re.compile(r"Failed password for .* from (?P<ip>\d+\.\d+\.\d+\.\d+)"),
|
||||
"SQL Injection": re.compile(r"UNION SELECT|OR 1=1", re.IGNORECASE),
|
||||
"Port Scanning": re.compile(r"BLOCK .* SRC=(?P<ip>\d+\.\d+\.\d+\.\d+)")
|
||||
}
|
||||
|
||||
def analyze_logs():
|
||||
alerts = []
|
||||
|
||||
# محاكاة لبيانات قادمة من 3 مصادر (Authentication, Web Server, Firewall)
|
||||
mock_logs = [
|
||||
"[AUTH] Failed password for admin from 192.168.1.50",
|
||||
"[AUTH] Failed password for root from 192.168.1.50",
|
||||
"[WEB] GET /api/data?id=1' OR 1=1-- HTTP/1.1",
|
||||
"[FIREWALL] BLOCK TCP SRC=10.0.0.9 DST=192.168.1.10 DPT=22"
|
||||
]
|
||||
|
||||
print("🔍 بدء تحليل السجلات...")
|
||||
|
||||
for line in mock_logs:
|
||||
for attack_type, pattern in SUSPICIOUS_PATTERNS.items():
|
||||
match = pattern.search(line)
|
||||
if match:
|
||||
ip = match.groupdict().get("ip", "Unknown") if "ip" in pattern.groupindex else "Unknown"
|
||||
alerts.append({
|
||||
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"type": attack_type,
|
||||
"source_ip": ip,
|
||||
"raw_log": line
|
||||
})
|
||||
|
||||
# حفظ التنبيهات في ملف JSON لتقرأه لوحة التحكم
|
||||
with open("alerts.json", "w", encoding="utf-8") as f:
|
||||
json.dump(alerts, f, indent=4, ensure_ascii=False)
|
||||
|
||||
print(f"✅ تم الانتهاء من التحليل. تم العثور على {len(alerts)} تهديدات محتملة.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_logs()
|
||||
المرجع في مشكلة جديدة
حظر مستخدم