diff --git a/ESXi/ansible/roles/logger/tasks/main.yml b/ESXi/ansible/roles/logger/tasks/main.yml index e141330..0650158 100644 --- a/ESXi/ansible/roles/logger/tasks/main.yml +++ b/ESXi/ansible/roles/logger/tasks/main.yml @@ -217,7 +217,7 @@ /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/punchcard-custom-visualization_130.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/sankey-diagram-custom-visualization_130.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/link-analysis-app-for-splunk_161.tgz -auth 'admin:changeme' - /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/threathunting_143.tgz -auth 'admin:changeme' + /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/threathunting_144.tgz -auth 'admin:changeme' ## Fix a bug with the ThreatHunting App (https://github.com/olafhartong/ThreatHunting/pull/57) mv /opt/splunk/etc/apps/ThreatHunting/lookups/sysmonevencodes.csv /opt/splunk/etc/apps/ThreatHunting/lookups/sysmoneventcodes.csv @@ -404,7 +404,9 @@ LATEST_VELOCIRAPTOR_LINUX_URL=$(curl -sL https://github.com/Velocidex/velociraptor/releases/latest | grep 'linux-amd64' | grep -Eo "/(?[^\"]+)" | grep amd | sed 's#^#https://github.com#g') echo "[$(date +%H:%M:%S)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL" echo "[$(date +%H:%M:%S)]: Attempting to download..." - wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL" + #wget -P /opt/velociraptor --progress=bar:force "$LATEST_VELOCIRAPTOR_LINUX_URL" + # Harcoding until the release after v0.4.7 + wget -P /opt/velociraptor --progress=bar:force "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-linux-amd64" if [ "$(file /opt/velociraptor/velociraptor*linux-amd64 | grep -c 'ELF 64-bit LSB executable')" -eq 1 ]; then echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!" else diff --git a/Vagrant/bootstrap.sh b/Vagrant/bootstrap.sh index 9366a2d..681331a 100644 --- a/Vagrant/bootstrap.sh +++ b/Vagrant/bootstrap.sh @@ -163,7 +163,7 @@ install_splunk() { /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/punchcard-custom-visualization_130.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/sankey-diagram-custom-visualization_130.tgz -auth 'admin:changeme' /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/link-analysis-app-for-splunk_161.tgz -auth 'admin:changeme' - /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/threathunting_143.tgz -auth 'admin:changeme' + /opt/splunk/bin/splunk install app /vagrant/resources/splunk_server/threathunting_144.tgz -auth 'admin:changeme' ## Fix a bug with the ThreatHunting App (https://github.com/olafhartong/ThreatHunting/pull/57) mv /opt/splunk/etc/apps/ThreatHunting/lookups/sysmonevencodes.csv /opt/splunk/etc/apps/ThreatHunting/lookups/sysmoneventcodes.csv diff --git a/Vagrant/resources/splunk_forwarder/wef_inputs.conf b/Vagrant/resources/splunk_forwarder/wef_inputs.conf index 7690af9..0b6c195 100755 --- a/Vagrant/resources/splunk_forwarder/wef_inputs.conf +++ b/Vagrant/resources/splunk_forwarder/wef_inputs.conf @@ -323,7 +323,7 @@ current_only = 0 checkpointInterval = 5 [WinEventLog://WEC6-Sysmon] -sourcetype = "XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" +sourcetype = XmlWinEventLog:Microsoft-Windows-Sysmon/Operational source = WinEventLog:Sysmon index=sysmon disabled = 0 diff --git a/Vagrant/resources/splunk_server/threathunting_143.tgz b/Vagrant/resources/splunk_server/threathunting_143.tgz deleted file mode 100644 index 304e163..0000000 Binary files a/Vagrant/resources/splunk_server/threathunting_143.tgz and /dev/null differ diff --git a/Vagrant/resources/splunk_server/threathunting_144.tgz b/Vagrant/resources/splunk_server/threathunting_144.tgz new file mode 100644 index 0000000..c2035c0 Binary files /dev/null and b/Vagrant/resources/splunk_server/threathunting_144.tgz differ diff --git a/Vagrant/scripts/configure-AuditingPolicyGPOs.ps1 b/Vagrant/scripts/configure-AuditingPolicyGPOs.ps1 index fa0ac69..e3254d5 100644 --- a/Vagrant/scripts/configure-AuditingPolicyGPOs.ps1 +++ b/Vagrant/scripts/configure-AuditingPolicyGPOs.ps1 @@ -2,7 +2,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Configuring auditing policy GPOs..." $GPOName = 'Domain Controllers Enhanced Auditing Policy' $OU = "ou=Domain Controllers,dc=windomain,dc=local" -Write-Host "Importing $GPOName..." +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Importing $GPOName..." Import-GPO -BackupGpoName $GPOName -Path "c:\vagrant\resources\GPO\Domain_Controllers_Enhanced_Auditing_Policy" -TargetName $GPOName -CreateIfNeeded $gpLinks = $null $gPLinks = Get-ADOrganizationalUnit -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions @@ -13,7 +13,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $GPOName = 'Servers Enhanced Auditing Policy' $OU = "ou=Servers,dc=windomain,dc=local" @@ -28,7 +28,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $GPOName = 'Workstations Enhanced Auditing Policy' @@ -44,5 +44,5 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } diff --git a/Vagrant/scripts/configure-disable-windows-defender-gpo.ps1 b/Vagrant/scripts/configure-disable-windows-defender-gpo.ps1 index bcd8348..fd5cf84 100644 --- a/Vagrant/scripts/configure-disable-windows-defender-gpo.ps1 +++ b/Vagrant/scripts/configure-disable-windows-defender-gpo.ps1 @@ -12,7 +12,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Disable Windows Defender GPO was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disable Windows Defender GPO was already linked at $OU. Moving On." } $OU = "ou=Servers,dc=windomain,dc=local" $gPLinks = $null @@ -24,6 +24,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Disable Windows Defender GPO was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disable Windows Defender GPO was already linked at $OU. Moving On." } gpupdate /force diff --git a/Vagrant/scripts/configure-ou.ps1 b/Vagrant/scripts/configure-ou.ps1 index 6d6f869..41a1c12 100644 --- a/Vagrant/scripts/configure-ou.ps1 +++ b/Vagrant/scripts/configure-ou.ps1 @@ -10,7 +10,7 @@ while ($servers_ou_created -ne 1) { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Server OU..." try { Get-ADOrganizationalUnit -Identity 'OU=Servers,DC=windomain,DC=local' | Out-Null - Write-Host "Servers OU already exists. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Servers OU already exists. Moving On." $servers_ou_created = 1 } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { @@ -19,11 +19,11 @@ while ($servers_ou_created -ne 1) { $servers_ou_created = 1 } catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { - Write-Host "Unable to reach Active Directory. Sleeping for 5 and trying again..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Unable to reach Active Directory. Sleeping for 5 and trying again..." Start-Sleep 5 } catch { - Write-Host "Something went wrong attempting to reach AD or create the OU." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong attempting to reach AD or create the OU." } } @@ -33,7 +33,7 @@ while ($workstations_ou_created -ne 1) { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Workstations OU..." try { Get-ADOrganizationalUnit -Identity 'OU=Workstations,DC=windomain,DC=local' | Out-Null - Write-Host "Workstations OU already exists. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Workstations OU already exists. Moving On." $workstations_ou_created = 1 } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { @@ -42,11 +42,11 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Workstations OU..." $workstations_ou_created = 1 } catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { - Write-Host "Unable to reach Active Directory. Sleeping for 5 and trying again..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Unable to reach Active Directory. Sleeping for 5 and trying again..." Start-Sleep 5 } catch { - Write-Host "Something went wrong attempting to reach AD or create the OU." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong attempting to reach AD or create the OU." } } diff --git a/Vagrant/scripts/configure-powershelllogging.ps1 b/Vagrant/scripts/configure-powershelllogging.ps1 index f4a47d2..ed7580e 100755 --- a/Vagrant/scripts/configure-powershelllogging.ps1 +++ b/Vagrant/scripts/configure-powershelllogging.ps1 @@ -11,7 +11,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Powershell Logging was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Powershell Logging was already linked at $OU. Moving On." } $OU = "ou=Servers,dc=windomain,dc=local" $gPLinks = $null @@ -23,7 +23,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Powershell Logging was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Powershell Logging was already linked at $OU. Moving On." } $OU = "ou=Domain Controllers,dc=windomain,dc=local" $gPLinks = $null @@ -34,6 +34,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Powershell Logging was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Powershell Logging was already linked at $OU. Moving On." } gpupdate /force diff --git a/Vagrant/scripts/configure-rdp-user-gpo.ps1 b/Vagrant/scripts/configure-rdp-user-gpo.ps1 index bb28168..1fbea02 100644 --- a/Vagrant/scripts/configure-rdp-user-gpo.ps1 +++ b/Vagrant/scripts/configure-rdp-user-gpo.ps1 @@ -12,7 +12,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Allow Domain Users RDP GPO was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Allow Domain Users RDP GPO was already linked at $OU. Moving On." } $OU = "ou=Servers,dc=windomain,dc=local" $gPLinks = $null @@ -24,6 +24,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "Allow Domain Users RDP GPO was already linked at $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Allow Domain Users RDP GPO was already linked at $OU. Moving On." } gpupdate /force diff --git a/Vagrant/scripts/configure-wef-gpo.ps1 b/Vagrant/scripts/configure-wef-gpo.ps1 index f7d1486..72ac12a 100644 --- a/Vagrant/scripts/configure-wef-gpo.ps1 +++ b/Vagrant/scripts/configure-wef-gpo.ps1 @@ -11,7 +11,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) { New-GPLink -Name $GPOName -Target $OU -Enforced yes } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $OU = "ou=Domain Controllers,dc=windomain,dc=local" $gpLinks = $null @@ -21,7 +21,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) { New-GPLink -Name $GPOName -Target $OU -Enforced yes } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $OU = "ou=Workstations,dc=windomain,dc=local" $gpLinks = $null @@ -31,7 +31,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) { New-GPLink -Name $GPOName -Target $OU -Enforced yes } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Importing the GPO to modify ACLs on Custom Event Channels" @@ -48,7 +48,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $OU = "ou=Domain Controllers,dc=windomain,dc=local" $gPLinks = Get-ADOrganizationalUnit -Server "dc.windomain.local" -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions @@ -59,7 +59,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } $OU = "ou=Workstations,dc=windomain,dc=local" $gPLinks = Get-ADOrganizationalUnit -Server "dc.windomain.local" -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions @@ -70,7 +70,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) } else { - Write-Host "GpLink $GPOName already linked on $OU. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) GpLink $GPOName already linked on $OU. Moving On." } gpupdate /force diff --git a/Vagrant/scripts/create-domain.ps1 b/Vagrant/scripts/create-domain.ps1 index 01220c7..7256732 100644 --- a/Vagrant/scripts/create-domain.ps1 +++ b/Vagrant/scripts/create-domain.ps1 @@ -63,24 +63,29 @@ if ((gwmi win32_computersystem).partofdomain -eq $false) { dnscmd /ResetListenAddresses $dnslistenip $nics=Get-WmiObject "Win32_NetworkAdapterConfiguration where IPEnabled='TRUE'" |? { $_.IPAddress[0] -ilike "10.*" } - foreach($nic in $nics) - { + foreach($nic in $nics) { $nic.DomainDNSRegistrationEnabled = $false $nic.SetDynamicDNSRegistration($false) |Out-Null - } - - - #Get-DnsServerResourceRecord -ZoneName $domain -type 1 -Name "@" |Select-Object HostName,RecordType -ExpandProperty RecordData |Where-Object {$_.IPv4Address -ilike "10.*"}|Remove-DnsServerResourceRecord - $RRs= Get-DnsServerResourceRecord -ZoneName $domain -type 1 -Name "@" - - foreach($RR in $RRs) - { - if ( (Select-Object -InputObject $RR HostName,RecordType -ExpandProperty RecordData).IPv4Address -ilike "10.*") - { - Remove-DnsServerResourceRecord -ZoneName $domain -RRType A -Name "@" -RecordData $RR.RecordData.IPv4Address -Confirm } - } + $RRs= Get-DnsServerResourceRecord -ZoneName $domain -type 1 -Name "@" + foreach($RR in $RRs) { + if ( (Select-Object -InputObject $RR HostName,RecordType -ExpandProperty RecordData).IPv4Address -ilike "10.*") { + Remove-DnsServerResourceRecord -ZoneName $domain -RRType A -Name "@" -RecordData $RR.RecordData.IPv4Address -Confirm + } + } Restart-Service DNS - +} + +# Uninstall Windows Defender +If ((Get-Service -Name WinDefend -ErrorAction SilentlyContinue).status -eq 'Running') { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Uninstalling Windows Defender..." + Try { + Uninstall-WindowsFeature Windows-Defender -ErrorAction Stop + Uninstall-WindowsFeature Windows-Defender-Features -ErrorAction Stop + } + Catch { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender did not uninstall successfully..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) We'll try again during install-red-team.ps1" + } } diff --git a/Vagrant/scripts/download_palantir_wef.ps1 b/Vagrant/scripts/download_palantir_wef.ps1 index a5a3c3c..3744cf2 100644 --- a/Vagrant/scripts/download_palantir_wef.ps1 +++ b/Vagrant/scripts/download_palantir_wef.ps1 @@ -13,6 +13,6 @@ If (-not (Test-Path $wefRepoPath)) } else { - Write-Host "$wefRepoPath already exists. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) $wefRepoPath already exists. Moving On." } Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Palantir WEF download complete!" diff --git a/Vagrant/scripts/fix-second-network.ps1 b/Vagrant/scripts/fix-second-network.ps1 index d38f7fe..1fa0854 100755 --- a/Vagrant/scripts/fix-second-network.ps1 +++ b/Vagrant/scripts/fix-second-network.ps1 @@ -2,31 +2,29 @@ param ([String] $ip, [String] $dns, [String] $gateway) if ( (Get-NetAdapter | Select-Object -First 1 | Select-Object -ExpandProperty InterfaceDescription).Contains('Red Hat VirtIO')) { - Write-Host "Setting Network Configuration for LibVirt interface" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Setting Network Configuration for LibVirt interface" $subnet = $ip -replace "\.\d+$", "" $name = (Get-NetIPAddress -AddressFamily IPv4 ` | Where-Object -FilterScript { ($_.IPAddress).StartsWith("$subnet") } ` ).InterfaceAlias if ($name) { - Write-Host "Set IP address to $ip of interface $name" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Set IP address to $ip of interface $name" & netsh.exe int ip set address "$name" static $ip 255.255.255.0 "$gateway" if ($dns) { - Write-Host "Set DNS server address to $dns of interface $name" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Set DNS server address to $dns of interface $name" & netsh.exe interface ipv4 add dnsserver "$name" address=$dns index=1 } } else { Write-Error "Could not find a interface with subnet $subnet.xx" } - exit 0 } if (! (Test-Path 'C:\Program Files\VMware\VMware Tools') ) { - Write-Host "Nothing to do for other providers than VMware." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Nothing to do for other providers than VMware." exit 0 } - Write-Host "$('[{0:HH:mm}]' -f (Get-Date))" Write-Host "Setting IP address and DNS information for the Ethernet1 interface" Write-Host "If this step times out, it's because vagrant is connecting to the VM on the wrong interface" @@ -42,12 +40,12 @@ if (!$name) { ).InterfaceAlias } if ($name) { - Write-Host "Set IP address to $ip of interface $name" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Set IP address to $ip of interface $name" & netsh.exe int ip set address "$name" static $ip 255.255.255.0 "$subnet.1" if ($dns) { - Write-Host "Set DNS server address to $dns of interface $name" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Set DNS server address to $dns of interface $name" & netsh.exe interface ipv4 add dnsserver "$name" address=$dns index=1 } } else { - Write-Error "Could not find a interface with subnet $subnet.xx" + Write-Error "$('[{0:HH:mm}]' -f (Get-Date)) Could not find a interface with subnet $subnet.xx" } diff --git a/Vagrant/scripts/fix-windows-expiration.ps1 b/Vagrant/scripts/fix-windows-expiration.ps1 index f5247b2..7810d40 100644 --- a/Vagrant/scripts/fix-windows-expiration.ps1 +++ b/Vagrant/scripts/fix-windows-expiration.ps1 @@ -20,7 +20,7 @@ Elseif ($regex.Matches.Value -eq "0xC004FC07") { Try { cscript c:\windows\system32\slmgr.vbs /rearm } Catch { - Write-Host "Something went wrong trying to re-arm the image..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong trying to re-arm the image..." } } @@ -48,7 +48,7 @@ If ($days_left -as [int] -lt 30) { Try { cscript c:\windows\system32\slmgr.vbs /rearm } Catch { - Write-Host "Something went wrong trying to re-arm the image..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong trying to re-arm the image..." } } } diff --git a/Vagrant/scripts/install-autorunstowineventlog.ps1 b/Vagrant/scripts/install-autorunstowineventlog.ps1 index fd36469..e11d332 100644 --- a/Vagrant/scripts/install-autorunstowineventlog.ps1 +++ b/Vagrant/scripts/install-autorunstowineventlog.ps1 @@ -4,7 +4,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing AutorunsToWinEventLog..." If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) { . c:\Users\vagrant\AppData\Local\Temp\windows-event-forwarding-master\AutorunsToWinEventLog\Install.ps1 - Write-Host "AutorunsToWinEventLog installed. Starting the scheduled task. Future runs will begin at 11am" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) AutorunsToWinEventLog installed. Starting the scheduled task. Future runs will begin at 11am" Start-ScheduledTask -TaskName "AutorunsToWinEventLog" # https://mcpmag.com/articles/2018/03/16/wait-action-function-powershell.aspx # Wait 30 seconds for the scheduled task to enter the "Running" state @@ -12,7 +12,7 @@ If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) $timer = [Diagnostics.Stopwatch]::StartNew() while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog").State -ne "Running")) { Start-Sleep -Seconds 3 - Write-Host "Still waiting for scheduled task to start after "$timer.Elapsed.Seconds" seconds..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Still waiting for scheduled task to start after "$timer.Elapsed.Seconds" seconds..." } $timer.Stop() $Tsk = Get-ScheduledTask -TaskName "AutorunsToWinEventLog" @@ -23,5 +23,5 @@ If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) } else { - Write-Host "AutorunsToWinEventLog already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) AutorunsToWinEventLog already installed. Moving On." } diff --git a/Vagrant/scripts/install-choco-extras.ps1 b/Vagrant/scripts/install-choco-extras.ps1 index cbc14fe..4912c21 100644 --- a/Vagrant/scripts/install-choco-extras.ps1 +++ b/Vagrant/scripts/install-choco-extras.ps1 @@ -3,13 +3,13 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing additional Choco packages..." If (-not (Test-Path "C:\ProgramData\chocolatey")) { - Write-Host "Installing Chocolatey" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Chocolatey" iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) } else { - Write-Host "Chocolatey is already installed." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Chocolatey is already installed." } -Write-Host "Installing Chocolatey extras..." +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Chocolatey extras..." choco install -y --limit-output --no-progress wireshark winpcap Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Choco addons complete!" diff --git a/Vagrant/scripts/install-inputsconf.ps1 b/Vagrant/scripts/install-inputsconf.ps1 index b061168..cb82144 100755 --- a/Vagrant/scripts/install-inputsconf.ps1 +++ b/Vagrant/scripts/install-inputsconf.ps1 @@ -1,6 +1,6 @@ -# Purpose: Configures the inputs.conf for the Splunk forwarders on the Windows hosts +# Purpose: Configures the inputs.conf for the Splunk forwarder on WEF to send events from the WEF channels -Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Setting up Splunk Inputs for Sysmon & osquery" +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Setting up Splunk Inputs for Sysmon" $inputsPath = "C:\Program Files\SplunkUniversalForwarder\etc\apps\SplunkUniversalForwarder\local\inputs.conf" $currentContent = get-content $inputsPath @@ -28,7 +28,7 @@ if ($currentContent -ne $targetContent) } else { - Write-Host "Splunk forwarder already configured. Moving on." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Splunk forwarder already configured. Moving on." } If ((Get-Service -name splunkforwarder).Status -ne "Running") { diff --git a/Vagrant/scripts/install-microsoft-ata.ps1 b/Vagrant/scripts/install-microsoft-ata.ps1 index 372ee4e..022fb15 100644 --- a/Vagrant/scripts/install-microsoft-ata.ps1 +++ b/Vagrant/scripts/install-microsoft-ata.ps1 @@ -61,7 +61,7 @@ If (-not (Test-Path "C:\Program Files\Microsoft Advanced Threat Analytics\Center } $Mount = Mount-DiskImage -ImagePath "$env:temp\$title.iso" -StorageType ISO -Access ReadOnly -PassThru $Volume = $Mount | Get-Volume - Write-Host "Installing $title" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing $title" $Install = Start-Process -Wait -FilePath ($Volume.DriveLetter + ":\Microsoft ATA Center Setup.exe") -ArgumentList "/q --LicenseAccepted NetFrameworkCommandLineArguments=`"/q`" --EnableMicrosoftUpdate" -PassThru $Install $Mount | Dismount-DiskImage -Confirm:$false diff --git a/Vagrant/scripts/install-osquery.ps1 b/Vagrant/scripts/install-osquery.ps1 index e151c81..fcf7cfe 100755 --- a/Vagrant/scripts/install-osquery.ps1 +++ b/Vagrant/scripts/install-osquery.ps1 @@ -5,7 +5,7 @@ $flagfile = "c:\Program Files\osquery\osquery.flags" choco install -y --limit-output --no-progress osquery | Out-String # Apparently Out-String makes the process wait $service = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'" If (-not ($service)) { - Write-Host "Setting osquery to run as a service" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Setting osquery to run as a service" New-Service -Name "osqueryd" -BinaryPathName "C:\Program Files\osquery\osqueryd\osqueryd.exe --flagfile=`"C:\Program Files\osquery\osquery.flags`"" # Download the flags file from the Palantir osquery-configuration Github @@ -38,7 +38,7 @@ If (-not ($service)) { Start-Service osqueryd } else { - Write-Host "osquery is already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) osquery is already installed. Moving On." } If ((Get-Service -name osqueryd).Status -ne "Running") { diff --git a/Vagrant/scripts/install-redteam.ps1 b/Vagrant/scripts/install-redteam.ps1 index ed3865d..b5df981 100644 --- a/Vagrant/scripts/install-redteam.ps1 +++ b/Vagrant/scripts/install-redteam.ps1 @@ -11,13 +11,22 @@ If ($hostname -eq "win10") { Set-MpPreference -DisableRealtimeMonitoring $true } -# Windows Defender should be disabled already by the GPO, sometimes it doesnt work +# Windows Defender should be disabled by the GPO or uninstalled already, but we'll keep this just in case If ($hostname -ne "win10" -And (Get-Service -Name WinDefend -ErrorAction SilentlyContinue).status -eq 'Running') { # Uninstalling Windows Defender (https://github.com/StefanScherer/packer-windows/issues/201) - Uninstall-WindowsFeature Windows-Defender - Uninstall-WindowsFeature Windows-Defender-Features + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Uninstalling Windows Defender..." + Try { + Uninstall-WindowsFeature Windows-Defender -ErrorAction Stop + Uninstall-WindowsFeature Windows-Defender-Features -ErrorAction Stop + } + Catch { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender did not uninstall successfully..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) We'll try again during install-red-team.ps1" + } +} +Else { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender has already been disabled or uninstalled." } - # Purpose: Downloads and unzips a copy of the latest Mimikatz trunk Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Mimikatz..." # GitHub requires TLS 1.2 as of 2/27 @@ -30,7 +39,7 @@ if (-not (Test-Path $mimikatzRepoPath)) { Expand-Archive -path "$mimikatzRepoPath" -destinationpath 'c:\Tools\Mimikatz' -Force } else { - Write-Host "Mimikatz was already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Mimikatz was already installed. Moving On." } # Download and unzip a copy of PowerSploit @@ -45,7 +54,7 @@ if (-not (Test-Path $powersploitRepoPath)) { Copy-Item "c:\Tools\PowerSploit\PowerSploit-dev\*" "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" -Recurse -Force } else { - Write-Host "PowerSploit was already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) PowerSploit was already installed. Moving On." } # Download and unzip a copy of Atomic Red Team @@ -59,7 +68,7 @@ if (-not (Test-Path $atomicRedTeamRepoPath)) { Expand-Archive -path "$atomicRedTeamRepoPath" -destinationpath 'c:\Tools\Atomic Red Team' -Force } else { - Write-Host "Atomic Red Team was already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Atomic Red Team was already installed. Moving On." } # Download and unzip a copy of BadBlood @@ -76,7 +85,7 @@ if (-not (Test-Path $badbloodRepoPath)) { ((Get-Content -path $invokeBadBloodPath -Raw) -replace '1000..5000','500..1500') | Set-Content -Path $invokeBadBloodPath } else { - Write-Host "BadBlood was already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) BadBlood was already installed. Moving On." } Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!" diff --git a/Vagrant/scripts/install-splunkuf.ps1 b/Vagrant/scripts/install-splunkuf.ps1 index 0e76820..ed9f15f 100755 --- a/Vagrant/scripts/install-splunkuf.ps1 +++ b/Vagrant/scripts/install-splunkuf.ps1 @@ -1,7 +1,7 @@ # Purpose: Installs a Splunk Universal Forwader on the host If (-not (Test-Path "C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe")) { - Write-Host "Downloading Splunk Universal Forwarder" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading Splunk Universal Forwarder..." $msiFile = $env:Temp + "\splunkforwarder-7.1.0-2e75b3406c5b-x64-release.msi" Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing & Starting Splunk" @@ -9,7 +9,7 @@ If (-not (Test-Path "C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe")) (New-Object System.Net.WebClient).DownloadFile('https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=windows&version=7.1.0&product=universalforwarder&filename=splunkforwarder-7.1.0-2e75b3406c5b-x64-release.msi&wget=true', $msiFile) Start-Process -FilePath "c:\windows\system32\msiexec.exe" -ArgumentList '/i', "$msiFile", 'RECEIVING_INDEXER="192.168.38.105:9997" WINEVENTLOG_SEC_ENABLE=0 WINEVENTLOG_SYS_ENABLE=0 WINEVENTLOG_APP_ENABLE=0 AGREETOLICENSE=Yes SERVICESTARTTYPE=1 LAUNCHSPLUNK=1 SPLUNKPASSWORD=changeme /quiet' -Wait } Else { - Write-Host "Splunk is already installed. Moving on." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Splunk is already installed. Moving on." } If ((Get-Service -name splunkforwarder).Status -ne "Running") { diff --git a/Vagrant/scripts/install-sysinternals.ps1 b/Vagrant/scripts/install-sysinternals.ps1 index a761de1..79dab0f 100755 --- a/Vagrant/scripts/install-sysinternals.ps1 +++ b/Vagrant/scripts/install-sysinternals.ps1 @@ -1,4 +1,5 @@ # Purpose: Installs a handful of SysInternals tools on the host into c:\Tools\Sysinternals +# Also installs Sysmon and Olaf Harton's Sysmon config Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing SysInternals Tooling..." $sysinternalsDir = "C:\Tools\Sysinternals" @@ -6,14 +7,14 @@ $sysmonDir = "C:\ProgramData\Sysmon" If(!(test-path $sysinternalsDir)) { New-Item -ItemType Directory -Force -Path $sysinternalsDir } Else { - Write-Host "Tools directory exists. Exiting." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Tools directory exists, no need to re-install. Exiting." exit } If(!(test-path $sysmonDir)) { New-Item -ItemType Directory -Force -Path $sysmonDir } Else { - Write-Host "Sysmon directory exists. Exiting." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Sysmon directory exists, no need to re-install. Exiting." exit } diff --git a/Vagrant/scripts/install-utilities.ps1 b/Vagrant/scripts/install-utilities.ps1 index 930bf85..5859699 100755 --- a/Vagrant/scripts/install-utilities.ps1 +++ b/Vagrant/scripts/install-utilities.ps1 @@ -2,10 +2,10 @@ If (-not (Test-Path "C:\ProgramData\chocolatey")) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - Write-Host "Installing Chocolatey" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Chocolatey" iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) } else { - Write-Host "Chocolatey is already installed." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Chocolatey is already installed." } Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing utilities..." @@ -17,4 +17,4 @@ If ($(hostname) -eq "win10") { } choco install -y --limit-output --no-progress NotepadPlusPlus GoogleChrome WinRar -Write-Host "Utilties installation complete!" +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Utilties installation complete!" diff --git a/Vagrant/scripts/install-velociraptor.ps1 b/Vagrant/scripts/install-velociraptor.ps1 index 43a6740..22aca9c 100644 --- a/Vagrant/scripts/install-velociraptor.ps1 +++ b/Vagrant/scripts/install-velociraptor.ps1 @@ -27,7 +27,7 @@ If (-not (Test-Path $velociraptorLogFile)) { Restart-Service Velociraptor Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Velociraptor successfully installed!" } Else { - Write-Host "Velociraptor was already installed. Moving On." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Velociraptor was already installed. Moving On." } If ((Get-Service -name Velociraptor).Status -ne "Running") { diff --git a/Vagrant/scripts/install-wefsubscriptions.ps1 b/Vagrant/scripts/install-wefsubscriptions.ps1 index 7d74e2f..b56766b 100644 --- a/Vagrant/scripts/install-wefsubscriptions.ps1 +++ b/Vagrant/scripts/install-wefsubscriptions.ps1 @@ -11,7 +11,7 @@ if (-not (Test-Path "$env:windir\system32\CustomEventChannels.dll")) Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Custom Event Channels Manifest..." wevtutil im "c:\windows\system32\CustomEventChannels.man" - Write-Host "Resizing Channels to 4GB..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Resizing Channels to 4GB..." $xml = wevtutil el | select-string -pattern "WEC" foreach ($subscription in $xml) { wevtutil sl $subscription /ms:4294967296 } @@ -30,7 +30,7 @@ if (-not (Test-Path "$env:windir\system32\CustomEventChannels.dll")) } else { - Write-Host "WEF Subscriptions are already installed, moving on..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) WEF Subscriptions are already installed, moving on..." if ((Get-Service -Name wecsvc).Status -ne "Running") { net start wecsvc diff --git a/Vagrant/scripts/install-windows_ta.ps1 b/Vagrant/scripts/install-windows_ta.ps1 index baf74b9..ac1ca39 100755 --- a/Vagrant/scripts/install-windows_ta.ps1 +++ b/Vagrant/scripts/install-windows_ta.ps1 @@ -4,7 +4,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing the Windows TA for Splunk" If (test-path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\default") { - Write-Host "Windows TA is already installed. Moving on." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows TA is already installed. Moving on." Exit } @@ -24,6 +24,6 @@ start-sleep -s 15 If (test-path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\default") { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows TA installed successfully." } Else { - Write-Host "Something went wrong during installation." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong during installation." exit 1 } diff --git a/Vagrant/scripts/join-domain.ps1 b/Vagrant/scripts/join-domain.ps1 index 3e36631..30822b8 100755 --- a/Vagrant/scripts/join-domain.ps1 +++ b/Vagrant/scripts/join-domain.ps1 @@ -19,7 +19,7 @@ $DomainCred = New-Object System.Management.Automation.PSCredential $user, $pass If ($hostname -eq "wef") { Add-Computer -DomainName "windomain.local" -credential $DomainCred -OUPath "ou=Servers,dc=windomain,dc=local" -PassThru } ElseIf ($hostname -eq "win10") { - Write-Host "Adding Win10 to the domain. Sometimes this step times out. If that happens, just run 'vagrant reload win10 --provision'" #debug + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Adding Win10 to the domain. Sometimes this step times out. If that happens, just run 'vagrant reload win10 --provision'" #debug Add-Computer -DomainName "windomain.local" -credential $DomainCred -OUPath "ou=Workstations,dc=windomain,dc=local" } Else { Add-Computer -DomainName "windomain.local" -credential $DomainCred -PassThru @@ -30,8 +30,24 @@ Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" - Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value "vagrant" # Stop Windows Update -Write-Host "Disabling Windows Updates and Windows Module Services" +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disabling Windows Updates and Windows Module Services" Set-Service wuauserv -StartupType Disabled Stop-Service wuauserv Set-Service TrustedInstaller -StartupType Disabled Stop-Service TrustedInstaller + + + +# Uninstall Windows Defender from WEF +# This command isn't supported on WIN10 +If ($hostname -ne "win10" -And (Get-Service -Name WinDefend -ErrorAction SilentlyContinue).status -eq 'Running') { + # Uninstalling Windows Defender (https://github.com/StefanScherer/packer-windows/issues/201) + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Uninstalling Windows Defender..." + Try { + Uninstall-WindowsFeature Windows-Defender -ErrorAction Stop + Uninstall-WindowsFeature Windows-Defender-Features -ErrorAction Stop + } Catch { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows Defender did not uninstall successfully..." + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) We'll try again during install-red-team.ps1" + } +} \ No newline at end of file diff --git a/Vagrant/scripts/provision.ps1 b/Vagrant/scripts/provision.ps1 index c631b8b..db8a277 100644 --- a/Vagrant/scripts/provision.ps1 +++ b/Vagrant/scripts/provision.ps1 @@ -13,7 +13,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Checking if Windows evaluation is exp # Ping DetectionLab server for usage statistics curl -userAgent "DetectionLab-$box" "https://detectionlab.network/$box" -UseBasicParsing | out-null -Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disable IPv6 on all network adatpers..." +Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Disabling IPv6 on all network adatpers..." Get-NetAdapterBinding -ComponentID ms_tcpip6 | ForEach-Object {Disable-NetAdapterBinding -Name $_.Name -ComponentID ms_tcpip6} Get-NetAdapterBinding -ComponentID ms_tcpip6 # https://support.microsoft.com/en-gb/help/929852/guidance-for-configuring-ipv6-in-windows-for-advanced-users @@ -26,14 +26,12 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing bginfo..." . c:\vagrant\scripts\install-bginfo.ps1 - Write-Host -fore red 'Hint: vagrant reload' $box '--provision' - } elseif ((gwmi win32_computersystem).partofdomain -eq $false) { - Write-Host -fore red "$('[{0:HH:mm}]' -f (Get-Date)) Current domain is set to 'workgroup'. Time to join the domain!" + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Current domain is set to 'workgroup'. Time to join the domain!" if (!(Test-Path 'c:\Program Files\sysinternals\bginfo.exe')) { - Write-Host 'Install bginfo' + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing bginfo..." . c:\vagrant\scripts\install-bginfo.ps1 # Set background to be "fitted" instead of "tiled" Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name TileWallpaper -Value '0' @@ -48,13 +46,10 @@ if ($env:COMPUTERNAME -imatch 'vagrant') { . c:\vagrant\scripts\join-domain.ps1 } } else { - Write-Host -fore green "$('[{0:HH:mm}]' -f (Get-Date)) I am domain joined!" - if (!(Test-Path 'c:\Program Files\sysinternals\bginfo.exe')) { - Write-Host 'Installing bginfo...' + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing bginfo..." . c:\vagrant\scripts\install-bginfo.ps1 } - Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Provisioning after joining domain..." } diff --git a/ci/manual_machine_bootstrap_vmware.sh b/ci/manual_machine_bootstrap_vmware.sh index 741b87d..ed5ceec 100644 --- a/ci/manual_machine_bootstrap_vmware.sh +++ b/ci/manual_machine_bootstrap_vmware.sh @@ -10,7 +10,7 @@ sed -i 's#http://archive.ubuntu.com#http://us.archive.ubuntu.com#g' /etc/apt/sou # Install VMWare Workstation 15 apt-get update -apt-get install -y linux-headers-"$(uname -r)" build-essential unzip git ufw apache2 python-pip ubuntu-desktop python-pip +apt-get install -y linux-headers-"$(uname -r)" build-essential unzip git ufw apache2 python-pip ubuntu-desktop python-pip libxtst6 pip install awscli --upgrade --user cp /root/.local/bin/aws /usr/local/bin/aws && chmod +x /usr/local/bin/aws diff --git a/img/badblood.png b/img/badblood.png new file mode 100644 index 0000000..e96ae30 Binary files /dev/null and b/img/badblood.png differ