Merge pull request #1 from clong/master
Update from original repository
This commit is contained in:
		| @@ -47,6 +47,21 @@ These commands can be run in parallel from three separate terminal sessions. | |||||||
|  |  | ||||||
| If you run into any issues along the way, please open an issue on Github and I'll do my best to find a solution. | If you run into any issues along the way, please open an issue on Github and I'll do my best to find a solution. | ||||||
|  |  | ||||||
|  | ## Configuring Windows 10 with WSL as a Provisioning Host | ||||||
|  |  | ||||||
|  | Note: Run the following commands as a root user or with sudo | ||||||
|  |  | ||||||
|  | 1. In Windows 10 install WSL (version 1 or 2) | ||||||
|  | 2. Install Ubuntu 18.04 app from the Microsoft Store | ||||||
|  | 3. Update repositories and upgrade the distro: apt update && upgrade | ||||||
|  | 4. Ensure you will install the most recent Ansible version: apt-add-repository --yes --update ppa:ansible/ansible | ||||||
|  | 5. Install the following packages: apt install python python-pip ansible unzip sshpass libffi-dev libssl-dev | ||||||
|  | 6. Install PyWinRM using: pip install pywinrm | ||||||
|  | 7. Install Terraform and Packer by downloading the 64-bit Linux binaries and moving them to /usr/local/bin | ||||||
|  | 8. Install VMWare OVF tool by downloading 64-bit Linux binary from my.vmware.com and running it with "--eulas-agreed" option | ||||||
|  | 9. Download the Linux binary for the Terraform ESXi Provider from https://github.com/josenk/terraform-provider-esxi/releases and move it to /usr/local/bin | ||||||
|  | 10. From "DetectionLab/ESXi/ansible" directory, run: "ansible --version" and ensure that the config file used is "DetectionLab/ESXi/ansible/ansible.cfg". If not, implement the Ansible "world-writtable directory" fix by going to running: "chmod o-w ." from "DetectionLab/ESXi/ansible" directory. | ||||||
|  |  | ||||||
| ## Future work required | ## Future work required | ||||||
| * It probably makes sense to abstract all of the logic in `bootstrap.sh` into individual Ansible tasks | * It probably makes sense to abstract all of the logic in `bootstrap.sh` into individual Ansible tasks | ||||||
| * There's a lot of areas to make reliability improvements | * There's a lot of areas to make reliability improvements | ||||||
|   | |||||||
| @@ -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/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/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/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) |       ## 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 |       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') |     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)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL" | ||||||
|     echo "[$(date +%H:%M:%S)]: Attempting to download..." |     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 |     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!" |       echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!" | ||||||
|     else |     else | ||||||
|   | |||||||
| @@ -30,8 +30,8 @@ resource "esxi_guest" "logger" { | |||||||
|  |  | ||||||
|     provisioner "remote-exec" { |     provisioner "remote-exec" { | ||||||
|     inline = [ |     inline = [ | ||||||
|       "sudo ifconfig up eth1 || echo 'eth1 up'", |       "sudo ifconfig eth1 up || echo 'eth1 up'", | ||||||
|       "sudo ifconfig up eth2 || echo 'eth2 up'", |       "sudo ifconfig eth2 up || echo 'eth2 up'", | ||||||
|       "sudo route add default gw 192.168.76.1 || echo 'route exists'" |       "sudo route add default gw 192.168.76.1 || echo 'route exists'" | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								README.md
									
									
									
									
									
								
							| @@ -111,3 +111,30 @@ A sizable percentage of this code was borrowed and adapted from [Stefan Scherer] | |||||||
| * [Atomic Red Team](https://github.com/redcanaryco/atomic-red-team) | * [Atomic Red Team](https://github.com/redcanaryco/atomic-red-team) | ||||||
| * [Hunting for Beacons](http://findingbad.blogspot.com/2020/05/hunting-for-beacons-part-2.html) | * [Hunting for Beacons](http://findingbad.blogspot.com/2020/05/hunting-for-beacons-part-2.html) | ||||||
| * [BadBlood](https://github.com/davidprowe/BadBlood) | * [BadBlood](https://github.com/davidprowe/BadBlood) | ||||||
|  |  | ||||||
|  | # DetectionLab Sponsors | ||||||
|  | #### Lated updated: 8/8/2020 | ||||||
|  | I would like to extend thanks to the following sponsors for funding DetectionLab development. If you are interested in becoming a sponsor, please visit the [sponsors page](https://github.com/sponsors/clong). | ||||||
|  |  | ||||||
|  | ### Diamond Sponsors: | ||||||
|  | * [Veramine](https://github.com/veramine) | ||||||
|  | * [Thinkst](https://github.com/ThinkstAppliedResearch) | ||||||
|  |  | ||||||
|  | ### Premium Sponsors: | ||||||
|  | * [CyDefUnicorn](https://github.com/CyDefUnicorn) | ||||||
|  | * [dlee35](https://github.com/dlee35) | ||||||
|  | * [chrissanders](https://github.com/chrissanders) | ||||||
|  | * [punchdrunktux](https://github.com/punchdrunktux) | ||||||
|  | * [jaredhaight](https://github.com/jaredhaight) | ||||||
|  | * [iamfuntime](https://github.com/iamfuntime) | ||||||
|  | * +1 private sponsor | ||||||
|  |  | ||||||
|  | ### Standard Sponsors: | ||||||
|  | * [dtonomy](https://github.com/dtonomy) | ||||||
|  | * [braimee](https://github.com/braimee) | ||||||
|  | * [iLoC0dez](https://github.com/iLoC0dez) | ||||||
|  | * [defensivedepth](https://github.com/defensivedepth) | ||||||
|  | * [elreydetoda](https://github.com/elreydetoda) | ||||||
|  | * [kafkaesqu3](https://github.com/kafkaesqu3) | ||||||
|  | * [anthonysecurity](https://github.com/anthonysecurity) | ||||||
|  | * +2 private sponsors | ||||||
							
								
								
									
										2
									
								
								Vagrant/Vagrantfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								Vagrant/Vagrantfile
									
									
									
									
										vendored
									
									
								
							| @@ -188,7 +188,7 @@ Vagrant.configure("2") do |config| | |||||||
|     cfg.winrm.retry_limit = 20 |     cfg.winrm.retry_limit = 20 | ||||||
|     cfg.vm.network :private_network, ip: "192.168.38.104", gateway: "192.168.38.1", dns: "192.168.38.102" |     cfg.vm.network :private_network, ip: "192.168.38.104", 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.104 -dns 8.8.8.8 -gateway 192.168.38.1"  |     cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: false, args: "-ip 192.168.38.104 -dns 8.8.8.8 -gateway 192.168.38.1"  | ||||||
|     cfg.vm.provision "shell", path: "scripts/MakeWindows10GreatAgain.ps1", privileged: false |     cfg.vm.provision "shell", path: "scripts/MakeWindows10GreatAgain.ps1", privileged: false | ||||||
|     cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false |     cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false | ||||||
|     cfg.vm.provision "reload" |     cfg.vm.provision "reload" | ||||||
|   | |||||||
| @@ -163,12 +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/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/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/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 |  | ||||||
|     sed -i 's/= sysmoneventcode /= sysmoneventcodes.csv /g' /opt/splunk/etc/apps/ThreatHunting/default/props.conf |  | ||||||
|     sed -i 's/sysmoneventcode.csv/sysmoneventcodes.csv/g' /opt/splunk/etc/apps/ThreatHunting/default/props.conf |  | ||||||
|  |  | ||||||
|     # Install the Maxmind license key for the ASNgen App |     # Install the Maxmind license key for the ASNgen App | ||||||
|     if [ -n "$MAXMIND_LICENSE" ]; then |     if [ -n "$MAXMIND_LICENSE" ]; then | ||||||
| @@ -177,8 +172,17 @@ install_splunk() { | |||||||
|       sed -i "s/license_key =/license_key = $MAXMIND_LICENSE/g" /opt/splunk/etc/apps/TA-asngen/local/asngen.conf |       sed -i "s/license_key =/license_key = $MAXMIND_LICENSE/g" /opt/splunk/etc/apps/TA-asngen/local/asngen.conf | ||||||
|     fi |     fi | ||||||
|  |  | ||||||
|  |     # Replace the props.conf for Sysmon TA and Windows TA | ||||||
|  |     # Removed all the 'rename = xmlwineventlog' directives | ||||||
|  |     # I know youre not supposed to modify files in "default", | ||||||
|  |     # but for some reason adding them to "local" wasnt working | ||||||
|  |     cp /vagrant/resources/splunk_server/windows_ta_props.conf /opt/splunk/etc/apps/Splunk_TA_windows/default/props.conf | ||||||
|  |     cp /vagrant/resources/splunk_server/sysmon_ta_props.conf /opt/splunk/etc/apps/TA-microsoft-sysmon/default/props.conf | ||||||
|  |  | ||||||
|     # Add custom Macro definitions for ThreatHunting App |     # Add custom Macro definitions for ThreatHunting App | ||||||
|     cp /vagrant/resources/splunk_server/macros.conf /opt/splunk/etc/apps/ThreatHunting/default/macros.conf |     cp /vagrant/resources/splunk_server/macros.conf /opt/splunk/etc/apps/ThreatHunting/default/macros.conf | ||||||
|  |     # Fix props.conf in ThreatHunting App | ||||||
|  |     sed -i 's/EVAL-host_fqdn = Computer/EVAL-host_fqdn = ComputerName/g' /opt/splunk/etc/apps/ThreatHunting/default/props.conf | ||||||
|     # Fix Windows TA macros |     # Fix Windows TA macros | ||||||
|     mkdir /opt/splunk/etc/apps/Splunk_TA_windows/local |     mkdir /opt/splunk/etc/apps/Splunk_TA_windows/local | ||||||
|     cp /opt/splunk/etc/apps/Splunk_TA_windows/default/macros.conf /opt/splunk/etc/apps/Splunk_TA_windows/local |     cp /opt/splunk/etc/apps/Splunk_TA_windows/default/macros.conf /opt/splunk/etc/apps/Splunk_TA_windows/local | ||||||
| @@ -398,7 +402,9 @@ install_velociraptor() { | |||||||
|   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') |   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)]: The URL for the latest release was extracted as $LATEST_VELOCIRAPTOR_LINUX_URL" | ||||||
|   echo "[$(date +%H:%M:%S)]: Attempting to download..." |   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 |   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!" |     echo "[$(date +%H:%M:%S)]: Velociraptor successfully downloaded!" | ||||||
|   else |   else | ||||||
|   | |||||||
| @@ -323,7 +323,7 @@ current_only = 0 | |||||||
| checkpointInterval = 5 | checkpointInterval = 5 | ||||||
|  |  | ||||||
| [WinEventLog://WEC6-Sysmon] | [WinEventLog://WEC6-Sysmon] | ||||||
| sourcetype = "XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" | sourcetype = XmlWinEventLog:Microsoft-Windows-Sysmon/Operational | ||||||
| source = WinEventLog:Sysmon | source = WinEventLog:Sysmon | ||||||
| index=sysmon | index=sysmon | ||||||
| disabled = 0 | disabled = 0 | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								Vagrant/resources/splunk_server/sysmon_ta_props.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Vagrant/resources/splunk_server/sysmon_ta_props.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | ##Below fields extractions have been moved from [XmlWinEventLog:Microsoft-Windows-Sysmon/Operational] | ||||||
|  | [source::XmlWinEventLog:Microsoft-Windows-Sysmon/Operational] | ||||||
|  | #SEDCMD-pwd_rule1 = s/ -pw ([^\s\<])+/ -pw ***MASK***/g | ||||||
|  | REPORT-sysmon = sysmon-eventid,sysmon-version,sysmon-level,sysmon-task,sysmon-opcode,sysmon-keywords,sysmon-created,sysmon-record,sysmon-correlation,sysmon-channel,sysmon-computer,sysmon-sid,sysmon-data,sysmon-md5,sysmon-sha1,sysmon-sha256,sysmon-imphash,sysmon-hashes,sysmon-filename,sysmon-registry,sysmon-dns-record-data,sysmon-dns-ip-data | ||||||
|  |  | ||||||
|  | FIELDALIAS-src_ip = SourceIp AS src_ip | ||||||
|  | FIELDALIAS-src_host = SourceHostname AS src_host | ||||||
|  | EVAL-src = if(isnotnull(SourceHostname),SourceHostname,SourceIp) | ||||||
|  | FIELDALIAS-src_port = SourcePort AS src_port | ||||||
|  | FIELDALIAS-app = Image AS app | ||||||
|  | FIELDALIAS-dest_ip = DestinationIp AS dest_ip | ||||||
|  | FIELDALIAS-dest_host = DestinationHostname AS dest_host | ||||||
|  | EVAL-dest = case(EventCode=="3" AND isnotnull(DestinationHostname),DestinationHostname,EventCode=="3",DestinationIp,EventCode=="1" OR EventCode == "11" OR EventCode == "12" OR EventCode == "13" OR EventCode == "14", Computer) | ||||||
|  | FIELDALIAS-dest_port = DestinationPort AS dest_port | ||||||
|  | EVAL-direction = if(Initiated=="true","outbound","inbound") | ||||||
|  | FIELDALIAS-dvc = Computer AS dvc | ||||||
|  | FIELDALIAS-transport = Protocol AS transport | ||||||
|  | EVAL-protocol = if(Initiated=="true",DestinationPortName,SourcePortName) | ||||||
|  | FIELDALIAS-session_id = ProcessGuid AS session_id | ||||||
|  | EVAL-vendor_product = "Microsoft Sysmon" | ||||||
|  | FIELDALIAS-cmdline = CommandLine AS cmdline | ||||||
|  |  | ||||||
|  | #Common fieldnames for Registry, Process, FileSystem Node in Endpoint Datamodel | ||||||
|  | EVAL-action = case(EventCode=="1","allowed",EventCode=="12" AND EventType=="CreateKey","created",EventCode=="12" AND (EventType=="DeleteKey" OR EventType=="DeleteValue") ,"deleted",EventCode=="13" AND EventType=="SetValue","modified",EventCode=="11" AND EventDescription=="File Created","created") | ||||||
|  |  | ||||||
|  | #Ports Node | ||||||
|  | EVAL-creation_time = case(EventCode=="3",UtcTime) | ||||||
|  | EVAL-state = case(EventCode=="3", "listening") | ||||||
|  |  | ||||||
|  | #Processes Node | ||||||
|  | EVAL-parent_process_exec = case(EventCode=="1" OR EventCode=="2" OR EventCode=="3" OR EventCode=="5" OR EventCode=="7" OR EventCode=="9" OR EventCode=="11" OR EventCode=="12" OR EventCode=="13" OR EventCode=="14" OR EventCode=="15" OR EventCode=="17" OR EventCode=="18", replace(ParentImage,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),1==1,"") | ||||||
|  | FIELDALIAS-parent_process_id = ParentProcessId AS parent_process_id | ||||||
|  | FIELDALIAS-parent_process_guid = ParentProcessGuid AS parent_process_guid | ||||||
|  | FIELDALIAS-parent_process_path = ParentImage AS parent_process_path | ||||||
|  | FIELDALIAS-process_current_directory = CurrentDirectory AS process_current_directory | ||||||
|  | EVAL-process_exec = case(EventCode=="1" OR EventCode=="2" OR EventCode=="3" OR EventCode=="5" OR EventCode=="7" OR EventCode=="9" OR EventCode=="11" OR EventCode=="12" OR EventCode=="13" OR EventCode=="14" OR EventCode=="15" OR EventCode=="17" OR EventCode=="18" OR EventCode="22", replace(Image,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),EventCode=="6","System",EventCode=="8" OR EventCode=="10",replace(SourceImage,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),1==1,"") | ||||||
|  | FIELDALIAS-process_hash = Hashes AS process_hash | ||||||
|  | FIELDALIAS-process_guid = ProcessGuid AS process_guid | ||||||
|  | FIELDALIAS-process_id = ProcessId AS process_id | ||||||
|  | FIELDALIAS-process_integrity_level = IntegrityLevel AS process_integrity_level | ||||||
|  | FIELDALIAS-process_path = Image AS process_path | ||||||
|  | FIELDALIAS-user_id = UserID AS user_id | ||||||
|  | REPORT-user_for_sysmon = User_as_user | ||||||
|  | FIELDALIAS-parent_process = ParentCommandLine AS parent_process | ||||||
|  | EVAL-parent_process_name = case(EventCode=="1" OR EventCode=="2" OR EventCode=="3" OR EventCode=="5" OR EventCode=="7" OR EventCode=="9" OR EventCode=="11" OR EventCode=="12" OR EventCode=="13" OR EventCode=="14" OR EventCode=="15" OR EventCode=="17" OR EventCode=="18", replace(ParentImage,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),1==1,"") | ||||||
|  | FIELDALIAS-process = CommandLine AS process | ||||||
|  | EVAL-process_name = case(EventCode=="1" OR EventCode=="2" OR EventCode=="3" OR EventCode=="5" OR EventCode=="7" OR EventCode=="9" OR EventCode=="11" OR EventCode=="12" OR EventCode=="13" OR EventCode=="14" OR EventCode=="15" OR EventCode=="17" OR EventCode=="18" OR EventCode="22", replace(Image,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),EventCode=="6","System",EventCode=="8" OR EventCode=="10",replace(SourceImage,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)",""),1==1,"") | ||||||
|  |  | ||||||
|  | #Filesystem Node | ||||||
|  | FIELDALIAS-file_path = TargetFilename AS file_path | ||||||
|  | FIELDALIAS-file_create_time = CreationUtcTime AS file_create_time | ||||||
|  |  | ||||||
|  | #Fields for ChangeAnalysis DM (old field names) | ||||||
|  | EVAL-object_category = case(EventCode=="11" OR EventCode=="2", "file", EventCode=="12" OR EventCode=="13" OR EventCode="14", "registry", EventCode=="19" OR EventCode=="20" OR EventCode="21", "wmi") | ||||||
|  | EVAL-object_path = case(EventCode=="12" OR EventCode=="13", TargetObject, EventCode=="14", NewName) | ||||||
|  | LOOKUP-eventcode = eventcode EventCode OUTPUTNEW EventDescription EventDescription AS signature | ||||||
|  | FIELDALIAS-signature_id = EventCode AS signature_id | ||||||
|  | FIELDALIAS-eventid = EventCode AS EventID | ||||||
|  |  | ||||||
|  | #Registry Node | ||||||
|  | EVAL-registry_path = case(EventCode=="12" OR EventCode=="13" OR EventCode=="14", TargetObject) | ||||||
|  | EVAL-registry_value_name = case(EventCode=="13", Details) | ||||||
|  | EVAL-registry_key_name = case(EventCode=="12" OR EventCode=="13" OR EventCode=="14",replace(TargetObject,".+\\\\","")) | ||||||
|  |  | ||||||
|  | #DNS Node | ||||||
|  | FIELDALIAS-query = QueryName AS query | ||||||
|  | FIELDALIAS-replycode = QueryStatus AS reply_code_id | ||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Vagrant/resources/splunk_server/threathunting_144.tgz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Vagrant/resources/splunk_server/threathunting_144.tgz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1495
									
								
								Vagrant/resources/splunk_server/windows_ta_props.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1495
									
								
								Vagrant/resources/splunk_server/windows_ta_props.conf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -2,7 +2,7 @@ | |||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Configuring auditing policy GPOs..." | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Configuring auditing policy GPOs..." | ||||||
| $GPOName = 'Domain Controllers Enhanced Auditing Policy' | $GPOName = 'Domain Controllers Enhanced Auditing Policy' | ||||||
| $OU = "ou=Domain Controllers,dc=windomain,dc=local" | $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 | Import-GPO -BackupGpoName $GPOName -Path "c:\vagrant\resources\GPO\Domain_Controllers_Enhanced_Auditing_Policy" -TargetName $GPOName -CreateIfNeeded | ||||||
| $gpLinks = $null | $gpLinks = $null | ||||||
| $gPLinks = Get-ADOrganizationalUnit -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions | $gPLinks = Get-ADOrganizationalUnit -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions | ||||||
| @@ -13,7 +13,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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' | $GPOName = 'Servers Enhanced Auditing Policy' | ||||||
| $OU = "ou=Servers,dc=windomain,dc=local" | $OU = "ou=Servers,dc=windomain,dc=local" | ||||||
| @@ -28,7 +28,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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' | $GPOName = 'Workstations Enhanced Auditing Policy' | ||||||
| @@ -44,5 +44,5 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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." | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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" | $OU = "ou=Servers,dc=windomain,dc=local" | ||||||
| $gPLinks = $null | $gPLinks = $null | ||||||
| @@ -24,6 +24,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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 | gpupdate /force | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ while ($servers_ou_created -ne 1) { | |||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Server OU..." |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Server OU..." | ||||||
|   try { |   try { | ||||||
|     Get-ADOrganizationalUnit -Identity 'OU=Servers,DC=windomain,DC=local' | Out-Null |     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 |     $servers_ou_created = 1 | ||||||
|   } |   } | ||||||
|   catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { |   catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { | ||||||
| @@ -19,11 +19,11 @@ while ($servers_ou_created -ne 1) { | |||||||
|     $servers_ou_created = 1 |     $servers_ou_created = 1 | ||||||
|   } |   } | ||||||
|   catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { |   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 |     Start-Sleep 5 | ||||||
|   } |   } | ||||||
|   catch { |   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..." | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Workstations OU..." | ||||||
|   try { |   try { | ||||||
|     Get-ADOrganizationalUnit -Identity 'OU=Workstations,DC=windomain,DC=local' | Out-Null |     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 |     $workstations_ou_created = 1 | ||||||
|   } |   } | ||||||
|   catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { |   catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { | ||||||
| @@ -42,11 +42,11 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Creating Workstations OU..." | |||||||
|     $workstations_ou_created = 1 |     $workstations_ou_created = 1 | ||||||
|   } |   } | ||||||
|   catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { |   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 |     Start-Sleep 5 | ||||||
|   } |   } | ||||||
|   catch { |   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." | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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" | $OU = "ou=Servers,dc=windomain,dc=local" | ||||||
| $gPLinks = $null | $gPLinks = $null | ||||||
| @@ -23,7 +23,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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" | $OU = "ou=Domain Controllers,dc=windomain,dc=local" | ||||||
| $gPLinks = $null | $gPLinks = $null | ||||||
| @@ -34,6 +34,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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 | gpupdate /force | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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" | $OU = "ou=Servers,dc=windomain,dc=local" | ||||||
| $gPLinks = $null | $gPLinks = $null | ||||||
| @@ -24,6 +24,6 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| } | } | ||||||
| else | 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 | gpupdate /force | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| { | { | ||||||
|     New-GPLink -Name $GPOName -Target $OU -Enforced yes |     New-GPLink -Name $GPOName -Target $OU -Enforced yes | ||||||
| } else { | } 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" | $OU = "ou=Domain Controllers,dc=windomain,dc=local" | ||||||
| $gpLinks = $null | $gpLinks = $null | ||||||
| @@ -21,7 +21,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| { | { | ||||||
|     New-GPLink -Name $GPOName -Target $OU -Enforced yes |     New-GPLink -Name $GPOName -Target $OU -Enforced yes | ||||||
| } else { | } 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" | $OU = "ou=Workstations,dc=windomain,dc=local" | ||||||
| $gpLinks = $null | $gpLinks = $null | ||||||
| @@ -31,7 +31,7 @@ If ($gPLinks.LinkedGroupPolicyObjects -notcontains $gpo.path) | |||||||
| { | { | ||||||
|     New-GPLink -Name $GPOName -Target $OU -Enforced yes |     New-GPLink -Name $GPOName -Target $OU -Enforced yes | ||||||
| } else { | } 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" | 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 | 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" | $OU = "ou=Domain Controllers,dc=windomain,dc=local" | ||||||
| $gPLinks = Get-ADOrganizationalUnit -Server "dc.windomain.local" -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions | $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 | 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" | $OU = "ou=Workstations,dc=windomain,dc=local" | ||||||
| $gPLinks = Get-ADOrganizationalUnit -Server "dc.windomain.local" -Identity $OU -Properties name,distinguishedName, gPLink, gPOptions | $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 | 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 | gpupdate /force | ||||||
|   | |||||||
| @@ -63,24 +63,29 @@ if ((gwmi win32_computersystem).partofdomain -eq $false) { | |||||||
|   dnscmd /ResetListenAddresses  $dnslistenip |   dnscmd /ResetListenAddresses  $dnslistenip | ||||||
|  |  | ||||||
|   $nics=Get-WmiObject "Win32_NetworkAdapterConfiguration where IPEnabled='TRUE'" |? { $_.IPAddress[0] -ilike "10.*" } |   $nics=Get-WmiObject "Win32_NetworkAdapterConfiguration where IPEnabled='TRUE'" |? { $_.IPAddress[0] -ilike "10.*" } | ||||||
|   foreach($nic in $nics) |   foreach($nic in $nics) { | ||||||
|   { |  | ||||||
|     $nic.DomainDNSRegistrationEnabled = $false |     $nic.DomainDNSRegistrationEnabled = $false | ||||||
|     $nic.SetDynamicDNSRegistration($false) |Out-Null |     $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 "@" |   $RRs= Get-DnsServerResourceRecord -ZoneName $domain -type 1 -Name "@" | ||||||
|  |   foreach($RR in $RRs) { | ||||||
|  foreach($RR in $RRs) |     if ( (Select-Object  -InputObject $RR HostName,RecordType -ExpandProperty RecordData).IPv4Address -ilike "10.*") { | ||||||
|  { |  | ||||||
|   if ( (Select-Object  -InputObject $RR HostName,RecordType -ExpandProperty RecordData).IPv4Address -ilike "10.*") |  | ||||||
|   { |  | ||||||
|       Remove-DnsServerResourceRecord -ZoneName $domain -RRType A -Name "@" -RecordData $RR.RecordData.IPv4Address -Confirm |       Remove-DnsServerResourceRecord -ZoneName $domain -RRType A -Name "@" -RecordData $RR.RecordData.IPv4Address -Confirm | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   } |   } | ||||||
|   Restart-Service DNS |   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" | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,6 +13,6 @@ If (-not (Test-Path $wefRepoPath)) | |||||||
| } | } | ||||||
| else | 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!" | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Palantir WEF download complete!" | ||||||
|   | |||||||
| @@ -1,32 +1,34 @@ | |||||||
| # Source: https://github.com/StefanScherer/adfs2 | # Source: https://github.com/StefanScherer/adfs2 | ||||||
| param ([String] $ip, [String] $dns, [String] $gateway) | param ([String] $ip, [String] $dns, [String] $gateway) | ||||||
|  |  | ||||||
|  | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Running fix-second-network.ps1..." | ||||||
|  |  | ||||||
| if ( (Get-NetAdapter | Select-Object -First 1 | Select-Object -ExpandProperty InterfaceDescription).Contains('Red Hat VirtIO')) { | 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+$", "" |   $subnet = $ip -replace "\.\d+$", "" | ||||||
|   $name = (Get-NetIPAddress -AddressFamily IPv4 ` |   $name = (Get-NetIPAddress -AddressFamily IPv4 ` | ||||||
|      | Where-Object -FilterScript { ($_.IPAddress).StartsWith("$subnet") } ` |      | Where-Object -FilterScript { ($_.IPAddress).StartsWith("$subnet") } ` | ||||||
|      ).InterfaceAlias |      ).InterfaceAlias | ||||||
|   if ($name) { |   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" |     & netsh.exe int ip set address "$name" static $ip 255.255.255.0 "$gateway" | ||||||
|     if ($dns) { |     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 |       & netsh.exe interface ipv4 add dnsserver "$name" address=$dns index=1 | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     Write-Error "Could not find a interface with subnet $subnet.xx" |     Write-Error "Could not find a interface with subnet $subnet.xx" | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   exit 0 |   exit 0 | ||||||
|  | } Else { | ||||||
|  |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) No VirtIO adapters, moving on..." | ||||||
| } | } | ||||||
|  |  | ||||||
| if (! (Test-Path 'C:\Program Files\VMware\VMware Tools') ) { | 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)) VMware Tools not found, no need to continue. Exiting." | ||||||
|   exit 0 |   exit 0 | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date))" | Write-Host "$('[{0:HH:mm}]' -f (Get-Date))" | ||||||
| Write-Host "Setting IP address and DNS information for the Ethernet1 interface" | 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" | Write-Host "If this step times out, it's because vagrant is connecting to the VM on the wrong interface" | ||||||
| @@ -42,12 +44,12 @@ if (!$name) { | |||||||
|      ).InterfaceAlias |      ).InterfaceAlias | ||||||
| } | } | ||||||
| if ($name) { | 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" |   & netsh.exe int ip set address "$name" static $ip 255.255.255.0 "$subnet.1" | ||||||
|   if ($dns) { |   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 |     & netsh.exe interface ipv4 add dnsserver "$name" address=$dns index=1 | ||||||
|   } |   } | ||||||
| } else { | } 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" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ Elseif ($regex.Matches.Value -eq "0xC004FC07") { | |||||||
|   Try { |   Try { | ||||||
|     cscript c:\windows\system32\slmgr.vbs /rearm |     cscript c:\windows\system32\slmgr.vbs /rearm | ||||||
|   } Catch { |   } 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 { |     Try { | ||||||
|       cscript c:\windows\system32\slmgr.vbs /rearm |       cscript c:\windows\system32\slmgr.vbs /rearm | ||||||
|     } Catch { |     } 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..." | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| }  | }  | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing AutorunsToWinEventLog..." | |||||||
| If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) | If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) | ||||||
| { | { | ||||||
|     . c:\Users\vagrant\AppData\Local\Temp\windows-event-forwarding-master\AutorunsToWinEventLog\Install.ps1 |     . 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" |     Start-ScheduledTask -TaskName "AutorunsToWinEventLog" | ||||||
|     # https://mcpmag.com/articles/2018/03/16/wait-action-function-powershell.aspx |     # https://mcpmag.com/articles/2018/03/16/wait-action-function-powershell.aspx | ||||||
|     # Wait 30 seconds for the scheduled task to enter the "Running" state |     # 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() |     $timer = [Diagnostics.Stopwatch]::StartNew() | ||||||
|     while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog").State -ne "Running")) { |     while (($timer.Elapsed.TotalSeconds -lt $Timeout) -and ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog").State -ne "Running")) { | ||||||
|         Start-Sleep -Seconds 3 |         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() |     $timer.Stop() | ||||||
|     $Tsk = Get-ScheduledTask -TaskName "AutorunsToWinEventLog" |     $Tsk = Get-ScheduledTask -TaskName "AutorunsToWinEventLog" | ||||||
| @@ -23,5 +23,5 @@ If ((Get-ScheduledTask -TaskName "AutorunsToWinEventLog" -ea silent) -eq $null) | |||||||
| } | } | ||||||
| else | else | ||||||
| { | { | ||||||
|     Write-Host "AutorunsToWinEventLog already installed. Moving On." |     Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) AutorunsToWinEventLog already installed. Moving On." | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,13 +3,13 @@ | |||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing additional Choco packages..." | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing additional Choco packages..." | ||||||
|  |  | ||||||
| If (-not (Test-Path "C:\ProgramData\chocolatey")) { | 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')) |   iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) | ||||||
| } else { | } 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 | choco install -y --limit-output --no-progress wireshark winpcap | ||||||
|  |  | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Choco addons complete!" | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Choco addons complete!" | ||||||
|   | |||||||
| @@ -1,37 +0,0 @@ | |||||||
| # Purpose: Configures the inputs.conf for the Splunk forwarders on the Windows hosts |  | ||||||
|  |  | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Setting up Splunk Inputs for Sysmon & osquery" |  | ||||||
|  |  | ||||||
| $inputsPath = "C:\Program Files\SplunkUniversalForwarder\etc\apps\SplunkUniversalForwarder\local\inputs.conf" |  | ||||||
| $currentContent = get-content $inputsPath |  | ||||||
| $targetContent = get-content c:\vagrant\resources\splunk_forwarder\inputs.conf |  | ||||||
|  |  | ||||||
| if ($currentContent -ne $targetContent) |  | ||||||
| { |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Stopping the Splunk forwarder" |  | ||||||
|   try { |  | ||||||
|     Stop-Service splunkforwarder -ErrorAction Stop |  | ||||||
|   } catch { |  | ||||||
|     Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Failed to stop SplunkForwarder. Trying again..." |  | ||||||
|     Set-Location "C:\Program Files\SplunkUniversalForwarder\bin" |  | ||||||
|     & ".\splunk.exe" "stop" |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Deleting the default configuration" |  | ||||||
|   Remove-Item $inputsPath |  | ||||||
|  |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Copying over the custom configuration" |  | ||||||
|   Copy-Item c:\vagrant\resources\splunk_forwarder\inputs.conf $inputsPath |  | ||||||
|  |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Starting the Splunk forwarder" |  | ||||||
|   Start-Service splunkforwarder |  | ||||||
| } |  | ||||||
| else |  | ||||||
| { |  | ||||||
|   Write-Host "Splunk forwarder already configured. Moving on." |  | ||||||
| } |  | ||||||
| If ((Get-Service -name splunkforwarder).Status -ne "Running") |  | ||||||
| { |  | ||||||
|   throw "splunkforwarder service was not running." |  | ||||||
| } |  | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Splunk forwarder installation complete!" |  | ||||||
| @@ -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 |     $Mount = Mount-DiskImage -ImagePath "$env:temp\$title.iso" -StorageType ISO -Access ReadOnly -PassThru | ||||||
|     $Volume = $Mount | Get-Volume |     $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 = Start-Process -Wait -FilePath ($Volume.DriveLetter + ":\Microsoft ATA Center Setup.exe") -ArgumentList "/q --LicenseAccepted NetFrameworkCommandLineArguments=`"/q`" --EnableMicrosoftUpdate" -PassThru | ||||||
|     $Install |     $Install | ||||||
|     $Mount | Dismount-DiskImage -Confirm:$false |     $Mount | Dismount-DiskImage -Confirm:$false | ||||||
| @@ -110,7 +110,7 @@ Invoke-Command -computername dc -Credential (new-object pscredential("windomain\ | |||||||
|     [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [SSLValidator]::GetDelegate() |     [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [SSLValidator]::GetDelegate() | ||||||
|  |  | ||||||
|     If (-not (Test-Path "$env:temp\gatewaysetup.zip")) { |     If (-not (Test-Path "$env:temp\gatewaysetup.zip")) { | ||||||
|         Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [$env:computername] Downloading Microsoft ATA now..." |         Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [$env:computername] Downloading ATA Lightweight Gateway from WEF now..." | ||||||
|         Invoke-WebRequest -uri https://wef/api/management/softwareUpdates/gateways/deploymentPackage -UseBasicParsing -OutFile "$env:temp\gatewaysetup.zip" -Credential (new-object pscredential("wef\vagrant", (convertto-securestring -AsPlainText -Force -String "vagrant"))) |         Invoke-WebRequest -uri https://wef/api/management/softwareUpdates/gateways/deploymentPackage -UseBasicParsing -OutFile "$env:temp\gatewaysetup.zip" -Credential (new-object pscredential("wef\vagrant", (convertto-securestring -AsPlainText -Force -String "vagrant"))) | ||||||
|         Expand-Archive -Path "$env:temp\gatewaysetup.zip" -DestinationPath "$env:temp\gatewaysetup" -Force |         Expand-Archive -Path "$env:temp\gatewaysetup.zip" -DestinationPath "$env:temp\gatewaysetup" -Force | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -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 | 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'" | $service = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'" | ||||||
| If (-not ($service)) { | 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`"" |   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 |   # Download the flags file from the Palantir osquery-configuration Github | ||||||
| @@ -38,7 +38,7 @@ If (-not ($service)) { | |||||||
|   Start-Service osqueryd |   Start-Service osqueryd | ||||||
| } | } | ||||||
| else { | 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") | If ((Get-Service -name osqueryd).Status -ne "Running") | ||||||
| { | { | ||||||
|   | |||||||
| @@ -11,13 +11,22 @@ If ($hostname -eq "win10") { | |||||||
|   Set-MpPreference -DisableRealtimeMonitoring $true |   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') { | 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) |   # Uninstalling Windows Defender (https://github.com/StefanScherer/packer-windows/issues/201) | ||||||
|   Uninstall-WindowsFeature Windows-Defender |     Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Uninstalling Windows Defender..." | ||||||
|   Uninstall-WindowsFeature Windows-Defender-Features |   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 | # Purpose: Downloads and unzips a copy of the latest Mimikatz trunk | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Mimikatz..." | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Mimikatz..." | ||||||
| # GitHub requires TLS 1.2 as of 2/27 | # 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 |   Expand-Archive -path "$mimikatzRepoPath" -destinationpath 'c:\Tools\Mimikatz' -Force | ||||||
| } | } | ||||||
| else { | 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 | # 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 |   Copy-Item "c:\Tools\PowerSploit\PowerSploit-dev\*" "$Env:windir\System32\WindowsPowerShell\v1.0\Modules" -Recurse -Force | ||||||
| } | } | ||||||
| else { | 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 | # 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 |   Expand-Archive -path "$atomicRedTeamRepoPath" -destinationpath 'c:\Tools\Atomic Red Team' -Force | ||||||
| } | } | ||||||
| else { | 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 | # 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 |   ((Get-Content -path $invokeBadBloodPath -Raw) -replace '1000..5000','500..1500') | Set-Content -Path $invokeBadBloodPath | ||||||
| } | } | ||||||
| else { | 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!" | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Red Team tooling installation complete!" | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| # Purpose: Installs a Splunk Universal Forwader on the host | # Purpose: Installs a Splunk Universal Forwader on the host | ||||||
|  |  | ||||||
| If (-not (Test-Path "C:\Program Files\SplunkUniversalForwarder\bin\splunk.exe")) { | 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" |   $msiFile = $env:Temp + "\splunkforwarder-7.1.0-2e75b3406c5b-x64-release.msi" | ||||||
|  |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing & Starting Splunk" |   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) |   (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 |   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 { | } 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") | If ((Get-Service -name splunkforwarder).Status -ne "Running") | ||||||
| { | { | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| # Purpose: Installs a handful of SysInternals tools on the host into c:\Tools\Sysinternals | # 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..." | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing SysInternals Tooling..." | ||||||
| $sysinternalsDir = "C:\Tools\Sysinternals" | $sysinternalsDir = "C:\Tools\Sysinternals" | ||||||
| @@ -6,14 +7,14 @@ $sysmonDir = "C:\ProgramData\Sysmon" | |||||||
| If(!(test-path $sysinternalsDir)) { | If(!(test-path $sysinternalsDir)) { | ||||||
|   New-Item -ItemType Directory -Force -Path $sysinternalsDir |   New-Item -ItemType Directory -Force -Path $sysinternalsDir | ||||||
| } Else { | } 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 |   exit | ||||||
| } | } | ||||||
|  |  | ||||||
| If(!(test-path $sysmonDir)) { | If(!(test-path $sysmonDir)) { | ||||||
|   New-Item -ItemType Directory -Force -Path $sysmonDir |   New-Item -ItemType Directory -Force -Path $sysmonDir | ||||||
| } Else { | } 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 |   exit | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,10 +2,10 @@ | |||||||
|  |  | ||||||
| If (-not (Test-Path "C:\ProgramData\chocolatey")) { | If (-not (Test-Path "C:\ProgramData\chocolatey")) { | ||||||
|   [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |   [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')) |   iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) | ||||||
| } else { | } 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..." | 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  | 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!" | ||||||
|   | |||||||
| @@ -13,7 +13,9 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Determining latest release of Velocir | |||||||
| # GitHub requires TLS 1.2 as of 2/27 | # GitHub requires TLS 1.2 as of 2/27 | ||||||
| [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | ||||||
| $tag = (Invoke-WebRequest "https://api.github.com/repos/Velocidex/velociraptor/releases" -UseBasicParsing | ConvertFrom-Json)[0].tag_name | $tag = (Invoke-WebRequest "https://api.github.com/repos/Velocidex/velociraptor/releases" -UseBasicParsing | ConvertFrom-Json)[0].tag_name | ||||||
| $velociraptorDownloadUrl = "https://github.com/Velocidex/velociraptor/releases/download/$tag/velociraptor-$tag-windows-amd64.msi" | # Workaround hardcoded URL until this issue gets fixed: https://github.com/Velocidex/velociraptor/issues/528 | ||||||
|  | $velociraptorDownloadUrl = "https://github.com/Velocidex/velociraptor/releases/download/v0.4.7/velociraptor-v0.4.7-1-windows-amd64.msi" | ||||||
|  | #$velociraptorDownloadUrl = "https://github.com/Velocidex/velociraptor/releases/download/$tag/velociraptor-$tag-windows-amd64.msi" | ||||||
| $velociraptorMSIPath = 'C:\Users\vagrant\AppData\Local\Temp\velociraptor.msi' | $velociraptorMSIPath = 'C:\Users\vagrant\AppData\Local\Temp\velociraptor.msi' | ||||||
| $velociraptorLogFile = 'c:\Users\vagrant\AppData\Local\Temp\velociraptor_install.log' | $velociraptorLogFile = 'c:\Users\vagrant\AppData\Local\Temp\velociraptor_install.log' | ||||||
| If (-not (Test-Path $velociraptorLogFile)) { | If (-not (Test-Path $velociraptorLogFile)) { | ||||||
| @@ -25,7 +27,7 @@ If (-not (Test-Path $velociraptorLogFile)) { | |||||||
|   Restart-Service Velociraptor |   Restart-Service Velociraptor | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Velociraptor successfully installed!" |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Velociraptor successfully installed!" | ||||||
| } Else { | } 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") | If ((Get-Service -name Velociraptor).Status -ne "Running") | ||||||
| { | { | ||||||
|   | |||||||
| @@ -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..." |     Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing Custom Event Channels Manifest..." | ||||||
|     wevtutil im "c:\windows\system32\CustomEventChannels.man" |     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" |     $xml = wevtutil el | select-string -pattern "WEC" | ||||||
|     foreach ($subscription in $xml) { wevtutil sl $subscription /ms:4294967296 } |     foreach ($subscription in $xml) { wevtutil sl $subscription /ms:4294967296 } | ||||||
|  |  | ||||||
| @@ -30,7 +30,7 @@ if (-not (Test-Path "$env:windir\system32\CustomEventChannels.dll")) | |||||||
| } | } | ||||||
| else | 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") |   if ((Get-Service -Name wecsvc).Status -ne "Running") | ||||||
|   { |   { | ||||||
|     net start wecsvc |     net start wecsvc | ||||||
|   | |||||||
| @@ -3,9 +3,9 @@ | |||||||
|  |  | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing the Windows TA for Splunk" | 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") { | 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 |   Exit 0 | ||||||
| } | } | ||||||
|  |  | ||||||
| # Install Windows TA (this only needs to be done on the WEF server) | # Install Windows TA (this only needs to be done on the WEF server) | ||||||
| @@ -16,14 +16,14 @@ Start-Process -FilePath "C:\Program Files\SplunkUniversalForwarder\bin\splunk.ex | |||||||
|  |  | ||||||
| # Create local directory | # Create local directory | ||||||
| New-Item -ItemType Directory -Force -Path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\local" | New-Item -ItemType Directory -Force -Path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\local" | ||||||
| Copy-Item c:\vagrant\resources\splunk_forwarder\wef_inputs.conf $inputsPath | Copy-Item c:\vagrant\resources\splunk_forwarder\wef_inputs.conf $inputsPath -Force | ||||||
|  |  | ||||||
| # Add a check here to make sure the TA was installed correctly | # Add a check here to make sure the TA was installed correctly | ||||||
| Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Sleeping for 15 seconds" | Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Sleeping for 15 seconds" | ||||||
| start-sleep -s 15 | Start-Sleep -s 15 | ||||||
| If (test-path "C:\Program Files\SplunkUniversalForwarder\etc\apps\Splunk_TA_windows\default") { | 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." |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Windows TA installed successfully." | ||||||
| } Else { | } Else { | ||||||
|   Write-Host "Something went wrong during installation." |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong during installation." | ||||||
|   exit 1 |   exit 1 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ $DomainCred = New-Object System.Management.Automation.PSCredential $user, $pass | |||||||
| If ($hostname -eq "wef") { | If ($hostname -eq "wef") { | ||||||
|   Add-Computer -DomainName "windomain.local" -credential $DomainCred -OUPath "ou=Servers,dc=windomain,dc=local" -PassThru |   Add-Computer -DomainName "windomain.local" -credential $DomainCred -OUPath "ou=Servers,dc=windomain,dc=local" -PassThru | ||||||
| } ElseIf ($hostname -eq "win10") { | } 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" |   Add-Computer -DomainName "windomain.local" -credential $DomainCred -OUPath "ou=Workstations,dc=windomain,dc=local" | ||||||
| } Else { | } Else { | ||||||
|   Add-Computer -DomainName "windomain.local" -credential $DomainCred -PassThru |   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" | Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value "vagrant" | ||||||
|  |  | ||||||
| # Stop Windows Update | # 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 | Set-Service wuauserv -StartupType Disabled | ||||||
| Stop-Service wuauserv | Stop-Service wuauserv | ||||||
| Set-Service TrustedInstaller -StartupType Disabled | Set-Service TrustedInstaller -StartupType Disabled | ||||||
| Stop-Service TrustedInstaller | 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" | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -13,7 +13,7 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Checking if Windows evaluation is exp | |||||||
| # Ping DetectionLab server for usage statistics | # Ping DetectionLab server for usage statistics | ||||||
| curl -userAgent "DetectionLab-$box" "https://detectionlab.network/$box" -UseBasicParsing | out-null | 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 | ForEach-Object {Disable-NetAdapterBinding -Name $_.Name -ComponentID ms_tcpip6} | ||||||
| Get-NetAdapterBinding -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 | # 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..." |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Installing bginfo..." | ||||||
|   . c:\vagrant\scripts\install-bginfo.ps1 |   . c:\vagrant\scripts\install-bginfo.ps1 | ||||||
|  |  | ||||||
|   Write-Host -fore red 'Hint: vagrant reload' $box '--provision' |  | ||||||
|  |  | ||||||
| } elseif ((gwmi win32_computersystem).partofdomain -eq $false) { | } 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')) { |   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 |     . c:\vagrant\scripts\install-bginfo.ps1 | ||||||
|     # Set background to be "fitted" instead of "tiled" |     # Set background to be "fitted" instead of "tiled" | ||||||
|     Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name TileWallpaper -Value '0' |     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 |     . c:\vagrant\scripts\join-domain.ps1 | ||||||
|   } |   } | ||||||
| } else { | } else { | ||||||
|  |  | ||||||
|   Write-Host -fore green "$('[{0:HH:mm}]' -f (Get-Date)) I am domain joined!" |   Write-Host -fore green "$('[{0:HH:mm}]' -f (Get-Date)) I am domain joined!" | ||||||
|  |  | ||||||
|   if (!(Test-Path 'c:\Program Files\sysinternals\bginfo.exe')) { |   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 |     . c:\vagrant\scripts\install-bginfo.ps1 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Provisioning after joining domain..." |   Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Provisioning after joining domain..." | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ sed -i 's#http://archive.ubuntu.com#http://us.archive.ubuntu.com#g' /etc/apt/sou | |||||||
|  |  | ||||||
| # Install VMWare Workstation 15 | # Install VMWare Workstation 15 | ||||||
| apt-get update | 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 | pip install awscli --upgrade --user | ||||||
| cp /root/.local/bin/aws /usr/local/bin/aws && chmod +x /usr/local/bin/aws | cp /root/.local/bin/aws /usr/local/bin/aws && chmod +x /usr/local/bin/aws | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								img/badblood.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								img/badblood.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 40 KiB | 
		Reference in New Issue
	
	Block a user
	 sukster
					sukster