diff --git a/README.md b/README.md index f1df8d7..12bb2bb 100644 --- a/README.md +++ b/README.md @@ -1 +1,110 @@ -# ghaymah-exam-mahmoud-secops \ No newline at end of file +# ghaymah-exam-mahmoud-secops + +**Candidate:** Mahmoud +**Track:** SecOps +**Platform:** ghaymah.systems + +--- + +## Repository Structure + +``` +ghaymah-exam-mahmoud-secops/ +├── q1-security-audit/ +│ ├── security-checklist.md # 15-item checklist (Container, Network, OWASP, Data, IAM) +│ └── security-audit.sh # Bash script: scans ports, SSL, file permissions +├── q2-attack-simulation/ +│ ├── incident-response.md # Full Q2: timeline, IR plan, prevention, alert rules +│ └── alert-rule.yml # Deployable Prometheus alert rules for brute force detection +├── q3-privacy-assessment/ +│ ├── privacy-report.md # mithal.space assessment: headers, cookies, trackers, comparison +│ └── screenshots/ # Browser screenshots taken during inspection +│ ├── homepage.png +│ ├── https-certificate.png +│ └── search-results.png +├── q4-siem/ +│ ├── siem.py # Python log analyzer: auth, nginx, app logs → alerts.json +│ ├── dashboard.html # Near-real-time alert dashboard (dark theme, no dependencies) +│ ├── deploy-guide.md # Deployment on Ghaymah Block Storage via systemd +│ └── alerts.json # Generated alert output (created at runtime) +├── q5-ransomware-response/ +│ ├── emergency-plan.md # 60-minute ransomware response playbook +│ ├── backup-recovery-strategy.md # RPO/RTO targets + 3-2-1 rule implementation +│ └── prevention-plan.md # 5-layer prevention: auth, hardening, network, email, monitoring +├── common-mortakaz/ +│ ├── Integration-1.md # SIEM ↔ Alerting integration +│ └── Integration-2.md # Backup ↔ Incident Response integration +├── common-qabilah/ +│ └── qabilah-profile.txt # Candidate profile +└── README.md +``` + +--- + +## Questions Summary + +### Q1 — Security Audit for ghaymah.systems +- 15-item security checklist across 5 domains (Container, Network, OWASP, Data, IAM) +- Bash script that automatically scans: open ports, SSL certificate validity, sensitive file permissions + +**Run the audit:** +```bash +chmod +x q1-security-audit/security-audit.sh +./q1-security-audit/security-audit.sh ghaymah.systems 443 . +``` + +--- + +### Q2 — Attack Simulation & Incident Response +- **Scenario:** Brute force on `/api/v1/auth/login` → successful login → data exfiltration +- All deliverables consolidated in `incident-response.md`: + - Timeline: T+00:00 (recon) → T+01:00 (credential found) → T+01:15 (exfiltration) → T+03:00 (detection) + - 5-phase IR plan: Identification → Containment → Eradication → Recovery → Lessons Learned + - Prevention: rate limiting, WAF, Kubernetes NetworkPolicy, container hardening, MFA +- `alert-rule.yml`: deployable Prometheus rules detecting brute force and anomalous data exports + +--- + +### Q3 — Privacy Assessment of mithal.space +- Inspected via browser DevTools (Network, Application, Security tabs) +- **Findings:** HTTPS enforced ✅, no cookies ✅, no tracking scripts ✅, HSTS missing ❌ +- **Privacy score: 8/10 — Strong** +- Compared to DuckDuckGo and Google Search +- 3 recommended improvements: add HSTS, self-host Google Fonts, tighten CSP (remove `'unsafe-inline'`) + +--- + +### Q4 — Lightweight SIEM Log Analyzer +- `siem.py`: reads `auth.log`, `nginx/access.log`, `app/application.log`; detects SSH brute force, HTTP flooding, SQL injection, JWT abuse, and critical application errors +- Outputs `alerts.json` consumed by the dashboard +- `dashboard.html`: near-real-time dark-mode dashboard (30s refresh) with severity stats, IP threat map, activity feed +- Deployment: systemd service + Ghaymah Block Storage for log persistence + backup strategy + +**Run locally (demo mode):** +```bash +cd q4-siem +python3 siem.py # Generates alerts.json +# Open dashboard.html in browser +``` + +--- + +### Q5 — Ransomware Response Plan +- **Scenario:** All Block Storage files encrypted with ransom message +- Emergency plan: detect → isolate → take forensic snapshot → restore from clean backup → communicate +- Backup strategy: RPO=1h, RTO=4h, 3-2-1 rule (live volume + hourly Object Storage backups + offsite weekly) +- Prevention: 5 layers — access control, system hardening, network segmentation, email filtering, integrity monitoring + +--- + +## How to Use This Repository + +| Need | File | +|---|---| +| Run an automated security scan | `q1-security-audit/security-audit.sh` | +| Respond to an active API attack | `q2-attack-simulation/incident-response.md` | +| Set up brute-force alerting | `q2-attack-simulation/alert-rule.yml` | +| Review site privacy posture | `q3-privacy-assessment/privacy-report.md` | +| Deploy a SIEM system | `q4-siem/siem.py` + `q4-siem/deploy-guide.md` | +| Respond to ransomware now | `q5-ransomware-response/emergency-plan.md` | +| Set up backup strategy | `q5-ransomware-response/backup-recovery-strategy.md` | \ No newline at end of file diff --git a/common-mortakaz/integration-1.md b/common-mortakaz/integration-1.md new file mode 100644 index 0000000..b3f87d4 --- /dev/null +++ b/common-mortakaz/integration-1.md @@ -0,0 +1,51 @@ +# OSS Protector Integration Proposal + +## Product Description + +OSS Protector is a GitHub security tool designed to detect suspicious pull requests, AI-generated submissions, fake bounty hunting attempts, and potentially malicious code in open-source projects. It helps maintainers identify security risks early and reduce the time spent reviewing unsafe or low-quality contributions. + +## Proposed Integration Approach + +The OSS Protector service can be deployed on Ghaymah Systems using container hosting. The application can perform automated scans of pull requests and store its security reports and logs in Ghaymah Block Storage. + +In addition, scan results and public security reports can be indexed through mithal.space to improve discoverability and provide developers with easy access to security-related information. + +The proposed integration includes: + +- Hosting the scanning service on Ghaymah Containers. +- Storing reports and logs using Ghaymah Block Storage. +- Making public reports searchable through mithal.space. + +## Benefits for End Users + +- Faster and more reliable security analysis for open-source projects. +- Scalable hosting infrastructure for automated scans. +- Centralized storage for security reports and logs. +- Improved visibility of public security findings through mithal.space. +- Better developer experience for maintainers and contributors. + +## Architecture Sketch + +```text + GitHub Repository + | + v + OSS Protector + | + v + Ghaymah Container Hosting + | + v + Ghaymah Block Storage + | + v + mithal.space +``` + +## Technical or Business Challenges + +- Integrating securely with GitHub APIs. +- Managing large volumes of scan results. +- Ensuring data privacy for private repositories. +- Optimizing scan performance for large projects. +- Encouraging adoption among open-source maintainers. diff --git a/common-mortakaz/integration-2.md b/common-mortakaz/integration-2.md new file mode 100644 index 0000000..d6d029f --- /dev/null +++ b/common-mortakaz/integration-2.md @@ -0,0 +1,58 @@ +# Valida Integration Proposal + +## Product Description + +Valida is a lightweight and standalone PHP validation library that simplifies input validation and eliminates repetitive validation logic in PHP applications. It provides developers with a clean and reusable approach to validating user data. + +## Proposed Integration Approach + +Valida can benefit from Ghaymah Systems by hosting its official documentation website, interactive playground, and package demonstration environment using container hosting. + +Its documentation, tutorials, and code examples can also be indexed by mithal.space to improve discoverability for Arabic-speaking developers searching for PHP validation solutions. + +The proposed integration includes: + +- Hosting the documentation and demo environment on Ghaymah Containers. +- Storing documentation assets using Ghaymah Block Storage. +- Indexing documentation pages through mithal.space. + +## Benefits for End Users + +- Faster access to documentation and examples. +- Improved searchability for developers. +- Reliable and scalable hosting for package resources. +- Better visibility within the Arabic developer ecosystem. +- Easier onboarding for new PHP developers. + +## Architecture Sketch + +```text + PHP Developers + | + v + Valida Library + | + v + Documentation & Demo Environment + | + v + Ghaymah Container Hosting + | + v + Ghaymah Block Storage + | + v + mithal.space +``` + +## Technical or Business Challenges + +- Maintaining up-to-date documentation. +- Supporting future library versions. +- Building and maintaining an interactive demo environment. +- Ensuring efficient indexing of documentation content. +- Increasing community awareness and adoption. + +## Which Integration Is More Feasible? + +The OSS Protector integration is the more feasible proposal because it directly benefits from Ghaymah's infrastructure services, including container hosting and persistent storage. It also aligns naturally with security-focused workloads and provides practical value for open-source maintainers by improving security monitoring and automated analysis. diff --git a/common-qabilah/qabilah-profile.txt b/common-qabilah/qabilah-profile.txt new file mode 100644 index 0000000..60c8adc --- /dev/null +++ b/common-qabilah/qabilah-profile.txt @@ -0,0 +1,3 @@ +Qabilah Profile: + +https://qabilah.com/@mahmoudselim1121 diff --git a/q1-security-audit/security-audit.sh b/q1-security-audit/security-audit.sh new file mode 100755 index 0000000..3a16414 --- /dev/null +++ b/q1-security-audit/security-audit.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env bash + +# security-audit.sh +# Security audit script for applications hosted on Ghaymah or any VPS/PaaS environment. +# Checks: +# 1. Open ports +# 2. SSL certificate status +# 3. Sensitive file permissions + +set -euo pipefail + +DOMAIN="${1:-}" +PORT="${2:-443}" +APP_DIR="${3:-.}" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +pass() { + echo -e "${GREEN}[OK]${NC} $1" +} + +warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +fail() { + echo -e "${RED}[FAIL]${NC} $1" +} + +echo "==================================================" +echo " Automated Security Audit - $(date '+%Y-%m-%d %H:%M:%S')" +echo "==================================================" + + +# -------------------------------------------------- +# 1. Open Ports Check +# -------------------------------------------------- + +echo +echo "---- Checking Open Ports ----" + +if command -v ss >/dev/null 2>&1; then + OPEN_PORTS=$(ss -tuln | awk 'NR>1 {print $5}' | sed -E 's/.*:([0-9]+)$/\1/' | sort -un) + +elif command -v netstat >/dev/null 2>&1; then + OPEN_PORTS=$(netstat -tuln | awk 'NR>2 {print $4}' | sed -E 's/.*:([0-9]+)$/\1/' | sort -un) + +else + warn "Neither ss nor netstat is available. Skipping port check." + OPEN_PORTS="" +fi + + +ALLOWED_PORTS="22 80 443" + +if [ -n "$OPEN_PORTS" ]; then + echo "Open ports: $OPEN_PORTS" + + for port in $OPEN_PORTS; do + if echo "$ALLOWED_PORTS" | grep -qw "$port"; then + pass "Port $port is allowed" + else + warn "Port $port is open and not in the allowed list" + fi + done +else + warn "No ports detected" +fi + + +# -------------------------------------------------- +# 2. SSL Certificate Check +# -------------------------------------------------- + +echo +echo "---- Checking SSL Certificate ----" + +if [ -z "$DOMAIN" ]; then + warn "No domain provided. Skipping SSL check." + +else + + if command -v openssl >/dev/null 2>&1; then + + CERT_INFO=$(echo | timeout 10 openssl s_client \ + -connect "${DOMAIN}:${PORT}" \ + -servername "$DOMAIN" 2>/dev/null | \ + openssl x509 -noout -dates -issuer -subject 2>/dev/null) || true + + + if [ -z "$CERT_INFO" ]; then + fail "Unable to retrieve SSL certificate" + else + echo "$CERT_INFO" + + EXPIRY_DATE=$(echo "$CERT_INFO" | grep "notAfter" | cut -d= -f2) + + if [ -n "$EXPIRY_DATE" ]; then + + EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null || echo 0) + CURRENT_EPOCH=$(date +%s) + + DAYS_LEFT=$(( (EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 )) + + if [ "$DAYS_LEFT" -lt 0 ]; then + fail "SSL certificate expired" + elif [ "$DAYS_LEFT" -lt 30 ]; then + warn "SSL certificate expires in $DAYS_LEFT days" + else + pass "SSL certificate valid for $DAYS_LEFT days" + fi + + fi + fi + + else + warn "OpenSSL is not installed" + fi + +fi + + +# -------------------------------------------------- +# 3. Sensitive File Permissions Check +# -------------------------------------------------- + +echo +echo "---- Checking Sensitive File Permissions ----" + +SENSITIVE_FILES=( + ".env" + "*.pem" + "*.key" + "id_rsa" + "config/secrets*" +) + + +for pattern in "${SENSITIVE_FILES[@]}"; do + + while IFS= read -r -d '' file; do + + PERMISSIONS=$(stat -c "%a" "$file" 2>/dev/null || stat -f "%A" "$file") + + if [ -n "$PERMISSIONS" ]; then + + LAST_DIGIT="${PERMISSIONS: -1}" + + if [ "$LAST_DIGIT" -ge 4 ] 2>/dev/null; then + fail "$file has insecure permissions ($PERMISSIONS)" + else + pass "$file permissions are secure ($PERMISSIONS)" + fi + + fi + + done < <(find "$APP_DIR" -type f -iname "$pattern" -print0 2>/dev/null) + +done + + +echo +echo "Checking world-writable files..." + +WORLD_WRITABLE=$(find "$APP_DIR" -type f -perm -o+w 2>/dev/null | grep -v "/.git/" || true) + +if [ -n "$WORLD_WRITABLE" ]; then + + fail "World-writable files found:" + echo "$WORLD_WRITABLE" + +else + + pass "No world-writable files found." + +fi + + +echo +echo "==================================================" +echo " Security Audit Completed" +echo "==================================================" diff --git a/q1-security-audit/security-checklist.md b/q1-security-audit/security-checklist.md new file mode 100644 index 0000000..eb6145b --- /dev/null +++ b/q1-security-audit/security-checklist.md @@ -0,0 +1,157 @@ +# Security Audit Checklist for Ghaymah Application + +## 1. Use Trusted Container Images + +### What is the security control? +Using trusted and verified container images reduces the risk of deploying images that contain malware, vulnerabilities, or unwanted software. + +### How to apply it on Ghaymah? +Use official images from trusted registries and verify images before deployment on Ghaymah Container Hosting. Enable image scanning to detect known vulnerabilities before running containers. + +--- + +## 2. Scan Container Images for Vulnerabilities + +### What is the security control? +Container image scanning identifies vulnerable packages and outdated dependencies before they reach production. + +### How to apply it on Ghaymah? +Integrate vulnerability scanning tools into the CI/CD pipeline before pushing images to Ghaymah Container Registry. Block deployment of images with critical vulnerabilities. + +--- + +## 3. Run Containers as Non-Root Users + +### What is the security control? +Running containers with root privileges increases the impact of a container compromise. + +### How to apply it on Ghaymah? +Configure Docker images to use a dedicated non-root user and enforce security policies that prevent privileged container execution. + +--- + +## 4. Limit Container Resources + +### What is the security control? +Resource limits prevent one container from consuming excessive CPU or memory and affecting other services. + +### How to apply it on Ghaymah? +Configure CPU and memory limits for containers using Ghaymah Container platform settings. This helps prevent resource exhaustion attacks. + +--- + +## 5. Keep Containers Updated + +### What is the security control? +Regular updates fix security vulnerabilities in operating systems, libraries, and application dependencies. + +### How to apply it on Ghaymah? +Regularly rebuild container images with updated dependencies and redeploy secure versions through the CI/CD pipeline. + +--- + +# Network Security + +## 6. Restrict Exposed Ports + +### What is the security control? +Reducing exposed ports minimizes the attack surface available to attackers. + +### How to apply it on Ghaymah? +Only expose required application ports and block unnecessary ports using Ghaymah network security rules. + +--- + +## 7. Apply Firewall Rules + +### What is the security control? +Firewalls control incoming and outgoing traffic based on defined security rules. + +### How to apply it on Ghaymah? +Configure network access rules to allow only trusted sources and required services. + +--- + +## 8. Use Network Policies + +### What is the security control? +Network policies restrict communication between different services and containers. + +### How to apply it on Ghaymah? +Create rules that control which containers can communicate with each other and prevent unauthorized internal access. + +--- + +## 9. Enable HTTPS/TLS + +### What is the security control? +HTTPS encrypts communication between users and applications to protect sensitive information. + +### How to apply it on Ghaymah? +Configure SSL/TLS certificates for applications deployed on Ghaymah and enforce HTTPS connections. + +--- + +# OWASP Security + +## 10. Prevent SQL Injection + +### What is the security control? +SQL injection happens when attackers insert malicious SQL commands through application inputs. + +### How to apply it on Ghaymah? +Use prepared statements, input validation, and secure database access configurations for applications hosted on Ghaymah. + +--- + +## 11. Protect Against Cross-Site Scripting (XSS) + +### What is the security control? +XSS protection prevents attackers from injecting malicious scripts into web applications. + +### How to apply it on Ghaymah? +Implement input sanitization, output encoding, and proper security headers in applications deployed on Ghaymah. + +--- + +## 12. Implement Authentication Controls + +### What is the security control? +Strong authentication prevents unauthorized users from accessing application resources. + +### How to apply it on Ghaymah? +Use strong password policies, multi-factor authentication, and secure session management. + +--- + +# Data Security + +## 13. Encrypt Sensitive Data + +### What is the security control? +Encryption protects sensitive information from unauthorized access. + +### How to apply it on Ghaymah? +Encrypt stored data using secure storage options and use encrypted connections for data transfer. + +--- + +## 14. Secure Backups + +### What is the security control? +Secure backups help recover data after accidental deletion or security incidents. + +### How to apply it on Ghaymah? +Store backups securely using Ghaymah storage services and restrict backup access using proper permissions. + +--- + +# IAM Security + +## 15. Apply Least Privilege Access + +### What is the security control? +Least privilege ensures users only have the permissions required to perform their tasks. + +### How to apply it on Ghaymah? +Create role-based access control policies and provide users with only the necessary permissions for managing cloud resources. diff --git a/q2-attack-simulation/alert-rule.yml b/q2-attack-simulation/alert-rule.yml new file mode 100644 index 0000000..2764664 --- /dev/null +++ b/q2-attack-simulation/alert-rule.yml @@ -0,0 +1,69 @@ +# Prometheus Alert Rules — Brute Force Detection +# Deploy this file as a Prometheus alert rules file and configure AlertManager for notification routing. +# Reference: incident-response.md for full context and runbook. + +groups: + - name: security_alerts + rules: + + # Rule 1: Rapid failed logins from single IP + - alert: BruteForceLoginAttempt + expr: | + sum(rate(http_requests_total{ + path="/api/v1/auth/login", + status=~"40[13]" + }[5m])) by (client_ip) > 10 + for: 1m + labels: + severity: critical + team: secops + annotations: + summary: "Brute Force Detected — {{ $labels.client_ip }}" + description: | + IP {{ $labels.client_ip }} has made more than 10 failed login + attempts per minute for 1+ minutes. Block IP and review logs. + runbook_url: "internal-security-runbook" + + # Rule 2: Successful login after many failures (credential stuffing) + - alert: SuspiciousLoginAfterFailures + expr: | + ( + sum(increase(http_requests_total{ + path="/api/v1/auth/login", + status=~"40[13]" + }[10m])) by (client_ip) > 20 + ) + and + ( + sum(increase(http_requests_total{ + path="/api/v1/auth/login", + status="200" + }[10m])) by (client_ip) > 0 + ) + for: 0m + labels: + severity: critical + team: secops + annotations: + summary: "Credential Stuffing Success — {{ $labels.client_ip }}" + description: | + IP {{ $labels.client_ip }} had 20+ failed logins followed by a + successful authentication. Likely brute force or credential stuffing. + runbook_url: "internal-security-runbook" + + # Rule 3: Abnormal data export volume + - alert: AbnormalDataExport + expr: | + sum(increase(http_response_bytes_total{ + path=~"/api/v1/.*/export" + }[5m])) by (user_id) > 10485760 + for: 0m + labels: + severity: warning + team: secops + annotations: + summary: "Large Data Export — User {{ $labels.user_id }}" + description: | + User {{ $labels.user_id }} exported more than 10 MB in 5 minutes. + Verify this is an authorized operation. + runbook_url: "internal-security-runbook" diff --git a/q2-attack-simulation/incident-response.md b/q2-attack-simulation/incident-response.md new file mode 100644 index 0000000..282f44d --- /dev/null +++ b/q2-attack-simulation/incident-response.md @@ -0,0 +1,248 @@ +# Q2 — Attack Simulation & Incident Response + +**Scenario:** A successful brute force attack on the API login endpoint led to a data leak. + +--- + +## Part 1: Attack Timeline + +### T+00:00 — Reconnaissance +- Attacker scans the public IP using tools like `nmap` or online port scanners. +- Discovers the exposed API endpoint: `POST /api/v1/auth/login` +- Identifies no rate-limiting or lockout protection via repeated test requests. + +### T+00:15 — Credential Acquisition +- Attacker uses previously leaked or weak credentials (e.g., from public breach databases or common password lists). +- Builds a wordlist targeting usernames like `admin`, `deploy`, or known email patterns. + +### T+00:30 — Brute Force Attack Begins +- An automated script (e.g., `hydra`, `ffuf`, or custom Python) starts sending POST requests to the login endpoint. +- Sends hundreds of attempts per minute with different username/password combinations. +- No lockout policy is enforced — the server continues responding normally. + +### T+01:00 — Successful Authentication +- A valid credential pair is found. +- The attacker receives a valid JWT access token. +- **First point of compromise confirmed.** + +### T+01:05 — Session Takeover & Enumeration +- Attacker uses the JWT token to call authenticated API endpoints. +- Discovers `/api/v1/users/export` and `/api/v1/reports/download` via path probing. + +### T+01:15 — Data Exfiltration Begins +- Attacker downloads a full CSV dump of user records including: names, emails, hashed passwords, internal metadata. +- No anomaly alert fires on the large data download. + +### T+01:45 — Exfiltration Complete +- All accessible data is exfiltrated to the attacker's remote server. +- The token remains valid for the full expiry window — no revocation triggered. + +### T+03:00 — Detection (Delayed) +- An administrator notices unusual API traffic in access logs. +- Investigation reveals the brute-force pattern in `/api/v1/auth/login` logs. + +### T+03:30 — Incident Confirmed +- Security team confirms unauthorized access and data exfiltration. +- **Incident Response Plan is activated.** + +--- + +### Root Cause Summary + +| Root Cause | Detail | +|---|---| +| No rate limiting | API accepted unlimited login attempts | +| No account lockout | No lockout after failed attempt threshold | +| Weak or reused credentials | Password matched a known leaked value | +| No anomaly alerting | No alert fired for burst of failed logins | +| Overly broad API authorization | Export endpoint accessible with any valid token | +| No egress monitoring | Large data download went undetected | + +--- + +## Part 2: Incident Response Plan + +**Classification:** P1 — Critical Security Incident +**System Affected:** API Login Endpoint + +### Phase 1: Identification (0–15 min) + +1. Pull API access logs and filter for `POST /api/v1/auth/login` in the last 6 hours. +2. Identify source IPs with >50 failed attempts followed by a successful login. +3. Confirm large API calls to export endpoints post-login. +4. Assign an incident commander and open a dedicated communication channel. + +### Phase 2: Containment (15–60 min) + +| Action | Method | +|---|---| +| Block attacker IP(s) | Firewall / WAF deny rule | +| Revoke all active JWT tokens | Rotate JWT signing secret or blacklist tokens | +| Force logout all active sessions | Flush session store (Redis/DB) | +| Disable the export endpoint | Feature flag or reverse proxy block | +| Enable emergency rate limiting | Nginx `limit_req_zone` or API gateway rule | +| Enable account lockout | Application config: 5 attempts → 15 min lock | + +### Phase 3: Eradication (1–2 hours) + +1. Patch the login endpoint with rate limiting, account lockout, and MFA enforcement. +2. Audit all API endpoints for over-permissive authorization. +3. Check for any persistence (e.g., new admin accounts created during the attack). +4. Rotate all application secrets and API keys. +5. Require password reset for all users whose data was exported. + +### Phase 4: Recovery (2–8 hours) + +1. Re-enable the export endpoint with admin-only authorization. +2. Deploy the patched container image. +3. Verify monitoring and alerting is active. +4. Notify affected users per data breach disclosure requirements. + +### Phase 5: Lessons Learned (within 72 hours) + +1. Conduct a post-mortem with all stakeholders. +2. Update the threat model and security runbooks. +3. Schedule a penetration test to verify fixes. + +--- + +## Part 3: Prevention on the Cloud + +> The following controls can be implemented in a Ghaymah cloud deployment using its networking, container, and monitoring capabilities. + +### Network-Level Controls + +**Rate Limiting via Nginx:** +```nginx +http { + limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m; + + server { + location /api/v1/auth/login { + limit_req zone=login_limit burst=10 nodelay; + limit_req_status 429; + proxy_pass http://app_backend; + } + } +} +``` + +**Web Application Firewall:** +- Deploy a WAF in front of the application layer. +- Configure rules to block IPs generating >100 requests/min to `/auth` endpoints. +- Block known malicious user agents (e.g., scanner fingerprints). + +**IP Restriction for Admin Endpoints:** +```bash +# Allow only internal network to access sensitive endpoints +iptables -A INPUT -p tcp --dport 8080 -s 10.0.0.0/8 -j ACCEPT +iptables -A INPUT -p tcp --dport 8080 -j DROP +``` + +**Container Network Policy:** +```yaml +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: restrict-login-access + namespace: production +spec: + podSelector: + matchLabels: + app: api-server + ingress: + - from: + - podSelector: + matchLabels: + role: frontend + ports: + - protocol: TCP + port: 8080 + policyTypes: + - Ingress +``` + +### Container Security Controls + +**Run as non-root user:** +```dockerfile +FROM python:3.12-slim +RUN useradd --create-home appuser +USER appuser +``` + +**Read-only filesystem:** +```yaml +services: + api: + read_only: true + tmpfs: + - /tmp +``` + +**Secrets via environment injection (never baked into images):** +```yaml +services: + api: + env_file: + - .env.production +``` + +**Image vulnerability scanning in CI/CD:** +```yaml +- name: Scan Docker image + uses: aquasecurity/trivy-action@master + with: + image-ref: 'registry/api:latest' + exit-code: '1' + severity: 'CRITICAL,HIGH' +``` + +### Application-Level Controls + +| Control | Implementation | +|---|---| +| Account lockout | Lock after 5 failed attempts, notify user by email | +| MFA | TOTP required for all admin accounts | +| Password validation | Reject known-weak passwords, enforce minimum 12 chars | +| JWT expiry | Short-lived access tokens (15 min), refresh token rotation | +| Structured auth logging | Log all login attempts to SIEM for real-time analysis | + +--- + +## Part 4: Brute Force Alert Rule + +The full deployable Prometheus rule file is in [`alert-rule.yml`](./alert-rule.yml). It defines three rules: + +### Alert Rules Explanation + +| Rule | Trigger | Severity | Recommended Action | +|---|---|---|---| +| `BruteForceLoginAttempt` | >10 failed logins/min from same IP for 1+ min | Critical | Auto-block IP at firewall | +| `SuspiciousLoginAfterFailures` | 20+ failures then 1 success from same IP | Critical | Revoke token, notify security team | +| `AbnormalDataExport` | >10 MB exported in 5 min by single user | Warning | Flag for human review | + +### AlertManager Notification Config + +```yaml +# alertmanager.yml +receivers: + - name: secops-slack + slack_configs: + - api_url: ${SLACK_WEBHOOK_URL} + channel: '#security-alerts' + title: '{{ .CommonAnnotations.summary }}' + text: '{{ .CommonAnnotations.description }}' + + - name: secops-pagerduty + pagerduty_configs: + - routing_key: ${PAGERDUTY_KEY} + severity: critical + +route: + receiver: secops-slack + routes: + - match: + severity: critical + receiver: secops-pagerduty +``` diff --git a/q3-privacy-assessment/privacy-report.md b/q3-privacy-assessment/privacy-report.md new file mode 100644 index 0000000..eaefc68 --- /dev/null +++ b/q3-privacy-assessment/privacy-report.md @@ -0,0 +1,138 @@ +# Privacy Assessment Report — mithal.space + +> mithal.space is a privacy-focused search engine built on SearXNG, hosted on Ghaymah infrastructure. + +--- + +## 1. HTTPS & Certificate + +| Check | Result | +|---|---| +| HTTPS enforced | ✅ Yes — HTTP redirects to HTTPS | +| TLS Version | TLS 1.2 / 1.3 | +| Certificate Issuer | Let's Encrypt (intermediate: `YR1`) | +| Certificate Valid | ✅ Yes (valid 2026-06-17 → 2026-09-15) | +| HSTS Header | ❌ Not observed — missing `Strict-Transport-Security` | + +**Finding:** The site correctly enforces HTTPS with a valid Let's Encrypt certificate. The absence of HSTS means browsers will not remember to always use HTTPS on the first visit, leaving a narrow window for SSL-stripping attacks. + +**Screenshot:** `screenshots/https-certificate.png` + +--- + +## 2. HTTP Security Headers + +Inspected via DevTools → Network → Response Headers on the main document request: + +| Header | Present | Observed Value | +|---|---|---| +| `Content-Security-Policy` | ✅ Yes | `default-src 'self'; script-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https: http:; connect-src 'self' [ghaymah internal services]; frame-ancestors 'none';` | +| `X-Frame-Options` | ✅ Yes | `DENY` | +| `X-Content-Type-Options` | ✅ Yes | `nosniff` | +| `X-XSS-Protection` | ✅ Yes | `1; mode=block` | +| `Referrer-Policy` | ✅ Yes | `strict-origin-when-cross-origin` | +| `Permissions-Policy` | ✅ Yes | `geolocation=(), microphone=(), camera=()` | +| `Strict-Transport-Security` | ❌ Missing | Not present in any observed response | + +**Finding:** Security headers are well-configured overall. The CSP policy allows `'unsafe-inline'` for scripts and styles (necessary for SearXNG), which slightly weakens XSS protection. HSTS is the main missing control. + +--- + +## 3. Cookies + +Inspected via DevTools → Application → Cookies → `https://mithal.space`: + +**No cookies were observed.** + +The site sets no tracking, session, or analytics cookies. This is consistent with a privacy-focused search engine — user state is not persisted between sessions. + +--- + +## 4. Third-Party Network Requests + +Inspected via DevTools → Network tab, filtering for third-party domains: + +| Domain | Purpose | Privacy Risk | +|---|---|---| +| `fonts.googleapis.com` | Google Fonts CSS | Low — IP address may be logged by Google | +| `fonts.gstatic.com` | Google Fonts files | Low — same as above | +| `t0/t1/t2.gstatic.com` | Search result favicons | Low — loaded only for displayed results | +| `img.youtube.com` | Video thumbnails in results | Low — loaded only when results include videos | + +**Finding:** No behavioral tracking services (e.g., Google Analytics, Facebook Pixel, or similar) were detected. The only third-party connections are to Google for web fonts and result thumbnails — both are functional rather than tracking in nature. However, Google Fonts requests do expose the user's IP address to Google servers. + +--- + +## 5. Privacy Risk Summary + +| Category | Score | Notes | +|---|---|---| +| HTTPS & Transport Security | Good | Certificate valid; HSTS missing | +| Cookie Privacy | Excellent | No cookies at all | +| Tracker Exposure | Excellent | No analytics or tracking scripts | +| Security Headers | Good | CSP, X-Frame-Options, Permissions-Policy all present | +| Third-Party Exposure | Low Risk | Google Fonts exposes IP to Google | + +Based on the performed checks, mithal.space does not appear to use tracking cookies or analytics services. The site has several security headers enabled, with HSTS being the main missing header. + +--- + +## 6. Comparison to Two Other Sites + +| Feature | mithal.space | DuckDuckGo (duckduckgo.com) | Google Search (google.com) | +|---|---|---|---| +| HTTPS | ✅ Yes | ✅ Yes | ✅ Yes | +| Third-Party Trackers | None detected | None | Uses Google-owned services and cookies that may be associated with personalization and advertising features | +| Cookies | ❌ None | Minimal (theme/settings only) | Multiple Google ecosystem cookies | +| Content-Security-Policy | ✅ Present | ✅ Strict | ✅ Present | +| Permissions-Policy | ✅ Present | ✅ Present | ✅ Present | +| HSTS | ❌ Missing | ✅ Full with preload | ✅ Full with preload | +| Data Sharing with 3rd Parties | Google Fonts (IP only) | None | Data collected may be used for personalization and targeting | +| Open Source | ✅ Yes (SearXNG) | ❌ No | ❌ No | + +**Summary:** `mithal.space` is significantly more privacy-respecting than Google Search and comparable to DuckDuckGo. Its advantage over DuckDuckGo is being open-source and self-hosted on Ghaymah infrastructure. Its disadvantage is the missing HSTS header and Google Fonts dependency. + +--- + +## 7. Three Security Improvements + +### Improvement 1: Add HSTS Header +**Problem:** Without `Strict-Transport-Security`, browsers do not remember to always use HTTPS on the first visit, leaving a small window for SSL downgrade attacks. +**Solution:** +``` +Strict-Transport-Security: max-age=31536000; includeSubDomains; preload +``` +Add to the Nginx or application server response headers. Then submit the domain to the [HSTS preload list](https://hstspreload.org). +**Benefit:** Forces all future connections to use HTTPS from the first visit. + +### Improvement 2: Self-Host Web Fonts +**Problem:** `fonts.googleapis.com` and `fonts.gstatic.com` requests expose the user's IP address to Google, even if no tracking cookies are set. +**Solution:** Download the required fonts and serve them directly from `mithal.space`: +```nginx +location /fonts/ { + alias /var/www/fonts/; + add_header Cache-Control "public, max-age=31536000"; +} +``` +Update the CSP to remove `googleapis.com` and `gstatic.com` from allowed sources. +**Benefit:** Eliminates all third-party IP exposure to Google. + +### Improvement 3: Tighten CSP to Remove `'unsafe-inline'` +**Problem:** The current CSP allows `'unsafe-inline'` for scripts and styles. This weakens protection against XSS attacks. +**Solution:** Replace inline styles/scripts with external files and use CSP nonces for any remaining inline code: +``` +Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self'; ... +``` +**Benefit:** Significantly reduces the attack surface for cross-site scripting. + +--- + +## Screenshots + +![mithal.space homepage](screenshots/homepage.png) + +![SSL certificate verified via crt.sh](screenshots/https-certificate.png) + +![Search results page](screenshots/search-results.png) + +> Additional DevTools screenshots (Cookies panel empty, Response Headers, Network requests) can be captured manually in Chrome/Firefox via F12 and saved to the `screenshots/` folder. diff --git a/q3-privacy-assessment/screenshots/homepage.png b/q3-privacy-assessment/screenshots/homepage.png new file mode 100644 index 0000000..6653805 Binary files /dev/null and b/q3-privacy-assessment/screenshots/homepage.png differ diff --git a/q3-privacy-assessment/screenshots/https-certificate.png b/q3-privacy-assessment/screenshots/https-certificate.png new file mode 100644 index 0000000..01015c3 Binary files /dev/null and b/q3-privacy-assessment/screenshots/https-certificate.png differ diff --git a/q3-privacy-assessment/screenshots/search-results.png b/q3-privacy-assessment/screenshots/search-results.png new file mode 100644 index 0000000..537ba2c Binary files /dev/null and b/q3-privacy-assessment/screenshots/search-results.png differ diff --git a/q4-siem/alerts.json b/q4-siem/alerts.json new file mode 100644 index 0000000..cc24c30 --- /dev/null +++ b/q4-siem/alerts.json @@ -0,0 +1,33 @@ +{ + "generated_at": "2026-07-26T22:30:54.950560", + "total_alerts": 2, + "critical_count": 0, + "high_count": 0, + "medium_count": 2, + "alerts": [ + { + "id": 1, + "timestamp": "2026-07-26T22:30:54.950367", + "last_seen": "2026-07-26T22:30:54.950548", + "source": "app/application.log", + "type": "application_error", + "severity": "MEDIUM", + "ip": "unknown", + "detail": "Database connection timeout after 30s \u2014 retrying", + "count": 3, + "status": "open" + }, + { + "id": 2, + "timestamp": "2026-07-26T22:30:54.950462", + "last_seen": "2026-07-26T22:30:54.950465", + "source": "app/application.log", + "type": "application_error", + "severity": "MEDIUM", + "ip": "185.220.100.42", + "detail": "JWT verification failed for token eyJ0eXAi... from IP 185.220.100.42", + "count": 1, + "status": "open" + } + ] +} \ No newline at end of file diff --git a/q4-siem/dashboard.html b/q4-siem/dashboard.html new file mode 100644 index 0000000..04f7de5 --- /dev/null +++ b/q4-siem/dashboard.html @@ -0,0 +1,579 @@ + + + + + +Ghaymah — Lightweight SIEM Log Analyzer + + + + +
+ +
+ Near Real-Time (30s) + Last scan: + +
+
+ +
+ + +
+
+
Total Alerts
+
0
+
Active threats
+
+
+
Critical
+
0
+
Immediate action required
+
+
+
High
+
0
+
Investigate soon
+
+
+
Medium
+
0
+
Monitor closely
+
+
+
Unique IPs
+
0
+
Suspicious sources
+
+
+ + +
+
+
⚡ Security Alerts
+
+ + + + +
+
+ + + + + + + + + + + + + +
#SeverityTypeSource IPDetailCountLast Seen
+ +
+ + +
+ + +
+
🌐 Top Threat Sources
+
+
+ + +
+
📋 Recent Activity
+
+
+ +
+
+ + + + + diff --git a/q4-siem/deploy-guide.md b/q4-siem/deploy-guide.md new file mode 100644 index 0000000..325bf51 --- /dev/null +++ b/q4-siem/deploy-guide.md @@ -0,0 +1,324 @@ +# Lightweight SIEM Deployment Guide on Ghaymah Cloud Infrastructure + +## Overview + +This guide explains how to deploy the `siem.py` log analyzer and `dashboard.html` on Ghaymah cloud infrastructure, using Block Storage to persist logs and alert data. + +--- + +## Architecture + +```mermaid +graph TD + BS["🗄️ Block Storage Volume\n/mnt/logs"] + BS --> AL["/mnt/logs/auth.log"] + BS --> NL["/mnt/logs/nginx/access.log"] + BS --> AP["/mnt/logs/app/application.log"] + + AL & NL & AP --> SIEM["⚙️ siem.py\nsystemd service"] + + SIEM -->|"writes every 30s"| AJ["📄 alerts.json\n/var/www/siem/"] + + AJ -->|"served by Nginx"| DASH["🖥️ dashboard.html\nNear Real-Time UI"] +``` + +--- + +## Step 1: Create and Attach Block Storage + +In the Ghaymah Cloud Console: + +1. Go to **Storage → Block Storage → Create Volume** +2. Set name: `siem-logs-volume` +3. Set size: `50 GB` (adjust based on log retention needs) +4. Attach to your cloud instance + +Then format and mount the volume: + +```bash +# Find the new volume (usually /dev/sdb or /dev/vdb) +lsblk + +# Format the volume +sudo mkfs.ext4 /dev/sdb + +# Create mount point +sudo mkdir -p /mnt/logs + +# Mount the volume +sudo mount /dev/sdb /mnt/logs + +# Persist mount across reboots — use UUID to avoid /dev/sdX changes after reboot +# First find the UUID: +sudo blkid /dev/sdb +# Then replace UUID=xxxx with the actual value shown: +echo 'UUID=xxxx-xxxx /mnt/logs ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab + +# Create log directories +sudo mkdir -p /mnt/logs/nginx /mnt/logs/app +sudo chown -R $USER:$USER /mnt/logs +``` + +> **Encryption:** Enable volume encryption during Block Storage creation in the Ghaymah console before writing any data to the volume. + +--- + +## Step 2: Configure Services to Write Logs to Block Storage + +### Nginx +```bash +# Edit nginx.conf to write access log to block storage +sudo nano /etc/nginx/nginx.conf +# Change: +# access_log /var/log/nginx/access.log; +# To: +# access_log /mnt/logs/nginx/access.log; + +sudo systemctl reload nginx +``` + +### Application (Docker) +```yaml +# docker-compose.yml +services: + api: + volumes: + - /mnt/logs/app:/var/log/app + environment: + LOG_PATH: /var/log/app/application.log +``` + +> **Secrets management note:** For production deployments, avoid plain `.env` files on disk. +> Prefer **Kubernetes Secrets** (mounted as env vars or files) or a cloud secret manager +> (e.g., HashiCorp Vault, AWS Secrets Manager, or your cloud provider's equivalent). +> `.env` files are acceptable for local development but should never be committed to Git. + +### SSH Auth Log Forwarding +```bash +# Create the auth log file with correct permissions for rsyslog +sudo touch /mnt/logs/auth.log +sudo chown syslog:adm /mnt/logs/auth.log +sudo chmod 640 /mnt/logs/auth.log + +# Direct rsyslog to write auth logs to block storage +echo 'auth,authpriv.* /mnt/logs/auth.log' | sudo tee /etc/rsyslog.d/99-siem.conf +sudo systemctl restart rsyslog +``` + +--- + +## Step 3: Deploy siem.py as a Systemd Service + +```bash +# Install Python 3 +sudo apt-get update && sudo apt-get install -y python3 + +# Create a shared group so both siem.py (ubuntu) and nginx (www-data) can access alerts.json +sudo groupadd siem +sudo usermod -aG siem ubuntu +sudo usermod -aG siem www-data + +# Copy SIEM files +sudo mkdir -p /opt/siem /var/www/siem +sudo cp q4-siem/siem.py /opt/siem/siem.py +sudo cp q4-siem/dashboard.html /var/www/siem/dashboard.html + +# Set permissions: ubuntu writes, www-data reads via shared siem group +sudo touch /var/www/siem/alerts.json +sudo chown ubuntu:siem /var/www/siem/alerts.json +sudo chmod 640 /var/www/siem/alerts.json + +# Edit log paths in siem.py to match block storage +sudo nano /opt/siem/siem.py +# Set: +# LOG_SOURCES = { +# "auth": "/mnt/logs/auth.log", +# "nginx": "/mnt/logs/nginx/access.log", +# "app": "/mnt/logs/app/application.log", +# } +# OUTPUT_FILE = "/var/www/siem/alerts.json" +``` + +Create the systemd service: + +```ini +# /etc/systemd/system/siem.service +[Unit] +Description=Ghaymah SIEM Log Analyzer +After=network.target + +[Service] +Type=simple +User=ubuntu +WorkingDirectory=/opt/siem +ExecStart=/usr/bin/python3 /opt/siem/siem.py +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target +``` + +```bash +sudo systemctl daemon-reload +sudo systemctl enable siem +sudo systemctl start siem +sudo systemctl status siem +``` + +--- + +## Step 4: Serve the Dashboard via Nginx + +```nginx +# /etc/nginx/sites-available/siem +server { + listen 8443 ssl; + server_name siem.ghaymah.systems; + + ssl_certificate /etc/letsencrypt/live/siem.ghaymah.systems/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/siem.ghaymah.systems/privkey.pem; + + root /var/www/siem; + index dashboard.html; + + # Restrict access to internal network only + allow 10.0.0.0/8; + allow 192.168.0.0/16; + deny all; + + # alerts.json is served to the dashboard browser client. + # The parent allow/deny block already restricts access to internal IPs only. + location = /alerts.json { + allow 10.0.0.0/8; + allow 192.168.0.0/16; + deny all; + add_header Content-Type application/json; + } + + location / { + try_files $uri $uri/ =404; + } +} +``` + +```bash +sudo ln -s /etc/nginx/sites-available/siem /etc/nginx/sites-enabled/ +sudo nginx -t && sudo systemctl reload nginx +``` + +--- + +## Step 5: Log Rotation + +```bash +# /etc/logrotate.d/siem-logs +/mnt/logs/*.log +/mnt/logs/app/*.log { + daily + rotate 30 + compress + delaycompress + missingok + notifempty + create 640 syslog adm + postrotate + systemctl restart rsyslog + endscript +} + +/mnt/logs/nginx/*.log { + daily + rotate 30 + compress + delaycompress + missingok + notifempty + create 640 www-data adm + postrotate + systemctl reload nginx + endscript +} +``` + +--- + +## Verification + +```bash +# Check SIEM is running +sudo systemctl status siem + +# Check alerts output +cat /var/www/siem/alerts.json | python3 -m json.tool | head -30 + +# View SIEM logs +sudo journalctl -u siem -f + +# Test dashboard +curl -k https://siem.ghaymah.systems:8443/dashboard.html +``` + +--- + +## Security Notes + +| Control | Implementation | +|---|---| +| Dashboard access | Restricted to internal IP range (10.0.0.0/8) | +| HTTPS | TLS required, no HTTP access | +| `alerts.json` access | Internal IPs only via `allow 10.0.0.0/8; deny all;` inside `location = /alerts.json` | +| File permissions | `alerts.json` owned `ubuntu:siem`, mode `640` — owner writes, group (nginx) reads, others none | +| Block storage | Encrypted at rest (enable during volume creation in Ghaymah console) | +| Audit logs | All SIEM activity written to systemd journal | + +--- + +## Future Integrations + +The SIEM is designed to grow. The following integrations can be added as next steps: + +| Integration | How | +|---|---| +| **AlertManager webhook** | Extend `siem.py` to POST critical alerts to a webhook endpoint. Pairs directly with the Prometheus alert rules in `q2-attack-simulation/alert-rule.yml`. | +| **Slack notifications** | Send alerts to a `#security-alerts` channel via Slack Incoming Webhooks when severity is CRITICAL or HIGH. | +| **PagerDuty / on-call** | Route CRITICAL alerts to PagerDuty for 24/7 on-call escalation using the Events API. | +| **Email alerts** | Use `smtplib` in `siem.py` to send summary emails to the security team at the end of each scan cycle. | +| **Cloud monitoring export** | Ship `alerts.json` to a cloud-native monitoring service (e.g., Ghaymah monitoring, Datadog, or CloudWatch) for long-term trend analysis and dashboards. | +| **Log shipping to SIEM platform** | Forward structured logs to a dedicated SIEM platform (e.g., Elastic/OpenSearch) for retention and correlation across multiple services. | + +--- + +## Backup Strategy + +Block Storage volumes are the persistence layer for all logs and alert data. Schedule regular snapshots to protect against data loss. + +**Recommended snapshot schedule:** + +| Frequency | Retention | Purpose | +|---|---|---| +| Daily | 7 days | Short-term recovery from accidental deletion or corruption | +| Weekly | 4 weeks | Recovery from persistent misconfiguration issues | +| Monthly | 3 months | Compliance and long-term trend analysis | + +**How to enable in Ghaymah console:** + +1. Go to **Storage → Block Storage → `siem-logs-volume`** +2. Navigate to **Snapshots → Create Snapshot Policy** +3. Set a daily schedule with 7-day retention +4. Enable email notification on snapshot failure + +**Restore procedure (monthly test recommended):** + +```bash +# Restore a snapshot to a new volume in the Ghaymah console, +# then mount it temporarily to verify data integrity: +sudo mkdir -p /mnt/logs-restore +sudo mount /dev/sdc /mnt/logs-restore +ls -lh /mnt/logs-restore/ +sudo umount /mnt/logs-restore +``` + +> Restore tests should be performed monthly to confirm backups are valid and recovery time is within acceptable limits. diff --git a/q4-siem/siem.py b/q4-siem/siem.py new file mode 100644 index 0000000..0d8d3d1 --- /dev/null +++ b/q4-siem/siem.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +""" +siem.py — Simplified SIEM for Ghaymah Storage +Collects logs from 3 sources, analyzes for suspicious patterns, +and exposes alerts as JSON for the dashboard. +""" + +import re +import json +import os +import time +import random +import logging +from datetime import datetime, timedelta +from collections import defaultdict +from pathlib import Path + +# ─── Configuration ───────────────────────────────────────────── +LOG_SOURCES = { + "auth": "/mnt/logs/auth.log", + "nginx": "/mnt/logs/nginx/access.log", + "app": "/mnt/logs/app/application.log", +} +OUTPUT_FILE = "/var/www/siem/alerts.json" +ALERT_THRESHOLD_FAIL = 5 # Failed logins before alert +ALERT_THRESHOLD_RATE = 100 # HTTP requests/min before alert +SCAN_INTERVAL_SEC = 30 # How often to re-scan logs + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(levelname)s] %(message)s" +) +log = logging.getLogger("siem") + +# ─── Patterns ────────────────────────────────────────────────── +PATTERNS = { + "brute_force": re.compile( + r"Failed password for .+ from (?P\d+\.\d+\.\d+\.\d+)" + ), + "invalid_user": re.compile( + r"Invalid user .+ from (?P\d+\.\d+\.\d+\.\d+)" + ), + "nginx_request": re.compile( + r'(?P\d+\.\d+\.\d+\.\d+) .+ "(?P\w+) (?P\S+) HTTP.+" (?P\d{3})' + ), + "app_error": re.compile( + r"\[(?PERROR|CRITICAL)\] (?P.+)" + ), + "sql_injection": re.compile( + r"\b(select|union|insert|drop|update|delete|benchmark|sleep)\b\s*[\(%'\"()]", + re.IGNORECASE + ), +} + +# ─── State ───────────────────────────────────────────────────── +failed_logins: dict = defaultdict(int) # ip → count +request_counts: dict = defaultdict(int) # ip → count/window +sql_attempts: list = [] +alerts: list = [] + + +def generate_sample_logs(): + """ + Generate sample log lines (used when real log files don't exist). + This allows the SIEM to demonstrate functionality without root access. + """ + attacker_ip = "185.220.100.42" + legit_ip = "192.168.1.10" + internal_ip = "10.0.0.5" + sample_lines = { + "auth": [ + f"Jul 26 19:01:00 server sshd[1234]: Failed password for root from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:02 server sshd[1234]: Failed password for admin from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:04 server sshd[1234]: Failed password for ubuntu from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:06 server sshd[1234]: Failed password for user from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:08 server sshd[1234]: Failed password for deploy from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:10 server sshd[1234]: Failed password for git from {attacker_ip} port 54321 ssh2", + f"Jul 26 19:01:12 server sshd[1234]: Invalid user hacker from {attacker_ip} port 54321", + f"Jul 26 19:05:00 server sshd[5678]: Accepted password for deploy from {legit_ip} port 22122 ssh2", + ], + "nginx": [ + f'185.220.100.42 - - [26/Jul/2026:19:01:00 +0300] "POST /api/v1/auth/login HTTP/1.1" 401 120', + f'185.220.100.42 - - [26/Jul/2026:19:01:01 +0300] "POST /api/v1/auth/login HTTP/1.1" 401 120', + f'185.220.100.42 - - [26/Jul/2026:19:01:02 +0300] "POST /api/v1/auth/login HTTP/1.1" 401 120', + f'185.220.100.42 - - [26/Jul/2026:19:01:03 +0300] "GET /api/v1/users?id=1 UNION SELECT * FROM users-- HTTP/1.1" 400 80', + f'192.168.1.10 - - [26/Jul/2026:19:02:00 +0300] "GET /dashboard HTTP/1.1" 200 4096', + f'10.0.0.5 - - [26/Jul/2026:19:03:00 +0300] "GET /health HTTP/1.1" 200 32', + ], + "app": [ + "[ERROR] Database connection timeout after 30s — retrying", + "[CRITICAL] Unhandled exception in /api/v1/users/export: PermissionError", + "[ERROR] JWT verification failed for token eyJ0eXAi... from IP 185.220.100.42", + "[INFO] User admin@ghaymah.systems logged in from 192.168.1.10", + "[ERROR] SQL query failed: syntax error near 'UNION'", + ], + } + return sample_lines + + +def read_log_source(name: str, path: str) -> list[str]: + """Read lines from a log file, or fall back to sample data.""" + if os.path.exists(path): + try: + with open(path, "r", errors="replace") as f: + lines = f.readlines() + log.info(f"[{name}] Read {len(lines)} lines from {path}") + return lines + except PermissionError: + log.warning(f"[{name}] Permission denied reading {path} — using sample data") + else: + log.warning(f"[{name}] File not found: {path} — using sample data") + + # Return sample data + return generate_sample_logs().get(name, []) + + +def analyze_auth_log(lines: list[str]): + """Detect brute force SSH attempts.""" + for line in lines: + m = PATTERNS["brute_force"].search(line) + if m: + ip = m.group("ip") + failed_logins[ip] += 1 + + m = PATTERNS["invalid_user"].search(line) + if m: + ip = m.group("ip") + failed_logins[ip] += 1 + + for ip, count in failed_logins.items(): + if count >= ALERT_THRESHOLD_FAIL: + create_alert( + source="auth.log", + alert_type="brute_force_ssh", + severity="CRITICAL", + ip=ip, + detail=f"{count} failed SSH login attempts detected", + ) + + +def analyze_nginx_log(lines: list[str]): + """Detect HTTP flooding and SQL injection attempts.""" + ip_requests = defaultdict(list) + + for line in lines: + m = PATTERNS["nginx_request"].search(line) + if m: + ip = m.group("ip") + path = m.group("path") + status = m.group("status") + ip_requests[ip].append((path, status)) + + # Check for SQL injection in path + if PATTERNS["sql_injection"].search(path): + create_alert( + source="nginx/access.log", + alert_type="sql_injection_attempt", + severity="HIGH", + ip=ip, + detail=f"Possible SQL injection detected in request path: {path[:120]}", + ) + + # Check high request rate + for ip, reqs in ip_requests.items(): + failed = [r for r in reqs if r[1].startswith(("4", "5"))] + if len(reqs) >= ALERT_THRESHOLD_RATE: + create_alert( + source="nginx/access.log", + alert_type="http_flood", + severity="HIGH", + ip=ip, + detail=f"{len(reqs)} requests detected in log window ({len(failed)} errors)", + ) + elif len(failed) >= ALERT_THRESHOLD_FAIL: + create_alert( + source="nginx/access.log", + alert_type="repeated_http_errors", + severity="MEDIUM", + ip=ip, + detail=f"{len(failed)} HTTP error responses to IP in log window", + ) + + +def analyze_app_log(lines: list[str]): + """Detect application-level errors and anomalies.""" + for line in lines: + m = PATTERNS["app_error"].search(line) + if m: + level = m.group("level") + msg = m.group("msg") + + # Extract IP if present + ip_match = re.search(r"\d+\.\d+\.\d+\.\d+", msg) + ip = ip_match.group(0) if ip_match else "unknown" + + if "JWT" in msg or "token" in msg.lower(): + severity = "HIGH" + elif level == "CRITICAL": + severity = "CRITICAL" + else: + severity = "MEDIUM" + create_alert( + source="app/application.log", + alert_type="application_error", + severity=severity, + ip=ip, + detail=msg[:200], + ) + + +def create_alert(source: str, alert_type: str, severity: str, ip: str, detail: str): + """Create a deduplicated alert entry.""" + # Deduplicate: only merge if same type + IP + first 60 chars of detail match. + # This prevents a low-severity alert from absorbing a different high-severity one. + for existing in alerts: + if (existing["type"] == alert_type + and existing["ip"] == ip + and existing["detail"][:60] == detail[:60]): + existing["count"] += 1 + existing["last_seen"] = datetime.now().isoformat() + return + + alert_entry = { + "id": len(alerts) + 1, + "timestamp": datetime.now().isoformat(), + "last_seen": datetime.now().isoformat(), + "source": source, + "type": alert_type, + "severity": severity, + "ip": ip, + "detail": detail, + "count": 1, + "status": "open", + } + alerts.append(alert_entry) + log.warning(f"[ALERT] [{severity}] {alert_type} — IP: {ip} — {detail[:80]}") + + +def run_scan(): + """Main scan loop — reads all 3 log sources and runs analysis. + + NOTE: This implementation is stateless — alert history resets on each + scan cycle. This is acceptable for demo/project use. Production deployments + should persist alert history in a database or SIEM backend (e.g., + Elasticsearch/OpenSearch) to retain trends and support correlation rules. + """ + global alerts, failed_logins + alerts = [] + failed_logins = defaultdict(int) + + log.info("Starting SIEM scan cycle...") + + # Source 1: Auth logs + auth_lines = read_log_source("auth", LOG_SOURCES["auth"]) + analyze_auth_log(auth_lines) + + # Source 2: Nginx access logs + nginx_lines = read_log_source("nginx", LOG_SOURCES["nginx"]) + analyze_nginx_log(nginx_lines) + + # Source 3: Application logs + app_lines = read_log_source("app", LOG_SOURCES["app"]) + analyze_app_log(app_lines) + + # Sort by severity + severity_order = {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3} + alerts.sort(key=lambda a: severity_order.get(a["severity"], 9)) + + output = { + "generated_at": datetime.now().isoformat(), + "total_alerts": len(alerts), + "critical_count": sum(1 for a in alerts if a["severity"] == "CRITICAL"), + "high_count": sum(1 for a in alerts if a["severity"] == "HIGH"), + "medium_count": sum(1 for a in alerts if a["severity"] == "MEDIUM"), + "alerts": alerts, + } + + with open(OUTPUT_FILE, "w") as f: + json.dump(output, f, indent=2) + + log.info(f"Scan complete. {len(alerts)} alerts written to {OUTPUT_FILE}") + return output + + +if __name__ == "__main__": + log.info("=== Ghaymah SIEM Starting ===") + log.info(f"Monitoring: {', '.join(LOG_SOURCES.values())}") + log.info(f"Output: {OUTPUT_FILE}") + + while True: + try: + results = run_scan() + print(f"\n[{datetime.now().strftime('%H:%M:%S')}] Alerts: {results['total_alerts']} " + f"(CRITICAL: {results['critical_count']}, HIGH: {results['high_count']}, " + f"MEDIUM: {results['medium_count']})") + except KeyboardInterrupt: + log.info("SIEM stopped by user.") + break + except Exception as e: + log.error(f"Scan error: {e}") + + time.sleep(SCAN_INTERVAL_SEC) diff --git a/q5-ransomware-response/backup-recovery-strategy.md b/q5-ransomware-response/backup-recovery-strategy.md new file mode 100644 index 0000000..3bc4ba8 --- /dev/null +++ b/q5-ransomware-response/backup-recovery-strategy.md @@ -0,0 +1,163 @@ +# Ghaymah Backup & Recovery Strategy + +## RPO and RTO Targets + +| Metric | Definition | Target for Ghaymah | +|---|---|---| +| **RPO** (Recovery Point Objective) | Maximum acceptable data loss (how old can a backup be?) | **1 hour** — automatic snapshots every hour | +| **RTO** (Recovery Time Objective) | Maximum acceptable downtime (how fast must we recover?) | **4 hours** — from incident declaration to restored service | + +--- + +## The 3-2-1 Backup Rule + +The **3-2-1 rule** is a commonly used backup best practice: + +``` +3 — Keep 3 copies of your data +2 — Store them on 2 different types of media/storage +1 — Keep 1 copy offsite (geographically separate location) +``` + +### How Ghaymah Implements 3-2-1 + +```mermaid +graph TD + subgraph Copy 1 - Primary + LIVE["💻 Production Instance"] + BS["🗄️ SSD Block Storage\n(Attached Volume)"] + LIVE --> BS + end + + subgraph Copy 2 - Cloud Backup + OS["☁️ Ghaymah Object Storage\n(Separate Storage Tier)"] + BS -->|"Automated Hourly Backup\nRetention: 7 days hourly, 30 days daily"| OS + end + + subgraph Copy 3 - Offsite Remote + OFF["🌍 Cold/Archive Storage\n(e.g., Secondary Regional Datacenter)"] + OS -->|"Daily Export\nRetention: 90 days"| OFF + end +``` + +--- + +## Backup Schedule + +| Backup Type | Frequency | Retention | Storage Location | +|---|---|---|---| +| Ghaymah Object Storage backup | Every 1 hour | 7 days | Ghaymah Object Storage (separate from Block Storage) | +| Daily backup | Every 24 hours at 02:00 | 30 days | Ghaymah Object Storage | +| Weekly backup | Every Sunday at 03:00 | 90 days | Offsite / remote region | +| Pre-deployment backup | Before every deployment | 30 days | Ghaymah Object Storage | + +--- + +## Automated Snapshot Script + +```bash +#!/bin/bash +# backup-snapshot.sh — Run via cron every hour + +VOLUME_ID="vol-xxxx-replace-with-actual" +SNAPSHOT_PREFIX="auto-backup" +RETENTION_DAYS=7 +DATE=$(date +%Y%m%d-%H%M) + +echo "[$(date)] Creating snapshot for volume $VOLUME_ID" + +# Create snapshot (replace with actual Ghaymah CLI command) +ghaymah-cli storage snapshot create \ + --volume-id "$VOLUME_ID" \ + --name "${SNAPSHOT_PREFIX}-${DATE}" + +# Clean up snapshots older than retention window +ghaymah-cli storage snapshot list --volume-id "$VOLUME_ID" \ + | awk -v cutoff="$(date -d "$RETENTION_DAYS days ago" +%s)" \ + '$3 < cutoff {print $1}' \ + | xargs -I{} ghaymah-cli storage snapshot delete --snapshot-id {} + +echo "[$(date)] Snapshot created: ${SNAPSHOT_PREFIX}-${DATE}" +``` + +Add to crontab: +```bash +# Run backup every hour at minute 0 +0 * * * * /opt/scripts/backup-snapshot.sh >> /var/log/backup.log 2>&1 +``` + +--- + +## Recovery Procedure + +### Standard Recovery (planned or scheduled) + +```bash +# 1. List available snapshots +ghaymah-cli storage snapshot list --volume-id vol-xxxx + +# 2. Create new volume from snapshot +ghaymah-cli storage volume create-from-snapshot \ + --snapshot-id snap-xxxx \ + --name recovery-$(date +%Y%m%d) + +# 3. Detach old volume (if still attached) +ghaymah-cli storage volume detach --instance-id inst-xxxx --volume-id vol-old + +# 4. Attach new volume +ghaymah-cli storage volume attach --instance-id inst-xxxx --volume-id vol-new + +# 5. Mount and verify +sudo mount /dev/sdb /mnt/data +ls -la /mnt/data +``` + +### Emergency Recovery (ransomware or corruption) + +1. Use emergency-plan.md for first 60 minutes. +2. Identify last clean snapshot from **before** the incident timestamp. +3. Never mount suspicious volumes to production instances. +4. Always verify restored data integrity before going live. + +--- + +## Backup Integrity Verification + +Monthly verification test: + +```bash +#!/bin/bash +# verify-backup.sh — Monthly DR drill + +echo "=== Backup Verification Test ===" +echo "Date: $(date)" + +# 1. Identify latest snapshot +LATEST_SNAP=$(ghaymah-cli storage snapshot list --volume-id vol-xxxx \ + | sort -k3 -r | head -1 | awk '{print $1}') + +# 2. Create test restore volume +ghaymah-cli storage volume create-from-snapshot \ + --snapshot-id "$LATEST_SNAP" \ + --name test-restore-$(date +%Y%m%d) + +# 3. Attach to test instance (never production) +ghaymah-cli storage volume attach --instance-id inst-test --volume-id vol-test + +# 4. Verify expected file structure +EXPECTED_COUNT=$(cat /opt/backup-manifest/expected-file-count.txt) +ACTUAL_COUNT=$(find /mnt/test-restore -type f | wc -l) + +echo "Expected files: $EXPECTED_COUNT" +echo "Actual files: $ACTUAL_COUNT" + +if [ "$ACTUAL_COUNT" -ge "$EXPECTED_COUNT" ]; then + echo "[PASS] Backup integrity verified" +else + echo "[FAIL] File count mismatch — alert secops team" +fi + +# 5. Cleanup test volume +ghaymah-cli storage volume detach --instance-id inst-test --volume-id vol-test +ghaymah-cli storage volume delete --volume-id vol-test +``` diff --git a/q5-ransomware-response/emergency-plan.md b/q5-ransomware-response/emergency-plan.md new file mode 100644 index 0000000..e0f23de --- /dev/null +++ b/q5-ransomware-response/emergency-plan.md @@ -0,0 +1,130 @@ +# Emergency Plan — First 60 Minutes of Ransomware Incident + +> **Scenario:** All Block Storage files on Ghaymah cloud are encrypted with a ransom message. + +--- + +## ⏱ Minute 0–5: Detect & Confirm + +**Trigger Indicators:** +- Files renamed to `*.encrypted` or `*.locked` +- Ransom note file: `READ_ME_TO_DECRYPT.txt` +- Sudden spike in Block Storage write IOPS +- Applications returning file-not-found errors + +**Immediate Actions:** +1. Alert the security team and management — declare a P1 incident. +2. Do NOT pay the ransom at this stage. +3. Do NOT reboot or shut down the instance (preserves memory evidence). +4. Take a forensic snapshot of the current Block Storage volume to preserve evidence. **Do not restore from this snapshot** — it may contain encrypted files. Restore from the last clean backup taken before the encryption event. + +```bash +# Forensic snapshot — evidence preservation only +ghaymah-cli storage snapshot create --volume-id vol-xxxx --name ransomware-forensic-$(date +%Y%m%d) +``` + +--- + +## ⏱ Minute 5–15: Isolate + +**Goal:** Stop the ransomware from spreading to other systems. + +| Action | Method | +|---|---| +| Isolate the infected instance | Remove from load balancer pool immediately | +| Block all outbound traffic | Apply deny-all egress firewall rule to the instance | +| Revoke instance API credentials | Rotate IAM keys/tokens used by the instance | +| Disconnect Block Storage | Detach volume to prevent further encryption | +| Alert other teams | Notify DB admins, network team, management | + +```bash +# Detach Block Storage volume +ghaymah-cli storage volume detach --instance-id inst-xxxx --volume-id vol-xxxx + +# Apply deny-all network rule (Ghaymah firewall) +ghaymah-cli network firewall add-rule \ + --instance inst-xxxx \ + --direction egress \ + --action deny \ + --priority 1 +``` + +--- + +## ⏱ Minute 15–30: Assess the Damage + +**Goal:** Understand the scope of encryption and identify the attack vector. + +1. **Check which files are encrypted:** + ```bash + # On a forensic copy only + find /mnt/forensic-copy -name "*.encrypted" -o -name "*.locked" | wc -l + ``` + +2. **Identify ransomware family** (from ransom note + file extensions). + +3. **Check intrusion timeline** — review access logs from the past 48 hours: + ```bash + grep -i "POST\|PUT" /var/log/nginx/access.log | tail -500 + journalctl --since "48 hours ago" | grep -E "error|fail|unauthorized" + ``` + +4. **Identify the attack vector:** + - Phishing email with malicious attachment? + - Exposed RDP/SSH with weak credentials? + - Vulnerable web application? + - Compromised supply chain dependency? + +5. **Check for legitimate decryption tools:** Search security databases (NoMoreRansom.org) — some ransomware strains have free decryptors. + +--- + +## ⏱ Minute 30–45: Begin Recovery + +**Goal:** Restore services from the last clean backup. + +1. Identify the last clean backup snapshot (before encryption): + ```bash + ghaymah-cli storage snapshot list --volume-id vol-xxxx + # Look for the last snapshot BEFORE the ransomware event timestamp + ``` + +2. Create a new volume from the clean snapshot: + ```bash + ghaymah-cli storage volume create-from-snapshot \ + --snapshot-id snap-clean-xxxx \ + --name restored-volume-$(date +%Y%m%d) + ``` + +3. Attach the restored volume to a clean, rebuilt instance. + +4. Verify data integrity before bringing services back online: + ```bash + # Check file counts match expected + find /mnt/restored -type f | wc -l + # Run application health checks + curl -f http://localhost:8080/health + ``` + +--- + +## ⏱ Minute 45–60: Restore Service & Communicate + +1. Re-add restored instance to the load balancer. +2. Monitor for any re-infection indicators (file modification spikes). +3. Send internal status update: scope, services affected, ETA for full recovery. +4. Prepare customer/stakeholder disclosure notification (if PII was exposed). +5. Preserve the forensic snapshot for later analysis and potential law enforcement reporting. + +--- + +## Incident Commander Checklist + +- [ ] P1 alert sent to all stakeholders +- [ ] Infected instance isolated (firewall + load balancer) +- [ ] Block Storage detached +- [ ] Forensic snapshot taken +- [ ] Clean backup identified +- [ ] Restoration in progress +- [ ] Communication sent to affected parties +- [ ] Legal/compliance team notified diff --git a/q5-ransomware-response/prevention-plan.md b/q5-ransomware-response/prevention-plan.md new file mode 100644 index 0000000..0b64eac --- /dev/null +++ b/q5-ransomware-response/prevention-plan.md @@ -0,0 +1,167 @@ +# Comprehensive Ransomware Prevention Plan + +> Goal: Eliminate the key attack vectors that allow ransomware to reach and encrypt Ghaymah Block Storage. + +--- + +## Prevention Layer 1: Access Control & Authentication + +### 1.1 Eliminate Password-Only Authentication +- **Replace SSH passwords with SSH keys** for all server access. +- Disable password-based SSH login: + ```bash + # /etc/ssh/sshd_config + PasswordAuthentication no + PermitRootLogin no + PubkeyAuthentication yes + ``` +- Restrict SSH access to a VPN or bastion host only. + +### 1.2 Enforce Multi-Factor Authentication (MFA) +- Require MFA for: + - Cloud console / Ghaymah dashboard access + - All admin and privileged user accounts + - CI/CD pipeline credentials + +### 1.3 Principle of Least Privilege +- Application containers and services should **never** have Block Storage mount access unless explicitly required. +- Use separate IAM roles: one for read, one for write, none for delete by default. +- Administrative access to cloud resources requires MFA + session time limit. + +--- + +## Prevention Layer 2: Endpoint & System Hardening + +### 2.1 Keep Systems Patched +```bash +# Automate security updates (Ubuntu/Debian) +sudo apt-get install unattended-upgrades -y +sudo dpkg-reconfigure --priority=low unattended-upgrades +``` + +### 2.2 Restrict Executable Permissions +- Mount Block Storage with `noexec` flag to prevent direct execution of files from storage: + ```bash + # /etc/fstab + /dev/sdb /mnt/data ext4 defaults,noexec,nosuid 0 2 + ``` +- This means even if a ransomware binary is uploaded to Block Storage, it cannot run directly from there. + +### 2.3 Disable Unused Services +```bash +# Disable unnecessary services +sudo systemctl disable --now telnet ftp rpcbind +sudo ufw enable +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow 22/tcp # SSH from known IPs only +sudo ufw allow 443/tcp # HTTPS +``` + +--- + +## Prevention Layer 3: Network Security + +### 3.1 Segment the Network +- Block Storage volumes should only be attached to authorized instances and protected from unauthorized access. +- Use private subnets: + ``` + Public subnet: Load Balancer, API Gateway + Private subnet: Application Servers, Block Storage + Database subnet: PostgreSQL, Redis (no internet access) + ``` + +### 3.2 Block Lateral Movement +Apply Ghaymah network policies to prevent instances from communicating with each other unless explicitly needed: + +```yaml +# Network policy: deny all east-west traffic by default +# Only allow app-server → database on port 5432 +# Only allow app-server → block-storage on mount connection +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-lateral-movement +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + egress: + - to: + - podSelector: + matchLabels: + tier: database + ports: + - port: 5432 +``` + +### 3.3 DNS Filtering & Egress Control +- Implement DNS-based blocking to prevent ransomware C2 (command-and-control) communication. +- Block outbound traffic to known malicious domains using a threat intelligence feed. +- Allow-list only required outbound destinations (e.g., update servers, CDNs). + +--- + +## Prevention Layer 4: Email & Social Engineering Defense + +| Control | Implementation | +|---|---| +| Email filtering | Block executable attachments (.exe, .bat, .ps1, .vbs) | +| Link scanning | Scan all URLs in emails before delivery | +| Phishing simulation | Run quarterly phishing drills with staff | +| Security awareness training | Train all employees on ransomware recognition | +| DMARC/SPF/DKIM | Prevent email spoofing using DNS mail security records | + +--- + +## Prevention Layer 5: Monitoring & Early Detection + +### 5.1 File Integrity Monitoring (FIM) +Monitor Block Storage for unusual file rename patterns: + +```bash +# Install auditd for file system monitoring +sudo apt-get install auditd -y + +# Watch for mass file renames (ransomware signature) +auditctl -w /mnt/data -p wra -k file_modification + +# Alert on rename events +ausearch -k file_modification | grep "rename" +``` + +### 5.2 SIEM Alerts (from Q4) +Configure the SIEM (`siem.py`) to detect early ransomware indicators: +- Sudden spike in Block Storage write IOPS (>1000 writes/minute) +- Mass file extension changes +- New processes accessing large numbers of files in seconds +- Outbound connections to unknown external IPs from storage-tier containers + +### 5.3 Immutable Block Storage Snapshots +Configure snapshots with **Object Lock** (immutable mode) so they cannot be deleted — even by an admin account — for a defined retention period: +```bash +# Example command — replace with actual Ghaymah immutable storage configuration +ghaymah-cli storage bucket set-object-lock \ + --bucket siem-backups \ + --mode COMPLIANCE \ + --retention-days 30 +``` + +--- + +## Prevention Checklist Summary + +| Priority | Control | Status | +|---|---|---| +| 🔴 Critical | SSH key-only authentication | Implement immediately | +| 🔴 Critical | MFA for cloud console | Implement immediately | +| 🔴 Critical | Least-privilege IAM roles | Implement immediately | +| 🟠 High | Automated OS patching | This week | +| 🟠 High | Network segmentation (public/private subnets) | This week | +| 🟠 High | `noexec` on Block Storage mounts | This week | +| 🟠 High | Immutable backup snapshots | This week | +| 🟡 Medium | DNS filtering / egress control | This month | +| 🟡 Medium | File Integrity Monitoring (FIM) | This month | +| 🟡 Medium | Phishing simulation program | This quarter | +| 🟢 Low | Security awareness training | This quarter |