diff --git a/extensions/sysmon/README.md b/extensions/sysmon/README.md new file mode 100755 index 00000000..7a18c336 --- /dev/null +++ b/extensions/sysmon/README.md @@ -0,0 +1,38 @@ +# Sysmon extension + +- Extension Name: sysmon +- Description: Deploy Sysmon with olafhartong modular config to all Windows domain machines +- Machine name: none (agent-only extension) +- Compatible with labs: * + +## What it does + +- Installs **Sysmon64** on every Windows machine in the `domain` group +- Uses **[olafhartong's sysmon-modular config](https://github.com/olafhartong/sysmon-modular)** for comprehensive detection coverage +- Covers: process creation, network connections, file creation, registry events, DNS queries, pipe events, WMI events, and more +- If Sysmon is already installed, updates the config in-place + +## No prerequisites + +No new VM is provisioned. This extension is agent-only. + +## Install + +``` +instance_id> install_extension sysmon +``` + +## Purple team value + +Sysmon events complement Windows Security event logs and are essential for detecting: +- Lateral movement (PtH, PtT, WMI, PSExec) +- Credential dumping (LSASS access) +- Persistence (registry, scheduled tasks, WMI subscriptions) +- C2 beaconing (DNS, network connections) +- LOLBins and living-off-the-land techniques + +Pairs well with the **elk** and **wazuh** extensions for log ingestion. + +## Credits +- [olafhartong/sysmon-modular](https://github.com/olafhartong/sysmon-modular) +- Sysinternals Sysmon: https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon diff --git a/extensions/sysmon/ansible/install.yml b/extensions/sysmon/ansible/install.yml new file mode 100755 index 00000000..c7bb2489 --- /dev/null +++ b/extensions/sysmon/ansible/install.yml @@ -0,0 +1,4 @@ +- name: Deploy Sysmon to all Windows domain machines + hosts: sysmon_targets + roles: + - { role: 'sysmon_windows', tags: 'sysmon' } diff --git a/extensions/sysmon/ansible/roles/sysmon_windows/defaults/main.yml b/extensions/sysmon/ansible/roles/sysmon_windows/defaults/main.yml new file mode 100755 index 00000000..b530e4b8 --- /dev/null +++ b/extensions/sysmon/ansible/roles/sysmon_windows/defaults/main.yml @@ -0,0 +1,9 @@ +# Sysmon binary - downloaded from Sysinternals +sysmon_download_url: "https://download.sysinternals.com/files/Sysmon.zip" +sysmon_install_location: "c:\\sysmon" + +# olafhartong modular sysmon config (comprehensive detection coverage) +sysmon_config_url: "https://raw.githubusercontent.com/olafhartong/sysmon-modular/master/sysmonconfig.xml" +sysmon_config_file: "sysmonconfig.xml" + +sysmon_service_name: "sysmon64" diff --git a/extensions/sysmon/ansible/roles/sysmon_windows/tasks/main.yml b/extensions/sysmon/ansible/roles/sysmon_windows/tasks/main.yml new file mode 100755 index 00000000..8f9a6858 --- /dev/null +++ b/extensions/sysmon/ansible/roles/sysmon_windows/tasks/main.yml @@ -0,0 +1,57 @@ +- name: Check if Sysmon service exists + win_service: + name: "{{ sysmon_service_name }}" + register: sysmon_service + failed_when: false + +- name: Create Sysmon install directory + ansible.windows.win_file: + path: "{{ sysmon_install_location }}" + state: directory + +- name: Download Sysmon zip + win_get_url: + url: "{{ sysmon_download_url }}" + dest: "{{ sysmon_install_location }}\\Sysmon.zip" + register: sysmon_download + until: sysmon_download is succeeded + retries: 3 + delay: 5 + when: not sysmon_service.exists + +- name: Unzip Sysmon + community.windows.win_unzip: + src: "{{ sysmon_install_location }}\\Sysmon.zip" + dest: "{{ sysmon_install_location }}" + when: not sysmon_service.exists + +- name: Download olafhartong modular sysmon config + win_get_url: + url: "{{ sysmon_config_url }}" + dest: "{{ sysmon_install_location }}\\{{ sysmon_config_file }}" + register: sysmon_config_download + until: sysmon_config_download is succeeded + retries: 3 + delay: 5 + +- name: Install Sysmon with modular config + win_command: > + {{ sysmon_install_location }}\Sysmon64.exe -accepteula -i + {{ sysmon_install_location }}\{{ sysmon_config_file }} + args: + chdir: "{{ sysmon_install_location }}" + when: not sysmon_service.exists + +- name: Update Sysmon config if already installed + win_command: > + {{ sysmon_install_location }}\Sysmon64.exe -c + {{ sysmon_install_location }}\{{ sysmon_config_file }} + args: + chdir: "{{ sysmon_install_location }}" + when: sysmon_service.exists + +- name: Ensure Sysmon service is running + win_service: + name: "{{ sysmon_service_name }}" + state: started + start_mode: auto diff --git a/extensions/sysmon/extension.json b/extensions/sysmon/extension.json new file mode 100755 index 00000000..4c462b5f --- /dev/null +++ b/extensions/sysmon/extension.json @@ -0,0 +1,9 @@ +{ + "name": "sysmon", + "description": "Deploy Sysmon with olafhartong modular config to all Windows domain machines", + "machines": [], + "compatibility": [ + "*" + ], + "impact": "installs Sysmon64 on all Windows domain machines with a modular detection-focused configuration" +} diff --git a/extensions/sysmon/inventory b/extensions/sysmon/inventory new file mode 100755 index 00000000..5b07adbc --- /dev/null +++ b/extensions/sysmon/inventory @@ -0,0 +1,5 @@ +; EXTENSION : SYSMON ------------------------------------------ +; No new machine - agents only + +[sysmon_targets:children] +domain diff --git a/extensions/velociraptor/README.md b/extensions/velociraptor/README.md new file mode 100755 index 00000000..68fcc5a1 --- /dev/null +++ b/extensions/velociraptor/README.md @@ -0,0 +1,77 @@ +# Velociraptor extension + +- Extension Name: velociraptor +- Description: Add Velociraptor DFIR platform - server + agents on all Windows domain machines +- Machine name: `{{lab_name}}-VELO` +- IP: `{{ip_range}}.54` +- Compatible with labs: * + +## What it does + +- Spins up an **Ubuntu 22.04** VM running the **Velociraptor** server +- Generates server config and auto-repackages the Windows agent MSI with embedded certs +- Deploys the **Velociraptor agent** to every Windows machine in the `domain` group +- Exposes the **Velociraptor GUI** on port `8889` + +## Prerequisites + +On ludus prepare template: +``` +ludus templates add -d ubuntu-22.04-x64-server +ludus templates build +``` + +## Install + +``` +instance_id> install_extension velociraptor +``` + +## Access + +After installation, access the web UI at: +``` +https://.54:8889 +Username: admin +Password: Velo@GOAD2024! +``` + +> Note: The cert is self-signed — accept the browser warning. + +## Useful VQL hunts for purple teaming + +```sql +-- Find all processes with LSASS handles (credential dumping) +SELECT Pid, Name, CommandLine FROM pslist() +WHERE Name =~ "lsass" + +-- Hunt for scheduled tasks (persistence) +SELECT * FROM Artifact.Windows.System.ScheduledTasks() + +-- Find lateral movement via WMI +SELECT * FROM Artifact.Windows.EventLogs.EvtxHunter( + EvtxGlob="**\\Security.evtx", + IdFilter="4648" +) + +-- Detect Kerberoasting (TGS requests for service accounts) +SELECT * FROM Artifact.Windows.EventLogs.EvtxHunter( + EvtxGlob="**\\Security.evtx", + IdFilter="4769" +) +WHERE TicketEncryptionType = "0x17" +``` + +## Purple team value + +Velociraptor is a **live forensics and endpoint hunting** platform: +- **Incident response**: Live memory, process, registry, filesystem triage +- **Threat hunting**: VQL queries across the entire fleet simultaneously +- **Detection validation**: Confirm whether attacks were actually executed and what artifacts they left +- **Timeline reconstruction**: Correlate artifacts across multiple machines + +Pairs well with **sysmon** (for enriched Windows events) and **zeek** (for network context). + +## Credits +- https://github.com/Velocidex/velociraptor +- https://docs.velociraptor.app/ diff --git a/extensions/velociraptor/ansible/install.yml b/extensions/velociraptor/ansible/install.yml new file mode 100755 index 00000000..e8f50759 --- /dev/null +++ b/extensions/velociraptor/ansible/install.yml @@ -0,0 +1,12 @@ +- name: Install Velociraptor server + hosts: velociraptor_server + become: yes + roles: + - { role: 'velociraptor_server', tags: 'velociraptor_server' } + +- name: Deploy Velociraptor agent to Windows machines + hosts: velociraptor_agents + roles: + - { role: 'velociraptor_agent', tags: 'velociraptor_agent' } + vars: + velociraptor_server_host: "{{ hostvars['velociraptor']['ansible_host'] }}" diff --git a/extensions/velociraptor/ansible/roles/velociraptor_agent/defaults/main.yml b/extensions/velociraptor/ansible/roles/velociraptor_agent/defaults/main.yml new file mode 100755 index 00000000..a015833b --- /dev/null +++ b/extensions/velociraptor/ansible/roles/velociraptor_agent/defaults/main.yml @@ -0,0 +1,3 @@ +velociraptor_agent_install_location: "c:\\tmp" +velociraptor_agent_msi_name: "velociraptor-agent.msi" +velociraptor_agent_service_name: "Velociraptor" diff --git a/extensions/velociraptor/ansible/roles/velociraptor_agent/tasks/main.yml b/extensions/velociraptor/ansible/roles/velociraptor_agent/tasks/main.yml new file mode 100755 index 00000000..1e8c3c0c --- /dev/null +++ b/extensions/velociraptor/ansible/roles/velociraptor_agent/tasks/main.yml @@ -0,0 +1,39 @@ +- name: Check if Velociraptor agent service exists + win_service: + name: "{{ velociraptor_agent_service_name }}" + register: velo_agent_service + failed_when: false + +- name: Create agent install directory + ansible.windows.win_file: + path: "{{ velociraptor_agent_install_location }}" + state: directory + +# Fetch the repacked MSI from the Velociraptor server via SSH/fetch +- name: Fetch repacked Velociraptor agent MSI from server + ansible.builtin.fetch: + src: "/opt/velociraptor/velociraptor-agent.msi" + dest: "/tmp/velociraptor-agent.msi" + flat: yes + delegate_to: "{{ velociraptor_server_host }}" + become: yes + run_once: true + when: not velo_agent_service.exists + +- name: Copy Velociraptor agent MSI to Windows machine + win_copy: + src: "/tmp/velociraptor-agent.msi" + dest: "{{ velociraptor_agent_install_location }}\\{{ velociraptor_agent_msi_name }}" + when: not velo_agent_service.exists + +- name: Install Velociraptor agent MSI + win_command: > + msiexec.exe /i "{{ velociraptor_agent_install_location }}\{{ velociraptor_agent_msi_name }}" /qn + when: not velo_agent_service.exists + +- name: Ensure Velociraptor agent service is running + win_service: + name: "{{ velociraptor_agent_service_name }}" + state: started + start_mode: auto + when: not velo_agent_service.exists diff --git a/extensions/velociraptor/ansible/roles/velociraptor_server/defaults/main.yml b/extensions/velociraptor/ansible/roles/velociraptor_server/defaults/main.yml new file mode 100755 index 00000000..d756a7a0 --- /dev/null +++ b/extensions/velociraptor/ansible/roles/velociraptor_server/defaults/main.yml @@ -0,0 +1,18 @@ +# Velociraptor version - check https://github.com/Velocidex/velociraptor/releases +velociraptor_version: "0.72.4" + +velociraptor_linux_url: "https://github.com/Velocidex/velociraptor/releases/download/v{{ velociraptor_version }}/velociraptor-v{{ velociraptor_version }}-linux-amd64" +velociraptor_windows_url: "https://github.com/Velocidex/velociraptor/releases/download/v{{ velociraptor_version }}/velociraptor-v{{ velociraptor_version }}-windows-amd64.exe" +velociraptor_windows_msi_url: "https://github.com/Velocidex/velociraptor/releases/download/v{{ velociraptor_version }}/velociraptor-v{{ velociraptor_version }}-windows-amd64.msi" + +velociraptor_install_dir: "/opt/velociraptor" +velociraptor_config_dir: "/etc/velociraptor" +velociraptor_binary: "/usr/local/bin/velociraptor" + +# Web UI / API +velociraptor_gui_port: 8889 +velociraptor_frontend_port: 8000 + +# Admin credentials for the web UI +velociraptor_admin_user: "admin" +velociraptor_admin_password: "Velo@GOAD2024!" diff --git a/extensions/velociraptor/ansible/roles/velociraptor_server/tasks/main.yml b/extensions/velociraptor/ansible/roles/velociraptor_server/tasks/main.yml new file mode 100755 index 00000000..dc5ee8bc --- /dev/null +++ b/extensions/velociraptor/ansible/roles/velociraptor_server/tasks/main.yml @@ -0,0 +1,106 @@ +- name: Check Velociraptor service facts + ansible.builtin.service_facts: + +- name: Create Velociraptor directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: '0750' + loop: + - "{{ velociraptor_install_dir }}" + - "{{ velociraptor_config_dir }}" + +- name: Download Velociraptor binary + ansible.builtin.get_url: + url: "{{ velociraptor_linux_url }}" + dest: "{{ velociraptor_binary }}" + mode: '0755' + when: not ansible_facts.services['velociraptor.service'] is defined + +# Generate server config non-interactively using --merge to set hostname/ports +- name: Generate Velociraptor server config + ansible.builtin.shell: | + {{ velociraptor_binary }} config generate \ + --merge '{"Frontend":{"hostname":"{{ ansible_host }}","bind_address":"0.0.0.0","bind_port":{{ velociraptor_frontend_port }}},"GUI":{"bind_address":"0.0.0.0","bind_port":{{ velociraptor_gui_port }}},"Client":{"server_urls":["https://{{ ansible_host }}:{{ velociraptor_frontend_port }}/"]},"logging":{"output_directory":"/opt/velociraptor/logs","separate_logs_per_component":true}}' \ + > {{ velociraptor_config_dir }}/server.config.yaml + args: + creates: "{{ velociraptor_config_dir }}/server.config.yaml" + +- name: Secure server config + ansible.builtin.file: + path: "{{ velociraptor_config_dir }}/server.config.yaml" + mode: '0600' + +# Extract client config from server config for agent packaging +- name: Extract client config + ansible.builtin.shell: | + {{ velociraptor_binary }} \ + --config {{ velociraptor_config_dir }}/server.config.yaml \ + config client > {{ velociraptor_config_dir }}/client.config.yaml + args: + creates: "{{ velociraptor_config_dir }}/client.config.yaml" + +# Download Windows MSI for repack +- name: Download Windows MSI + ansible.builtin.get_url: + url: "{{ velociraptor_windows_msi_url }}" + dest: "{{ velociraptor_install_dir }}/velociraptor-windows-amd64.msi" + when: not ansible_facts.services['velociraptor.service'] is defined + +# Repack the MSI with the embedded client config +- name: Repack Windows agent MSI with client config + ansible.builtin.shell: | + {{ velociraptor_binary }} config repack \ + --exe {{ velociraptor_install_dir }}/velociraptor-windows-amd64.msi \ + {{ velociraptor_config_dir }}/client.config.yaml \ + {{ velociraptor_install_dir }}/velociraptor-agent.msi + args: + creates: "{{ velociraptor_install_dir }}/velociraptor-agent.msi" + +# Add admin user +- name: Add Velociraptor admin user + ansible.builtin.shell: | + echo "{{ velociraptor_admin_password }}" | \ + {{ velociraptor_binary }} \ + --config {{ velociraptor_config_dir }}/server.config.yaml \ + user add {{ velociraptor_admin_user }} --role=administrator + register: user_add + failed_when: user_add.rc != 0 and 'already exists' not in user_add.stderr + changed_when: "'already exists' not in user_add.stderr" + +# Create systemd service +- name: Install Velociraptor systemd service + ansible.builtin.copy: + dest: /etc/systemd/system/velociraptor.service + content: | + [Unit] + Description=Velociraptor DFIR Platform + After=network.target + + [Service] + Type=simple + ExecStart={{ velociraptor_binary }} --config {{ velociraptor_config_dir }}/server.config.yaml frontend -v + Restart=on-failure + RestartSec=10 + LimitNOFILE=65536 + + [Install] + WantedBy=multi-user.target + owner: root + group: root + mode: '0644' + +- name: Enable and start Velociraptor service + ansible.builtin.systemd: + name: velociraptor + state: started + enabled: yes + daemon_reload: yes + +- name: Display Velociraptor access info + ansible.builtin.debug: + msg: + - "Velociraptor GUI : https://{{ ansible_host }}:{{ velociraptor_gui_port }}" + - "Username : {{ velociraptor_admin_user }}" + - "Password : {{ velociraptor_admin_password }}" + - "Agent MSI : {{ velociraptor_install_dir }}/velociraptor-agent.msi" diff --git a/extensions/velociraptor/extension.json b/extensions/velociraptor/extension.json new file mode 100755 index 00000000..d0c80624 --- /dev/null +++ b/extensions/velociraptor/extension.json @@ -0,0 +1,11 @@ +{ + "name": "velociraptor", + "description": "Add Velociraptor DFIR platform - server + agents on all Windows domain machines", + "machines": [ + "velociraptor" + ], + "compatibility": [ + "*" + ], + "impact": "add a linux machine running Velociraptor server and deploy Velociraptor agents to all Windows domain machines" +} diff --git a/extensions/velociraptor/inventory b/extensions/velociraptor/inventory new file mode 100755 index 00000000..a341017c --- /dev/null +++ b/extensions/velociraptor/inventory @@ -0,0 +1,12 @@ +; EXTENSION : VELOCIRAPTOR ------------------------------------------ +[default] +velociraptor ansible_host={{ip_range}}.54 ansible_connection=ssh ansible_ssh_common_args='-o StrictHostKeyChecking=no' + +[extensions] +velociraptor + +[velociraptor_server] +velociraptor + +[velociraptor_agents:children] +domain diff --git a/extensions/velociraptor/providers/aws/linux.tf b/extensions/velociraptor/providers/aws/linux.tf new file mode 100755 index 00000000..e91065ab --- /dev/null +++ b/extensions/velociraptor/providers/aws/linux.tf @@ -0,0 +1,9 @@ +"velociraptor" = { + name = "velociraptor" + linux_sku = "22_04-lts-gen2" + linux_version = "latest" + ami = "ami-00c71bd4d220aa22a" + private_ip_address = "{{ip_range}}.54" + password = "Velo@GOAD2024!" + size = "t2.medium" # 2cpu / 4GB +} diff --git a/extensions/velociraptor/providers/azure/linux.tf b/extensions/velociraptor/providers/azure/linux.tf new file mode 100755 index 00000000..53d7fc60 --- /dev/null +++ b/extensions/velociraptor/providers/azure/linux.tf @@ -0,0 +1,9 @@ +"velociraptor" = { + name = "velociraptor" + linux_sku = "22_04-lts-gen2" + linux_version = "latest" + ami = "" + private_ip_address = "{{ip_range}}.54" + password = "Velo@GOAD2024!" + size = "Standard_B2s" # 2cpu / 4GB +} diff --git a/extensions/velociraptor/providers/ludus/config.yml b/extensions/velociraptor/providers/ludus/config.yml new file mode 100755 index 00000000..70438135 --- /dev/null +++ b/extensions/velociraptor/providers/ludus/config.yml @@ -0,0 +1,8 @@ + - vm_name: "{{ range_id }}-VELO" + hostname: "{{ range_id }}-VELO" + template: ubuntu-22.04-x64-server-template + vlan: 10 + ip_last_octet: 54 + ram_gb: 4 + cpus: 2 + linux: true diff --git a/extensions/velociraptor/providers/virtualbox/Vagrantfile b/extensions/velociraptor/providers/virtualbox/Vagrantfile new file mode 100755 index 00000000..dc6f7a4f --- /dev/null +++ b/extensions/velociraptor/providers/virtualbox/Vagrantfile @@ -0,0 +1,13 @@ +boxes.append( + { :name => "{{lab_name}}-VELO", + :ip => "{{ip_range}}.54", + :box => "bento/ubuntu-22.04", + :os => "linux", + :cpus => 2, + :mem => 4096, + :forwarded_port => [ + {:guest => 22, :host => 2212, :id => "ssh"}, + {:guest => 8889, :host => 8889, :id => "gui"} + ] + } +) diff --git a/extensions/velociraptor/providers/vmware/Vagrantfile b/extensions/velociraptor/providers/vmware/Vagrantfile new file mode 100755 index 00000000..dc6f7a4f --- /dev/null +++ b/extensions/velociraptor/providers/vmware/Vagrantfile @@ -0,0 +1,13 @@ +boxes.append( + { :name => "{{lab_name}}-VELO", + :ip => "{{ip_range}}.54", + :box => "bento/ubuntu-22.04", + :os => "linux", + :cpus => 2, + :mem => 4096, + :forwarded_port => [ + {:guest => 22, :host => 2212, :id => "ssh"}, + {:guest => 8889, :host => 8889, :id => "gui"} + ] + } +) diff --git a/extensions/zeek/README.md b/extensions/zeek/README.md new file mode 100755 index 00000000..36fab773 --- /dev/null +++ b/extensions/zeek/README.md @@ -0,0 +1,59 @@ +# Zeek extension + +- Extension Name: zeek +- Description: Add a Zeek network security monitor to the lab +- Machine name: `{{lab_name}}-ZEEK` +- IP: `{{ip_range}}.53` +- Compatible with labs: * + +## What it does + +- Spins up an **Ubuntu 22.04** VM running **Zeek** (formerly Bro) +- Passively monitors all lab network traffic on `eth1` (the host-only/lab interface) +- Enables **JSON log output** for easy ingestion into ELK, Splunk, or other SIEMs +- Loads AD-relevant protocol analyzers: SMB, DCE-RPC, Kerberos, RDP, LDAP +- Sets up `zeekctl cron` every 5 minutes for log rotation and health checks + +## Prerequisites + +On ludus prepare template: +``` +ludus templates add -d ubuntu-22.04-x64-server +ludus templates build +``` + +## Install + +``` +instance_id> install_extension zeek +``` + +## Useful commands (on the Zeek VM) + +```bash +# Check status +zeekctl status + +# View live DNS logs +tail -f /opt/zeek/logs/current/dns.log | jq . + +# View Kerberos traffic +tail -f /opt/zeek/logs/current/kerberos.log | jq . + +# View SMB activity +tail -f /opt/zeek/logs/current/smb_files.log | jq . + +# View DCE-RPC calls (lateral movement) +tail -f /opt/zeek/logs/current/dce_rpc.log | jq . +``` + +## Purple team value + +Zeek provides **network-layer** visibility that host-based agents (Sysmon, Wazuh) cannot see: +- Kerberoasting / AS-REP roasting (unusual Kerberos ticket requests) +- Pass-the-Hash / lateral movement (SMB/DCE-RPC patterns) +- LDAP enumeration (large LDAP queries) +- DNS-based C2 / exfiltration +- Unusual authentication patterns across the domain + +Pairs well with **sysmon** (host) + **elk** or **wazuh** (SIEM) for full coverage. diff --git a/extensions/zeek/ansible/install.yml b/extensions/zeek/ansible/install.yml new file mode 100755 index 00000000..df3d8e67 --- /dev/null +++ b/extensions/zeek/ansible/install.yml @@ -0,0 +1,5 @@ +- name: Install Zeek network security monitor + hosts: zeek_server + become: yes + roles: + - { role: 'zeek', tags: 'zeek' } diff --git a/extensions/zeek/ansible/roles/zeek/defaults/main.yml b/extensions/zeek/ansible/roles/zeek/defaults/main.yml new file mode 100755 index 00000000..a0f4ce90 --- /dev/null +++ b/extensions/zeek/ansible/roles/zeek/defaults/main.yml @@ -0,0 +1,17 @@ +# Zeek version from the official repo +zeek_version: "7.0" + +# Interface to monitor - eth1 is typically the host-only/lab network on Vagrant VMs +zeek_monitor_interface: "eth1" + +# Log directory +zeek_log_dir: "/opt/zeek/logs" + +# Enable JSON logging for easier ingestion into SIEM +zeek_json_logs: true + +# Packages to install alongside Zeek +zeek_packages: + - zeek + - zeek-core + - zeekctl diff --git a/extensions/zeek/ansible/roles/zeek/tasks/main.yml b/extensions/zeek/ansible/roles/zeek/tasks/main.yml new file mode 100755 index 00000000..a73d2ca3 --- /dev/null +++ b/extensions/zeek/ansible/roles/zeek/tasks/main.yml @@ -0,0 +1,117 @@ +- name: Install prerequisites + ansible.builtin.apt: + name: + - curl + - gnupg2 + - apt-transport-https + state: present + update_cache: yes + +- name: Add Zeek GPG key + ansible.builtin.apt_key: + url: "https://download.opensuse.org/repositories/security:zeek/xUbuntu_22.04/Release.key" + state: present + +- name: Add Zeek repository + ansible.builtin.apt_repository: + repo: "deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /" + state: present + update_cache: yes + +- name: Install Zeek + ansible.builtin.apt: + name: "{{ zeek_packages }}" + state: present + +- name: Add Zeek to PATH + ansible.builtin.lineinfile: + path: /etc/environment + regexp: 'PATH=' + line: 'PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/zeek/bin"' + +- name: Configure ZeekControl node.cfg + ansible.builtin.template: + src: node.cfg.j2 + dest: /opt/zeek/etc/node.cfg + owner: root + group: root + mode: '0644' + +- name: Enable JSON log format in local.zeek + ansible.builtin.lineinfile: + path: /opt/zeek/share/zeek/site/local.zeek + line: "@load policy/tuning/json-logs" + state: present + when: zeek_json_logs + +- name: Load additional detection scripts in local.zeek + ansible.builtin.blockinfile: + path: /opt/zeek/share/zeek/site/local.zeek + marker: "# {mark} GOAD purple team additions" + block: | + @load policy/protocols/smb + @load policy/protocols/dce-rpc + @load policy/protocols/kerberos + @load policy/protocols/rdp + @load policy/protocols/ldap + @load policy/frameworks/notice/weird-report-summary + +- name: Create log directory + ansible.builtin.file: + path: "{{ zeek_log_dir }}" + state: directory + owner: root + group: root + mode: '0755' + +- name: Check if Zeek is already deployed + ansible.builtin.stat: + path: /opt/zeek/spool/zeek/.pid + register: zeek_pid + +- name: Deploy Zeek (zeekctl deploy) + ansible.builtin.shell: /opt/zeek/bin/zeekctl deploy + when: not zeek_pid.stat.exists + register: zeek_deploy + failed_when: zeek_deploy.rc != 0 and 'already running' not in zeek_deploy.stderr + +- name: Install zeek cron for log rotation and health check + ansible.builtin.cron: + name: zeekctl cron + minute: "*/5" + job: "/opt/zeek/bin/zeekctl cron" + state: present + +- name: Create zeek systemd service + ansible.builtin.copy: + dest: /etc/systemd/system/zeek.service + content: | + [Unit] + Description=Zeek Network Security Monitor + After=network.target + + [Service] + Type=forking + ExecStart=/opt/zeek/bin/zeekctl start + ExecStop=/opt/zeek/bin/zeekctl stop + ExecReload=/opt/zeek/bin/zeekctl restart + RemainAfterExit=yes + + [Install] + WantedBy=multi-user.target + owner: root + group: root + mode: '0644' + +- name: Enable Zeek service + ansible.builtin.systemd: + name: zeek + enabled: yes + daemon_reload: yes + +- name: Display Zeek info + ansible.builtin.debug: + msg: + - "Zeek installed and monitoring interface: {{ zeek_monitor_interface }}" + - "Logs location: /opt/zeek/logs/current/" + - "Run 'zeekctl status' to check health" diff --git a/extensions/zeek/ansible/roles/zeek/templates/node.cfg.j2 b/extensions/zeek/ansible/roles/zeek/templates/node.cfg.j2 new file mode 100755 index 00000000..a5073ffb --- /dev/null +++ b/extensions/zeek/ansible/roles/zeek/templates/node.cfg.j2 @@ -0,0 +1,7 @@ +# Zeek node configuration - generated by GOAD +# https://docs.zeek.org/en/master/quickstart.html + +[zeek] +type=standalone +host=localhost +interface={{ zeek_monitor_interface }} diff --git a/extensions/zeek/extension.json b/extensions/zeek/extension.json new file mode 100755 index 00000000..e4733857 --- /dev/null +++ b/extensions/zeek/extension.json @@ -0,0 +1,11 @@ +{ + "name": "zeek", + "description": "Add a Zeek network security monitor to the lab", + "machines": [ + "zeek" + ], + "compatibility": [ + "*" + ], + "impact": "add a linux machine running Zeek that passively monitors all lab network traffic" +} diff --git a/extensions/zeek/inventory b/extensions/zeek/inventory new file mode 100755 index 00000000..20b423c5 --- /dev/null +++ b/extensions/zeek/inventory @@ -0,0 +1,9 @@ +; EXTENSION : ZEEK ------------------------------------------ +[default] +zeek ansible_host={{ip_range}}.53 ansible_connection=ssh ansible_ssh_common_args='-o StrictHostKeyChecking=no' + +[extensions] +zeek + +[zeek_server] +zeek diff --git a/extensions/zeek/providers/aws/linux.tf b/extensions/zeek/providers/aws/linux.tf new file mode 100755 index 00000000..6681a05e --- /dev/null +++ b/extensions/zeek/providers/aws/linux.tf @@ -0,0 +1,9 @@ +"zeek" = { + name = "zeek" + linux_sku = "22_04-lts-gen2" + linux_version = "latest" + ami = "ami-00c71bd4d220aa22a" + private_ip_address = "{{ip_range}}.53" + password = "Ze3k@GOAD2024!" + size = "t2.small" # 2cpu / 2GB +} diff --git a/extensions/zeek/providers/azure/linux.tf b/extensions/zeek/providers/azure/linux.tf new file mode 100755 index 00000000..5cb684ef --- /dev/null +++ b/extensions/zeek/providers/azure/linux.tf @@ -0,0 +1,9 @@ +"zeek" = { + name = "zeek" + linux_sku = "22_04-lts-gen2" + linux_version = "latest" + ami = "" + private_ip_address = "{{ip_range}}.53" + password = "Ze3k@GOAD2024!" + size = "Standard_B2s" # 2cpu / 4GB +} diff --git a/extensions/zeek/providers/ludus/config.yml b/extensions/zeek/providers/ludus/config.yml new file mode 100755 index 00000000..3bb3736b --- /dev/null +++ b/extensions/zeek/providers/ludus/config.yml @@ -0,0 +1,8 @@ + - vm_name: "{{ range_id }}-ZEEK" + hostname: "{{ range_id }}-ZEEK" + template: ubuntu-22.04-x64-server-template + vlan: 10 + ip_last_octet: 53 + ram_gb: 2 + cpus: 2 + linux: true diff --git a/extensions/zeek/providers/virtualbox/Vagrantfile b/extensions/zeek/providers/virtualbox/Vagrantfile new file mode 100755 index 00000000..6997f779 --- /dev/null +++ b/extensions/zeek/providers/virtualbox/Vagrantfile @@ -0,0 +1,10 @@ +boxes.append( + { :name => "{{lab_name}}-ZEEK", + :ip => "{{ip_range}}.53", + :box => "bento/ubuntu-22.04", + :os => "linux", + :cpus => 2, + :mem => 2048, + :forwarded_port => [ {:guest => 22, :host => 2211, :id => "ssh"} ] + } +) diff --git a/extensions/zeek/providers/vmware/Vagrantfile b/extensions/zeek/providers/vmware/Vagrantfile new file mode 100755 index 00000000..6997f779 --- /dev/null +++ b/extensions/zeek/providers/vmware/Vagrantfile @@ -0,0 +1,10 @@ +boxes.append( + { :name => "{{lab_name}}-ZEEK", + :ip => "{{ip_range}}.53", + :box => "bento/ubuntu-22.04", + :os => "linux", + :cpus => 2, + :mem => 2048, + :forwarded_port => [ {:guest => 22, :host => 2211, :id => "ssh"} ] + } +)