From bf502e85c9a2dc5ddda72a2504257a17af45dded Mon Sep 17 00:00:00 2001 From: Chris Long Date: Mon, 29 Mar 2021 20:45:43 -0700 Subject: [PATCH 1/2] More Exchange related code --- .../splunk_forwarder/exchange_inputs.conf | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Vagrant/resources/splunk_forwarder/exchange_inputs.conf diff --git a/Vagrant/resources/splunk_forwarder/exchange_inputs.conf b/Vagrant/resources/splunk_forwarder/exchange_inputs.conf new file mode 100644 index 000000000..30f2d2024 --- /dev/null +++ b/Vagrant/resources/splunk_forwarder/exchange_inputs.conf @@ -0,0 +1,23 @@ +[monitor://C:\Program Files\Microsoft\Exchange Server\V15\Logging\Ews] +whitelist=\.log$|\.LOG$ +sourcetype=MSWindows:2016EWS:IIS +queue=parsingQueue +index=msexchange +disabled=false +initCrcLength=8192 + +[monitor://C:\inetpub\logs\LogFiles\W3SVC1] +whitelist=\.log$|\.LOG$ +sourcetype=MSWindows:IIS +queue=parsingQueue +index=msexchange +disabled=false +initCrcLength=8192 + +[monitor://C:\inetpub\logs\LogFiles\W3SVC2] +whitelist=\.log$|\.LOG$ +sourcetype=MSWindows:IIS +queue=parsingQueue +index=msexchange +disabled=false +initCrcLength=8192 \ No newline at end of file From 553f9a13c51b23c40a31ca821c6b9fb74f8b1651 Mon Sep 17 00:00:00 2001 From: Chris Long Date: Mon, 29 Mar 2021 20:50:01 -0700 Subject: [PATCH 2/2] Adding more code for Exchange --- AWS/Terraform/main.tf | 36 +++++++++++ AWS/Terraform/variables.tf | 24 ++++++++ Azure/Ansible/inventory.yml | 12 ++-- Azure/build_ansible_inventory.sh | 6 ++ ESXi/ansible/roles/common/tasks/main.yml | 20 +++---- ESXi/ansible/roles/logger/tasks/main.yml | 1 + ESXi/outputs.tf | 4 +- Vagrant/Vagrantfile | 63 ++++++++++++++++++++ Vagrant/logger_bootstrap.sh | 1 + Vagrant/resources/guacamole/user-mapping.xml | 10 ++++ Vagrant/scripts/install-exchange.ps1 | 17 ++++-- ci/copy_to_s3.sh | 3 + 12 files changed, 170 insertions(+), 27 deletions(-) diff --git a/AWS/Terraform/main.tf b/AWS/Terraform/main.tf index db9b530f3..bbcc8cc6a 100644 --- a/AWS/Terraform/main.tf +++ b/AWS/Terraform/main.tf @@ -285,6 +285,42 @@ resource "aws_instance" "wef" { } } +resource "aws_instance" "exchange" { + instance_type = "t3.medium" + count = var.create_exchange_server ? 1 : 0 + + provisioner "remote-exec" { + inline = [ + "choco install -force -y winpcap", + "powershell.exe -c \"Add-Content 'c:\\windows\\system32\\drivers\\etc\\hosts' ' 192.168.38.102 dc.windomain.local'\"", + "powershell.exe -c \"Add-Content 'c:\\windows\\system32\\drivers\\etc\\hosts' ' 192.168.38.102 windomain.local'\"", + "ipconfig /renew", + ] + + connection { + type = "winrm" + user = "vagrant" + password = "vagrant" + host = coalesce(self.public_ip, self.private_ip) + } + } + + # Uses the local variable if external data source resolution fails + ami = coalesce(var.exchange_ami, data.aws_ami.exchange_ami.image_id) + + tags = merge(var.custom-tags, map( + "Name", "${var.instance_name_prefix}exchange.windomain.local" + )) + + subnet_id = aws_subnet.default.id + vpc_security_group_ids = [aws_security_group.windows.id] + private_ip = "192.168.38.106" + + root_block_device { + delete_on_termination = true + } +} + resource "aws_instance" "win10" { instance_type = "t2.medium" diff --git a/AWS/Terraform/variables.tf b/AWS/Terraform/variables.tf index 97ebde22b..c8f34e67e 100644 --- a/AWS/Terraform/variables.tf +++ b/AWS/Terraform/variables.tf @@ -88,6 +88,18 @@ data "aws_ami" "wef_ami" { } } +# Uncomment after this AMI has been created and uploaded to AWS +# # Use Data Sources to resolve the AMI-ID for the pre-built EXCHANGE host +# data "aws_ami" "exchange_ami" { +# owners = ["505638924199"] +# most_recent = true + +# filter { +# name = "name" +# values = ["detectionlab-exchange"] +# } +# } + # Use Data Sources to resolve the AMI-ID for the pre-built Win10 host data "aws_ami" "win10_ami" { owners = ["505638924199"] @@ -116,7 +128,19 @@ variable "wef_ami" { default = "" } +variable "exchange_ami" { + type = string + default = "" +} + variable "win10_ami" { type = string default = "" } + +# Set to "true" in terraform.tfvars if you want to add the Exchange server +variable "create_exchange_server" { + description = "If set to true, adds an additional host that installs exchange" + type = bool + default = false +} diff --git a/Azure/Ansible/inventory.yml b/Azure/Ansible/inventory.yml index a581d9082..9c70bf159 100644 --- a/Azure/Ansible/inventory.yml +++ b/Azure/Ansible/inventory.yml @@ -2,17 +2,17 @@ # Replace the x's with the IP addresses from "terrafrom output" dc: hosts: - 13.77.149.92: + x.x.x.x: wef: hosts: - 13.66.251.74: + y.y.y.y: win10: hosts: - 13.66.225.219: + z.z.z.z: -exchange: - hosts: - 52.183.7.185: +#exchange: +# hosts: +# w.w.w.w: diff --git a/Azure/build_ansible_inventory.sh b/Azure/build_ansible_inventory.sh index 081ed30ad..82640388b 100755 --- a/Azure/build_ansible_inventory.sh +++ b/Azure/build_ansible_inventory.sh @@ -23,6 +23,7 @@ TF_OUTPUT=$(terraform output) DC_IP=$(echo "$TF_OUTPUT" | grep -E -o "dc_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ') WEF_IP=$(echo "$TF_OUTPUT" | grep -E -o "wef_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ') +EXCHANGE_IP=$(echo "$TF_OUTPUT" | grep -E -o "exchange_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ') WIN10_IP=$(echo "$TF_OUTPUT" | grep -E -o "win10_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ') # Code needs to be added for exchange @@ -39,5 +40,10 @@ fi echo "Replacing the default values in DetectionLab/Azure/Ansible/inventory.yml..." sed -i.bak "s/x.x.x.x/$DC_IP/g; s/y.y.y.y/$WEF_IP/g; s/z.z.z.z/$WIN10_IP/g" ../Ansible/inventory.yml +if [ -z $EXCHANGE_IP ]; then + echo "Found Exchange IP address in Terraform output. Adding to inventory." + sed -i.bak "s/#exchange:/exchange:/g; s/# hosts:/ hosts:/g; s/# w.w.w.w:/ $EXCHANGE_IP/g" ../Ansible/inventory.yml +fi + echo "Displaying the updated inventory.yml below!" cat ../Ansible/inventory.yml diff --git a/ESXi/ansible/roles/common/tasks/main.yml b/ESXi/ansible/roles/common/tasks/main.yml index c9abed46b..dd911aed3 100644 --- a/ESXi/ansible/roles/common/tasks/main.yml +++ b/ESXi/ansible/roles/common/tasks/main.yml @@ -54,16 +54,10 @@ - debug: msg="{{ redteam.stdout_lines }}" -- name: Install Utilities - win_chocolatey: - name: - - NotepadPlusPlus - - GoogleChrome - - WinRar - - wireshark - - winpcap - state: present - ignore_checksums: yes - - - +- name: Install Utilities + win_shell: ".\\install-utilities.ps1" + args: + chdir: 'c:\vagrant\scripts' + register: utilities + failed_when: "'Exception' in utilities.stdout" + ignore_errors: true diff --git a/ESXi/ansible/roles/logger/tasks/main.yml b/ESXi/ansible/roles/logger/tasks/main.yml index 757b04063..fef3a479d 100644 --- a/ESXi/ansible/roles/logger/tasks/main.yml +++ b/ESXi/ansible/roles/logger/tasks/main.yml @@ -212,6 +212,7 @@ /opt/splunk/bin/splunk add index suricata -auth 'admin:changeme' /opt/splunk/bin/splunk add index threathunting -auth 'admin:changeme' /opt/splunk/bin/splunk add index evtx_attack_samples -auth 'admin:changeme' + /opt/splunk/bin/splunk add index msexchange -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_forwarder/splunk-add-on-for-microsoft-windows_700.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/splunk-add-on-for-microsoft-sysmon_1062.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/asn-lookup-generator_110.tgz -auth 'admin:changeme' diff --git a/ESXi/outputs.tf b/ESXi/outputs.tf index 4012c94db..1bdf393f0 100644 --- a/ESXi/outputs.tf +++ b/ESXi/outputs.tf @@ -23,11 +23,11 @@ output "wef_ips" { } output "exchange_interfaces" { - value = esxi_guest.exchange.network_interfaces + value = esxi_guest.exchange[0].network_interfaces } output "exchange_ips" { - value = esxi_guest.exchange.ip_address + value = "${var.create_exchange_server ? esxi_guest.exchange[0].ip_address : null}" } output "win10_interfaces" { diff --git a/Vagrant/Vagrantfile b/Vagrant/Vagrantfile index d7d646b07..d9bae33f1 100644 --- a/Vagrant/Vagrantfile +++ b/Vagrant/Vagrantfile @@ -1,3 +1,5 @@ +build_exchange = false + Vagrant.configure("2") do |config| config.vm.define "logger" do |cfg| @@ -180,6 +182,67 @@ Vagrant.configure("2") do |config| end end + if build_exchange + config.vm.define "exchange" do |cfg| + cfg.vm.box = "detectionlab/win2016" + cfg.vm.hostname = "exchange" + cfg.vm.boot_timeout = 600 + cfg.vm.communicator = "winrm" + cfg.winrm.basic_auth_only = true + cfg.winrm.timeout = 300 + cfg.winrm.retry_limit = 20 + cfg.vm.network :private_network, ip: "192.168.38.106", gateway: "192.168.38.1", dns: "192.168.38.102" + + cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: true, args: "-ip 192.168.38.106 -dns 8.8.8.8 -gateway 192.168.38.1" + cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false + cfg.vm.provision "reload" + cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/download_palantir_wef.ps1", privileged: false + cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: false + cfg.vm.provision "shell", path: "scripts/install-splunkuf.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-windows_ta.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-utilities.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-redteam.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-choco-extras.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-osquery.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-sysinternals.ps1", privileged: false + cfg.vm.provision "shell", path: "scripts/install-velociraptor.ps1", privileged: false + cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false + cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: false + + cfg.vm.provider "vmware_desktop" do |v, override| + v.vmx["displayname"] = "exchange.windomain.local" + v.memory = 8192 + v.cpus = 4 + v.gui = true + v.enable_vmrun_ip_lookup = false + end + + cfg.vm.provider "virtualbox" do |vb, override| + vb.gui = true + vb.name = "exchange.windomain.local" + vb.default_nic_type = "82545EM" + vb.customize ["modifyvm", :id, "--memory", 8192] + vb.customize ["modifyvm", :id, "--cpus", 4] + vb.customize ["modifyvm", :id, "--vram", "32"] + vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"] + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ] + end + + cfg.vm.provider "libvirt" do |lv, override| + lv.graphics_type = "spice" + lv.video_type = "qxl" + lv.input :type => "tablet", :bus => "usb" + override.vm.box = "../Boxes/windows_2016_libvirt.box" + lv.video_vram = 32768 + lv.memory = 8192 + lv.cpus = 4 + override.vm.synced_folder '.', '/', type: 'winrm' + end + end + end + config.vm.define "win10" do |cfg| cfg.vm.box = "detectionlab/win10" cfg.vm.hostname = "win10" diff --git a/Vagrant/logger_bootstrap.sh b/Vagrant/logger_bootstrap.sh index 694acac3e..fe425cb3c 100644 --- a/Vagrant/logger_bootstrap.sh +++ b/Vagrant/logger_bootstrap.sh @@ -160,6 +160,7 @@ install_splunk() { /opt/splunk/bin/splunk add index suricata -auth 'admin:changeme' /opt/splunk/bin/splunk add index threathunting -auth 'admin:changeme' /opt/splunk/bin/splunk add index evtx_attack_samples -auth 'admin:changeme' + /opt/splunk/bin/splunk add index msexchange -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_forwarder/splunk-add-on-for-microsoft-windows_700.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/splunk-add-on-for-microsoft-sysmon_1062.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/asn-lookup-generator_110.tgz -auth 'admin:changeme' diff --git a/Vagrant/resources/guacamole/user-mapping.xml b/Vagrant/resources/guacamole/user-mapping.xml index df7e54e63..6b42d4b87 100644 --- a/Vagrant/resources/guacamole/user-mapping.xml +++ b/Vagrant/resources/guacamole/user-mapping.xml @@ -18,6 +18,16 @@ true + + rdp + 192.168.38.106 + 3389 + vagrant + vagrant + nla + true + + rdp 192.168.38.104 diff --git a/Vagrant/scripts/install-exchange.ps1 b/Vagrant/scripts/install-exchange.ps1 index e0003f4ca..ba06ccd14 100644 --- a/Vagrant/scripts/install-exchange.ps1 +++ b/Vagrant/scripts/install-exchange.ps1 @@ -37,6 +37,12 @@ If ($physicalMemory -lt 8000000000) { } } +# Gotta temporarily re-enable these services +Set-Service TrustedInstaller -StartupType Automatic +Start-Service TrustedInstaller +Set-Service wuauserv -StartupType Automatic +Start-Service wuauserv + If (-not(Test-Path c:\exchange_prereqs_complete.txt)) { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Beginning installation of prerequisites..." # Install Prerequisites @@ -49,11 +55,6 @@ If (-not(Test-Path c:\exchange_prereqs_complete.txt)) { If ((Get-WindowsOptionalFeature -Online -FeatureName "RSAT-AD-Tools-Feature").State -ne "Enabled") { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing a bunch of items from Microsoft Optional Components..." - # Gotta temporarily re-enable these services - Set-Service TrustedInstaller -StartupType Automatic - Start-Service TrustedInstaller - Set-Service wuauserv -StartupType Automatic - Start-Service wuauserv Install-WindowsFeature ` NET-Framework-45-Features, RPC-over-HTTP-proxy, @@ -153,6 +154,10 @@ If (-not(Test-Path c:\exchange_prereqs_complete.txt)) { # Create a file so this script knows to skip pre-req installation upon next run. New-Item -Path "c:\exchange_prereqs_complete.txt" -ItemType "file" Write-Host "A reboot is required to continue installation of exchange." + Write-Host "Rebooting in 3 seconds..." + Start-Sleep -Seconds 3 + shutdown /r /t 1 + # $reboot = Read-Host "Would you like to reboot now? [y/n]" # If ($reboot -eq "y") { # Write-Host "Rebooting in 3 seconds..." @@ -200,7 +205,7 @@ If (-not (Test-Path "E:\Setup.EXE")) { <# If (Test-Path "E:\Setup.exe") { Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/PrepareSchema", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait - Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/PrepareAD", "/OrganizationName:`"Detection Lab`"", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait + Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/PrepareAD", "/OrganizationName: DetectionLab", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/Mode:Install", "/Role:Mailbox", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait } Else { diff --git a/ci/copy_to_s3.sh b/ci/copy_to_s3.sh index 611b8b88f..4d25014e9 100644 --- a/ci/copy_to_s3.sh +++ b/ci/copy_to_s3.sh @@ -9,6 +9,9 @@ aws configure set default.region us-west-1 export BUCKET_NAME="FILL_ME_IN" cd /opt/DetectionLab/Vagrant || exit 1 +echo "Clearing out Splunk indexes" +ssh -i /opt/DetectionLab/Vagrant/.vagrant/machines/logger/virtualbox/private_key vagrant@192.168.38.105 'sudo /opt/splunk/bin/splunk stop && sudo /opt/splunk/bin/splunk clean eventdata -f' + echo "Running WinRM Commands to open WinRM on the firewall..." for host in dc wef win10; do