├── .gitignore ├── CNAME ├── Deploy-AD ├── DesiredSateConfig │ ├── Add-SSH-key.zip │ ├── Create-AD.zip │ ├── Deploy-ADCS-brokie.zip │ ├── Deploy-ADCS.zip │ ├── Install-Sysmon.zip │ ├── Join-Domain.zip │ └── src │ │ ├── Add-DC1-Services.ps1 │ │ ├── Add-DC2-Domain.ps1 │ │ ├── Add-DC3-Objects.ps1 │ │ ├── Add-SSH-key.ps1 │ │ ├── Create-AD.ps1 │ │ ├── Deploy-ADCS.ps1 │ │ ├── Install-Sysmon.ps1 │ │ └── Join-Domain.ps1 ├── azuredeploy-ad.json ├── resources │ ├── APT1.jpg │ ├── CheckContext.ps1 │ ├── DOLAB.gif │ ├── ca_templates │ │ ├── DOAZLab_Computer.json │ │ ├── DOAZLab_IPSec.json │ │ ├── DOAZLab_User.json │ │ ├── vuln_template1.json │ │ └── vuln_template4.json │ ├── doazlab_gpos.zip │ ├── dolabs.bgi │ ├── layout.xml │ └── sysmon.xml ├── scripts │ ├── Add-Browsers.ps1 │ ├── Add-DoazLabGPOs.ps1 │ ├── Add-Shortcuts.ps1 │ ├── Enable-PowerShell-Logging.ps1 │ ├── Enable-WinAuditCategories.ps1 │ ├── Install-DSC-Modules.ps1 │ ├── Prepare-Box.ps1 │ ├── Set-AuditRule.ps1 │ ├── Set-ChromeFRU.ps1 │ ├── Set-EdgeFRU.ps1 │ ├── Set-Initial-Settings.ps1 │ ├── Set-SACLs.ps1 │ ├── Set-ServerManager.ps1 │ └── Set-WallPaper.ps1 └── templates │ ├── AddSSHKey.json │ ├── createADForest.json │ ├── deployADCS.json │ ├── joinDomain.json │ ├── sysmonInstall.json │ └── vnet-dns-server.json ├── Deploy-AMA └── azuredeploy-ama.json ├── Deploy-DCRs └── azuredeploy-DCRs.json ├── Deploy-LAB ├── azure-deploy.json └── uidefinition.json ├── Deploy-Linux ├── azuredeploy-Linux.json └── scripts │ ├── .zshrc │ ├── Install-C2.sh │ ├── Install-Tools.sh │ ├── RunAtReboot.sh │ └── makekey.sh ├── Deploy-NetPeering └── azuredeploy-netpeering.json ├── Deploy-Sentinel ├── azuredeploy-sentinel.json ├── deploy-sysmonparser.json ├── deploy-sysmonparser_new.json └── resources │ └── sentinelparser.kql ├── LICENSE ├── README.html ├── README.md ├── _config.yml ├── images ├── APT1.jpg └── labenv.png └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /.vs/* 6 | /.vs/slnx.sqlite 7 | /.vs/VSWorkspaceState.json 8 | /Win10-AD/.vs 9 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | www.doazlab.com -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Add-SSH-key.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Add-SSH-key.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Create-AD.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Create-AD.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Deploy-ADCS-brokie.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Deploy-ADCS-brokie.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Deploy-ADCS.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Deploy-ADCS.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Install-Sysmon.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Install-Sysmon.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/Join-Domain.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/DesiredSateConfig/Join-Domain.zip -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Add-DC1-Services.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | # References: 4 | # https://github.com/Azure/azure-quickstart-templates/blob/master/sharepoint-adfs/dsc/ConfigureDCVM.ps1 5 | configuration ADD-DC1-Services { 6 | param 7 | ( 8 | [Parameter(Mandatory)] 9 | [String]$DomainFQDN, 10 | 11 | [Parameter(Mandatory)] 12 | [System.Management.Automation.PSCredential]$AdminCreds, 13 | 14 | [Parameter(Mandatory)] 15 | [Object]$DomainUsers 16 | ) 17 | 18 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, xDnsServer, ComputerManagementDsc 19 | 20 | [String] $DomainNetbiosName = (Get-NetBIOSName -DomainFQDN $DomainFQDN) 21 | [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainNetbiosName}\$($Admincreds.UserName)", $Admincreds.Password) 22 | 23 | $Interface = Get-NetAdapter | Where-Object Name -Like "Ethernet*" | Select-Object -First 1 24 | $InterfaceAlias = $($Interface.Name) 25 | $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AdminCreds.Password) 26 | $AdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) 27 | $ComputerName = Get-Content env:computername 28 | 29 | Node localhost 30 | { 31 | LocalConfigurationManager 32 | { 33 | ConfigurationMode = 'ApplyOnly' 34 | RebootNodeIfNeeded = $true 35 | } 36 | 37 | # ***** Add DNS and AD Features ***** 38 | WindowsFeature DNS 39 | { 40 | Ensure = "Present" 41 | Name = "DNS" 42 | } 43 | 44 | Script EnableDNSDiags 45 | { 46 | SetScript = { 47 | Set-DnsServerDiagnostics -All $true 48 | Write-Verbose -Verbose "Enabling DNS client diagnostics" 49 | } 50 | GetScript = { @{} } 51 | TestScript = { $false } 52 | DependsOn = "[WindowsFeature]DNS" 53 | } 54 | 55 | WindowsFeature DnsTools 56 | { 57 | Ensure = "Present" 58 | Name = "RSAT-DNS-Server" 59 | DependsOn = "[WindowsFeature]DNS" 60 | } 61 | 62 | DnsServerAddress SetDNS 63 | { 64 | Address = '127.0.0.1' 65 | InterfaceAlias = $InterfaceAlias 66 | AddressFamily = 'IPv4' 67 | DependsOn = "[WindowsFeature]DNS" 68 | } 69 | 70 | WindowsFeature ADDSInstall 71 | { 72 | Ensure = "Present" 73 | Name = "AD-Domain-Services" 74 | DependsOn = "[WindowsFeature]DNS" 75 | } 76 | 77 | WindowsFeature ADDSTools 78 | { 79 | Ensure = "Present" 80 | Name = "RSAT-ADDS-Tools" 81 | DependsOn = "[WindowsFeature]ADDSInstall" 82 | } 83 | 84 | WindowsFeature ADAdminCenter 85 | { 86 | Ensure = "Present" 87 | Name = "RSAT-AD-AdminCenter" 88 | DependsOn = "[WindowsFeature]ADDSTools" 89 | } 90 | 91 | 92 | PendingReboot RebootOnSignalFromADAdminCenter 93 | { 94 | Name = 'RebootOnSignalFromADAdminCenter' 95 | DependsOn = "[WindowsFeature]ADAdminCenter" 96 | } 97 | } 98 | } 99 | 100 | function Get-NetBIOSName { 101 | [OutputType([string])] 102 | param( 103 | [string]$DomainFQDN 104 | ) 105 | 106 | if ($DomainFQDN.Contains('.')) { 107 | $length = $DomainFQDN.IndexOf('.') 108 | if ( $length -ge 16) { 109 | $length = 15 110 | } 111 | return $DomainFQDN.Substring(0, $length) 112 | } 113 | else { 114 | if ($DomainFQDN.Length -gt 15) { 115 | return $DomainFQDN.Substring(0, 15) 116 | } 117 | else { 118 | return $DomainFQDN 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Add-DC2-Domain.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | # References: 4 | # https://github.com/Azure/azure-quickstart-templates/blob/master/sharepoint-adfs/dsc/ConfigureDCVM.ps1 5 | configuration Add-DC2-Domain { 6 | param 7 | ( 8 | [Parameter(Mandatory)] 9 | [String]$DomainFQDN, 10 | 11 | [Parameter(Mandatory)] 12 | [System.Management.Automation.PSCredential]$AdminCreds, 13 | 14 | [Parameter(Mandatory)] 15 | [Object]$DomainUsers 16 | ) 17 | 18 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, xDnsServer, ComputerManagementDsc 19 | 20 | [String] $DomainNetbiosName = (Get-NetBIOSName -DomainFQDN $DomainFQDN) 21 | [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainNetbiosName}\$($Admincreds.UserName)", $Admincreds.Password) 22 | 23 | $Interface = Get-NetAdapter | Where-Object Name -Like "Ethernet*" | Select-Object -First 1 24 | $InterfaceAlias = $($Interface.Name) 25 | $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AdminCreds.Password) 26 | $AdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) 27 | $ComputerName = Get-Content env:computername 28 | 29 | Node localhost 30 | { 31 | LocalConfigurationManager 32 | { 33 | ConfigurationMode = 'ApplyOnly' 34 | RebootNodeIfNeeded = $true 35 | } 36 | 37 | # ****** Create AD Domain ********* 38 | ADDomain CreateADForest 39 | { 40 | DomainName = $DomainFQDN 41 | Credential = $DomainCreds 42 | SafemodeAdministratorPassword = $DomainCreds 43 | DatabasePath = "C:\NTDS" 44 | LogPath = "C:\NTDS" 45 | SysvolPath = "C:\SYSVOL" 46 | } 47 | 48 | PendingReboot RebootOnSignalFromCreateADForest 49 | { 50 | Name = 'RebootOnSignalFromCreateADForest' 51 | DependsOn = "[ADDomain]CreateADForest" 52 | } 53 | } 54 | } 55 | 56 | function Get-NetBIOSName { 57 | [OutputType([string])] 58 | param( 59 | [string]$DomainFQDN 60 | ) 61 | 62 | if ($DomainFQDN.Contains('.')) { 63 | $length = $DomainFQDN.IndexOf('.') 64 | if ( $length -ge 16) { 65 | $length = 15 66 | } 67 | return $DomainFQDN.Substring(0, $length) 68 | } 69 | else { 70 | if ($DomainFQDN.Length -gt 15) { 71 | return $DomainFQDN.Substring(0, 15) 72 | } 73 | else { 74 | return $DomainFQDN 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Add-DC3-Objects.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | # References: 4 | # https://github.com/Azure/azure-quickstart-templates/blob/master/sharepoint-adfs/dsc/ConfigureDCVM.ps1 5 | configuration Add-DC3-Objects { 6 | param 7 | ( 8 | [Parameter(Mandatory)] 9 | [String]$DomainFQDN, 10 | 11 | [Parameter(Mandatory)] 12 | [System.Management.Automation.PSCredential]$AdminCreds, 13 | 14 | [Parameter(Mandatory)] 15 | [Object]$DomainUsers 16 | ) 17 | 18 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, xDnsServer, ComputerManagementDsc 19 | 20 | [String] $DomainNetbiosName = (Get-NetBIOSName -DomainFQDN $DomainFQDN) 21 | [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainNetbiosName}\$($Admincreds.UserName)", $Admincreds.Password) 22 | 23 | $Interface = Get-NetAdapter | Where-Object Name -Like "Ethernet*" | Select-Object -First 1 24 | $InterfaceAlias = $($Interface.Name) 25 | $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AdminCreds.Password) 26 | $AdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) 27 | $ComputerName = Get-Content env:computername 28 | 29 | Node localhost 30 | { 31 | LocalConfigurationManager 32 | { 33 | ConfigurationMode = 'ApplyOnly' 34 | RebootNodeIfNeeded = $true 35 | } 36 | 37 | WaitForADDomain WaitForDCReady 38 | { 39 | DomainName = $DomainFQDN 40 | WaitTimeout = 300 41 | RestartCount = 3 42 | Credential = $DomainCreds 43 | WaitForValidCredentials = $true 44 | } 45 | 46 | # ***** Create OUs ***** 47 | xScript CreateOUs 48 | { 49 | SetScript = { 50 | # Verifying ADWS service is running 51 | $ServiceName = 'ADWS' 52 | $arrService = Get-Service -Name $ServiceName 53 | 54 | while ($arrService.Status -ne 'Running') 55 | { 56 | Start-Service $ServiceName 57 | Start-Sleep -seconds 5 58 | $arrService.Refresh() 59 | } 60 | 61 | $DomainName1,$DomainName2 = ($using:domainFQDN).split('.') 62 | 63 | $ParentPath = "DC=$DomainName1,DC=$DomainName2" 64 | $OUS = @(("Workstations","Workstations in the domain"),("Servers","Servers in the domain"),("LogCollectors","Servers collecting event logs"),("DomainUsers","Users in the domain")) 65 | 66 | foreach($OU in $OUS) 67 | { 68 | #Check if exists, if it does skip 69 | [string] $Path = "OU=$($OU[0]),$ParentPath" 70 | if(![adsi]::Exists("LDAP://$Path")) 71 | { 72 | New-ADOrganizationalUnit -Name $OU[0] -Path $ParentPath ` 73 | -Description $OU[1] ` 74 | -ProtectedFromAccidentalDeletion $false -PassThru 75 | } 76 | } 77 | } 78 | GetScript = 79 | { 80 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 81 | return @{ "Result" = "false" } 82 | } 83 | TestScript = 84 | { 85 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 86 | return $false 87 | } 88 | DependsOn = "[WaitForADDomain]WaitForDCReady" 89 | } 90 | 91 | # ***** Create Domain Users ***** 92 | xScript CreateDomainUsers 93 | { 94 | SetScript = { 95 | # Verifying ADWS service is running 96 | $ServiceName = 'ADWS' 97 | $arrService = Get-Service -Name $ServiceName 98 | 99 | while ($arrService.Status -ne 'Running') 100 | { 101 | Start-Service $ServiceName 102 | Start-Sleep -seconds 5 103 | $arrService.Refresh() 104 | } 105 | 106 | $DomainName = $using:domainFQDN 107 | $DomainName1,$DomainName2 = $DomainName.split('.') 108 | $ADServer = $using:ComputerName+"."+$DomainName 109 | 110 | $NewDomainUsers = $using:DomainUsers 111 | 112 | foreach ($DomainUser in $NewDomainUsers) 113 | { 114 | $UserPrincipalName = $DomainUser.SamAccountName + "@" + $DomainName 115 | $DisplayName = $DomainUser.LastName + " " + $DomainUser.FirstName 116 | $OUPath = "OU="+$DomainUser.UserContainer+",DC=$DomainName1,DC=$DomainName2" 117 | $SamAccountName = $DomainUser.SamAccountName 118 | $ServiceName = $DomainUser.FirstName 119 | 120 | $UserExists = Get-ADUser -LDAPFilter "(sAMAccountName=$SamAccountName)" 121 | 122 | if ($UserExists -eq $Null) 123 | { 124 | write-host "Creating user $UserPrincipalName .." 125 | New-ADUser -Name $DisplayName ` 126 | -DisplayName $DisplayName ` 127 | -GivenName $DomainUser.FirstName ` 128 | -Surname $DomainUser.LastName ` 129 | -Department $DomainUser.Department ` 130 | -Title $DomainUser.JobTitle ` 131 | -UserPrincipalName $UserPrincipalName ` 132 | -SamAccountName $DomainUser.SamAccountName ` 133 | -Path $OUPath ` 134 | -AccountPassword (ConvertTo-SecureString $DomainUser.Password -AsPlainText -force) ` 135 | -Enabled $true ` 136 | -PasswordNeverExpires $true ` 137 | -Server $ADServer 138 | 139 | if($DomainUser.Identity -Like "Domain Admins") 140 | { 141 | $DomainAdminUser = $DomainUser.SamAccountName 142 | $Groups = @('domain admins','schema admins','enterprise admins') 143 | $Groups | ForEach-Object{ 144 | $members = Get-ADGroupMember -Identity $_ -Recursive | Select-Object -ExpandProperty Name 145 | if ($members -contains $DomainAdminUser) 146 | { 147 | Write-Host "$DomainAdminUser exists in $_ " 148 | } 149 | else { 150 | Add-ADGroupMember -Identity $_ -Members $DomainAdminUser 151 | } 152 | } 153 | } 154 | if($DomainUser.JobTitle -Like "Service Account") 155 | { 156 | setspn -a $ServiceName/$DomainName $DomainName1\$SamAccountName 157 | } 158 | } 159 | } 160 | } 161 | GetScript = 162 | { 163 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 164 | return @{ "Result" = "false" } 165 | } 166 | TestScript = 167 | { 168 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 169 | return $false 170 | } 171 | DependsOn = "[xScript]CreateOUs" 172 | } 173 | } 174 | } 175 | 176 | function Get-NetBIOSName { 177 | [OutputType([string])] 178 | param( 179 | [string]$DomainFQDN 180 | ) 181 | 182 | if ($DomainFQDN.Contains('.')) { 183 | $length = $DomainFQDN.IndexOf('.') 184 | if ( $length -ge 16) { 185 | $length = 15 186 | } 187 | return $DomainFQDN.Substring(0, $length) 188 | } 189 | else { 190 | if ($DomainFQDN.Length -gt 15) { 191 | return $DomainFQDN.Substring(0, 15) 192 | } 193 | else { 194 | return $DomainFQDN 195 | } 196 | } 197 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Add-SSH-key.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | configuration Add-Key { 4 | param 5 | ( 6 | [Parameter(Mandatory)] 7 | [String]$DomainFQDN, 8 | 9 | [Parameter(Mandatory)] 10 | [System.Management.Automation.PSCredential]$AdminCreds 11 | 12 | ) 13 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, ComputerManagementDsc 14 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 15 | 16 | Node localhost 17 | { 18 | LocalConfigurationManager 19 | { 20 | ConfigurationMode = 'ApplyOnly' 21 | RebootNodeIfNeeded = $true 22 | } 23 | 24 | # ***** Install ADCS ***** 25 | xScript InstallADCS 26 | { 27 | SetScript = { 28 | New-Item -ItemType Directory -Path "C:\ProgramData\DOAZLab" -Force > $null 29 | $targetPath = "C:\ProgramData\DOAZLab\id_rsa" 30 | 31 | $privateKey = @" 32 | -----BEGIN OPENSSH PRIVATE KEY----- 33 | b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn 34 | NhAAAAAwEAAQAAAgEAtV8aFw/6ByVPYXCXOBr9PtWSl2a3eHsqKmxtEVTAcF38pXOOToyO 35 | KELMCtLEBrYc8PpI1GW/dHXJDyDpdBhT2QrBLyJ57wSWgo7EucCrKu26IZ0SVD/HA11zoe 36 | MqwknDLwXfKNcSmz0L2q3/pEq26eKRd7HYasD43zDqtH471DLqa344llcTgpgnn4cjrVIL 37 | 0YRREEkm7TzekjLT6oESprV8LDDcFFlrziV36zkJeViUaA3Lx7M/TZUdjVy3gbwGcP152H 38 | lMgr9kMJeU2hZOvy9bsbIQILdZ/OhzqCQ5wHXF4nhwNx6+ogGPmIVuUyFjeDjKdTKSVBwQ 39 | g+u5/ADQWubYAcoXGnzTD6hxYhNm6P8xBys/Z05IzSJgobv9J+IQFo63yYKKEwvaC2tWcr 40 | rxi53mHLjWrGQZAcNueZdABYK2Xs+61qiw4cgsW+E9Rx8HI9BknKcrbQBQBCjU0VX8tw7D 41 | RWlpL8KGtWtDIIXL8/w9O4y+L6luoHL4L0OmmAAQhTTKxftzxZwM/y1B+3dJ7aZVyJzNqW 42 | ZqhyOHWnGFIH9WySPmlBZE+l/cHmWXcFaA8nyvJtiqd1pGa96/KCs+uX8PKtp1LZrgg4Dn 43 | 1MDi/DzcJd6KybCZ/ZA1Xmypm6HT+01CCxyeHrW0mqCK5XJmjvijG3Y3V/oSdm9+EpCDKV 44 | 0AAAdIvPR2+Lz0dvgAAAAHc3NoLXJzYQAAAgEAtV8aFw/6ByVPYXCXOBr9PtWSl2a3eHsq 45 | KmxtEVTAcF38pXOOToyOKELMCtLEBrYc8PpI1GW/dHXJDyDpdBhT2QrBLyJ57wSWgo7Euc 46 | CrKu26IZ0SVD/HA11zoeMqwknDLwXfKNcSmz0L2q3/pEq26eKRd7HYasD43zDqtH471DLq 47 | a344llcTgpgnn4cjrVIL0YRREEkm7TzekjLT6oESprV8LDDcFFlrziV36zkJeViUaA3Lx7 48 | M/TZUdjVy3gbwGcP152HlMgr9kMJeU2hZOvy9bsbIQILdZ/OhzqCQ5wHXF4nhwNx6+ogGP 49 | mIVuUyFjeDjKdTKSVBwQg+u5/ADQWubYAcoXGnzTD6hxYhNm6P8xBys/Z05IzSJgobv9J+ 50 | IQFo63yYKKEwvaC2tWcrrxi53mHLjWrGQZAcNueZdABYK2Xs+61qiw4cgsW+E9Rx8HI9Bk 51 | nKcrbQBQBCjU0VX8tw7DRWlpL8KGtWtDIIXL8/w9O4y+L6luoHL4L0OmmAAQhTTKxftzxZ 52 | wM/y1B+3dJ7aZVyJzNqWZqhyOHWnGFIH9WySPmlBZE+l/cHmWXcFaA8nyvJtiqd1pGa96/ 53 | KCs+uX8PKtp1LZrgg4Dn1MDi/DzcJd6KybCZ/ZA1Xmypm6HT+01CCxyeHrW0mqCK5XJmjv 54 | ijG3Y3V/oSdm9+EpCDKV0AAAADAQABAAACAFSnFTnTaqsAJos/rkzxB+dWbqu8tQCGV/li 55 | DwwKRyGLNJsSksalwsoW1z5r/jN1t49f+jMsZE5alWO6xEu7+RKx+tXhnRDKzucT9M0QGL 56 | QaLgh3U/E/rUcsTIawTSpOnEurzWs16wjK1ugT02BewP3sEmJP/0dgVyhxH/Lrgkg6FYDj 57 | ckz1SnVnSAMk46mHRF3fiKh1xDXxdZ6+G3v2D3sA9Pp5OZdD31Xh1hVTU1EwX2ArpEPKrU 58 | 6sPRVYQ4xJcqY1ILRBdU0HQJ+PeFnMFKgWVhFbnzxt55Hr+uNtOQlTzu8zsIiBkI9z9A5H 59 | pOUnDdK0iwZlerfIO4sfMHjm9lfUin8VQoROZKsRt6DNnHNAmGIaHfFyylWjfRIPSl6IB2 60 | 0Wu3nUBn3AiYDo6I9aQsxpF58ky3XHlfUMycedYe6lScWS47F3pvXL2GZqLm+1uggI8Qr6 61 | Lsasp+izebSdf9C36/CxImA5lt9gIAnv+/YCQJOi/KI6TqeVx2bOjeJwQDMoRFEtK5SyZC 62 | fu2thq4YhTibgt0BMFfqIYAGgey5qhg4mXuea0Ii+paa0fbKJ7JDC3XKR3szoyFlNy2aI1 63 | FfXJ9dqYQJy6aXZjimVDpl28JiqxdODTfQYfNId4cs8cOBD5F55ppRwo7Vl5CYfLuEB6P0 64 | AEk2zlQxvMVimNYr6PAAABAQC4Nz0Y9a/RSvd6p9E03LTXDCo3vTVHndguhIbjLXeoHUu/ 65 | ZtA9dv8XFFSmZ3f1gOOutXYIgXKoK2A5ZkEQgRBlzArjdX8fwnw2X3I5nw1Oa2/WT5kDY6 66 | nLhdxOztTEwWMdCNWKADg6VHQNaKcO6qNKLcVoDOVEGv/bby4dadLwuKXnU0c1LdNX4b01 67 | tFPucuWL8ZJhszteZJ2AuARSV2ripZZu63LRHuAdskc/crhFofCnuScw7EQFGZtlDtETW8 68 | 5tHGgrkCphRQ97MN2Nq5o1rCZijPL4K3staYrC5WzUASFTIctyF8dQbLEysNeP1U3bMbdM 69 | YS3Y0aa8cwdDeTiFAAABAQC+2TKC7y31DomvYVELoCXmvhyCDAg5QUFzUZD9ahQXTNNsR+ 70 | 21RVAgs7089FNnR5N7x8gSsnKMRX2TYz9X4wwLreTQ0duJk2AJiO7LaTkj6bDNjHc8OY29 71 | 82kgwQKEjYPwl5BCS4K48aaKLuEfvM4PBA1nThVS0cshbVSgtJv/FdlibjIqwZDr7RWQGn 72 | maqpNpB4Qd2NwuJhc0bnJ72GM/qaRpanaRwq0gvYJD3d9EKore6KwAqTt7yP20pPGOsj61 73 | MEn7sEiXnh0cYw9v1BVpht9k1wT0P9d+2YXtMJJA7krkIUwBY1Xp5wumxhViubAKmzLT/J 74 | z04b7gVuREoSIvAAABAQDzSbAAEUbFg/n8tLRV9GzkjgbhucAQ8WWynBxFGdjsmpIGap1k 75 | nA7J9rooGBhQoPzby94L0UqI9AvP4BKheGIbXc0gD/DJdA6Q1iY/ftUXF1M1YpB5YSZOOn 76 | +PjczXXVAegzXdmteQyycIWiI/qqBR0vkMLoQkSBAe6/Gl2yp7FpZXsfF7ok9JEFsTEKg9 77 | qcy2VO12+4YBjGlIlrTBZizhOHn8r1bd8mmayLzjRaVxrGDMl/P0hnjDwBT+aReX9PUDLV 78 | 9NW4GQ5b0CXN5F6M5kQipnek/WInSI/Y2YGuZcmSKCn7CaxoFBmDfv9tyYnG2OmHEekPiE 79 | +65g8W06V8YzAAAADWRvYWRtaW5ATnV4MDEBAgMEBQ== 80 | -----END OPENSSH PRIVATE KEY----- 81 | 82 | "@ 83 | 84 | # Write to file without persisting the key elsewhere 85 | Set-Content -Path $targetPath -Value $privateKey -NoNewline 86 | 87 | # Verify the file (optional) 88 | Write-Output "Private key written to $targetPath" 89 | 90 | $targetPath = "C:\ProgramData\DOAZLab\id_rsa" 91 | $DomainUser = "doazlab\doadmin" # Set the domain user 92 | 93 | # Remove inherited permissions 94 | icacls $targetPath /inheritance:r 95 | 96 | # Grant full control to the domain user 97 | icacls $targetPath /grant "$DomainUser`:F" 98 | 99 | # Remove access for "Authenticated Users" 100 | icacls $targetPath /remove "NT AUTHORITY\Authenticated Users" 101 | 102 | # Remove access for "Users" group (optional, but recommended) 103 | icacls $targetPath /remove "BUILTIN\Users" 104 | 105 | # Verify new permissions 106 | icacls $targetPath 107 | 108 | 109 | } 110 | GetScript = 111 | { 112 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 113 | return @{ "Result" = "false" } 114 | } 115 | TestScript = 116 | { 117 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 118 | return $false 119 | } 120 | } 121 | 122 | } 123 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Create-AD.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | # References: 4 | # https://github.com/Azure/azure-quickstart-templates/blob/master/sharepoint-adfs/dsc/ConfigureDCVM.ps1 5 | configuration Create-AD { 6 | param 7 | ( 8 | [Parameter(Mandatory)] 9 | [String]$DomainFQDN, 10 | 11 | [Parameter(Mandatory)] 12 | [System.Management.Automation.PSCredential]$AdminCreds, 13 | 14 | [Parameter(Mandatory)] 15 | [Object]$DomainUsers 16 | ) 17 | 18 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, xDnsServer, ComputerManagementDsc 19 | 20 | [String] $DomainNetbiosName = (Get-NetBIOSName -DomainFQDN $DomainFQDN) 21 | [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainNetbiosName}\$($Admincreds.UserName)", $Admincreds.Password) 22 | 23 | $Interface = Get-NetAdapter | Where-Object Name -Like "Ethernet*" | Select-Object -First 1 24 | $InterfaceAlias = $($Interface.Name) 25 | $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AdminCreds.Password) 26 | $AdminPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) 27 | $ComputerName = Get-Content env:computername 28 | 29 | Node localhost 30 | { 31 | LocalConfigurationManager 32 | { 33 | ConfigurationMode = 'ApplyOnly' 34 | RebootNodeIfNeeded = $true 35 | } 36 | 37 | # ***** Add DNS and AD Features ***** 38 | WindowsFeature DNS 39 | { 40 | Ensure = "Present" 41 | Name = "DNS" 42 | } 43 | 44 | Script EnableDNSDiags 45 | { 46 | SetScript = { 47 | Set-DnsServerDiagnostics -All $true 48 | Write-Verbose -Verbose "Enabling DNS client diagnostics" 49 | } 50 | GetScript = { @{} } 51 | TestScript = { $false } 52 | DependsOn = "[WindowsFeature]DNS" 53 | } 54 | 55 | WindowsFeature DnsTools 56 | { 57 | Ensure = "Present" 58 | Name = "RSAT-DNS-Server" 59 | DependsOn = "[WindowsFeature]DNS" 60 | } 61 | 62 | DnsServerAddress SetDNS 63 | { 64 | Address = '127.0.0.1' 65 | InterfaceAlias = $InterfaceAlias 66 | AddressFamily = 'IPv4' 67 | DependsOn = "[WindowsFeature]DNS" 68 | } 69 | 70 | WindowsFeature ADDSInstall 71 | { 72 | Ensure = "Present" 73 | Name = "AD-Domain-Services" 74 | DependsOn = "[WindowsFeature]DNS" 75 | } 76 | 77 | WindowsFeature ADDSTools 78 | { 79 | Ensure = "Present" 80 | Name = "RSAT-ADDS-Tools" 81 | DependsOn = "[WindowsFeature]ADDSInstall" 82 | } 83 | 84 | WindowsFeature ADAdminCenter 85 | { 86 | Ensure = "Present" 87 | Name = "RSAT-AD-AdminCenter" 88 | DependsOn = "[WindowsFeature]ADDSInstall" 89 | } 90 | 91 | # ****** Create AD Domain ********* 92 | ADDomain CreateADForest 93 | { 94 | DomainName = $DomainFQDN 95 | Credential = $DomainCreds 96 | SafemodeAdministratorPassword = $DomainCreds 97 | DatabasePath = "C:\NTDS" 98 | LogPath = "C:\NTDS" 99 | SysvolPath = "C:\SYSVOL" 100 | DependsOn = "[DnsServerAddress]SetDNS", "[WindowsFeature]ADDSInstall" 101 | } 102 | 103 | PendingReboot RebootOnSignalFromCreateADForest 104 | { 105 | Name = 'RebootOnSignalFromCreateADForest' 106 | DependsOn = "[ADDomain]CreateADForest" 107 | } 108 | 109 | WaitForADDomain WaitForDCReady 110 | { 111 | DomainName = $DomainFQDN 112 | WaitTimeout = 300 113 | RestartCount = 3 114 | Credential = $DomainCreds 115 | WaitForValidCredentials = $true 116 | DependsOn = "[PendingReboot]RebootOnSignalFromCreateADForest" 117 | } 118 | 119 | # ***** Create OUs ***** 120 | xScript CreateOUs 121 | { 122 | SetScript = { 123 | # Verifying ADWS service is running 124 | $ServiceName = 'ADWS' 125 | $arrService = Get-Service -Name $ServiceName 126 | 127 | while ($arrService.Status -ne 'Running') 128 | { 129 | Start-Service $ServiceName 130 | Start-Sleep -seconds 5 131 | $arrService.Refresh() 132 | } 133 | 134 | $DomainName1,$DomainName2 = ($using:domainFQDN).split('.') 135 | 136 | $ParentPath = "DC=$DomainName1,DC=$DomainName2" 137 | $OUS = @(("Workstations","Workstations in the domain"),("Servers","Servers in the domain"),("LogCollectors","Servers collecting event logs"),("DomainUsers","Users in the domain")) 138 | 139 | foreach($OU in $OUS) 140 | { 141 | #Check if exists, if it does skip 142 | [string] $Path = "OU=$($OU[0]),$ParentPath" 143 | if(![adsi]::Exists("LDAP://$Path")) 144 | { 145 | New-ADOrganizationalUnit -Name $OU[0] -Path $ParentPath ` 146 | -Description $OU[1] ` 147 | -ProtectedFromAccidentalDeletion $false -PassThru 148 | } 149 | } 150 | } 151 | GetScript = 152 | { 153 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 154 | return @{ "Result" = "false" } 155 | } 156 | TestScript = 157 | { 158 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 159 | return $false 160 | } 161 | DependsOn = "[WaitForADDomain]WaitForDCReady" 162 | } 163 | 164 | # ***** Create Domain Users ***** 165 | xScript CreateDomainUsers 166 | { 167 | SetScript = { 168 | # Verifying ADWS service is running 169 | $ServiceName = 'ADWS' 170 | $arrService = Get-Service -Name $ServiceName 171 | 172 | while ($arrService.Status -ne 'Running') 173 | { 174 | Start-Service $ServiceName 175 | Start-Sleep -seconds 5 176 | $arrService.Refresh() 177 | } 178 | 179 | $DomainName = $using:domainFQDN 180 | $DomainName1,$DomainName2 = $DomainName.split('.') 181 | $ADServer = $using:ComputerName+"."+$DomainName 182 | 183 | $NewDomainUsers = $using:DomainUsers 184 | 185 | foreach ($DomainUser in $NewDomainUsers) 186 | { 187 | $UserPrincipalName = $DomainUser.SamAccountName + "@" + $DomainName 188 | $DisplayName = $DomainUser.LastName + " " + $DomainUser.FirstName 189 | $OUPath = "OU="+$DomainUser.UserContainer+",DC=$DomainName1,DC=$DomainName2" 190 | $SamAccountName = $DomainUser.SamAccountName 191 | $ServiceName = $DomainUser.FirstName 192 | 193 | $UserExists = Get-ADUser -LDAPFilter "(sAMAccountName=$SamAccountName)" 194 | 195 | if ($UserExists -eq $Null) 196 | { 197 | write-host "Creating user $UserPrincipalName .." 198 | New-ADUser -Name $DisplayName ` 199 | -DisplayName $DisplayName ` 200 | -GivenName $DomainUser.FirstName ` 201 | -Surname $DomainUser.LastName ` 202 | -Department $DomainUser.Department ` 203 | -Title $DomainUser.JobTitle ` 204 | -UserPrincipalName $UserPrincipalName ` 205 | -SamAccountName $DomainUser.SamAccountName ` 206 | -Path $OUPath ` 207 | -AccountPassword (ConvertTo-SecureString $DomainUser.Password -AsPlainText -force) ` 208 | -Enabled $true ` 209 | -PasswordNeverExpires $true ` 210 | -Server $ADServer 211 | 212 | if($DomainUser.Identity -Like "Domain Admins") 213 | { 214 | $DomainAdminUser = $DomainUser.SamAccountName 215 | $Groups = @('domain admins','schema admins','enterprise admins') 216 | $Groups | ForEach-Object{ 217 | $members = Get-ADGroupMember -Identity $_ -Recursive | Select-Object -ExpandProperty Name 218 | if ($members -contains $DomainAdminUser) 219 | { 220 | Write-Host "$DomainAdminUser exists in $_ " 221 | } 222 | else { 223 | Add-ADGroupMember -Identity $_ -Members $DomainAdminUser 224 | } 225 | } 226 | } 227 | if($DomainUser.JobTitle -Like "Service Account") 228 | { 229 | setspn -a $ServiceName/$DomainName $DomainName1\$SamAccountName 230 | } 231 | } 232 | } 233 | } 234 | GetScript = 235 | { 236 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 237 | return @{ "Result" = "false" } 238 | } 239 | TestScript = 240 | { 241 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 242 | return $false 243 | } 244 | DependsOn = "[xScript]CreateOUs" 245 | } 246 | } 247 | } 248 | 249 | function Get-NetBIOSName { 250 | [OutputType([string])] 251 | param( 252 | [string]$DomainFQDN 253 | ) 254 | 255 | if ($DomainFQDN.Contains('.')) { 256 | $length = $DomainFQDN.IndexOf('.') 257 | if ( $length -ge 16) { 258 | $length = 15 259 | } 260 | return $DomainFQDN.Substring(0, $length) 261 | } 262 | else { 263 | if ($DomainFQDN.Length -gt 15) { 264 | return $DomainFQDN.Substring(0, 15) 265 | } 266 | else { 267 | return $DomainFQDN 268 | } 269 | } 270 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Deploy-ADCS.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | 4 | configuration Deploy-ADCS { 5 | param 6 | ( 7 | [Parameter(Mandatory)] 8 | [String]$DomainFQDN, 9 | 10 | [Parameter(Mandatory)] 11 | [System.Management.Automation.PSCredential]$AdminCreds 12 | 13 | ) 14 | Import-DscResource -ModuleName ActiveDirectoryDsc, NetworkingDsc, xPSDesiredStateConfiguration, ComputerManagementDsc 15 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 16 | 17 | Node localhost 18 | { 19 | LocalConfigurationManager 20 | { 21 | ConfigurationMode = 'ApplyOnly' 22 | RebootNodeIfNeeded = $true 23 | } 24 | 25 | # ***** Install ADCS ***** 26 | xScript InstallADCS 27 | { 28 | SetScript = { 29 | Get-WindowsFeature -Name AD-Certificate | Install-WindowsFeature 30 | Add-WindowsFeature Adcs-Cert-Authority -IncludeManagementTools 31 | Install-AdcsCertificationAuthority -CAType EnterpriseRootCA -Force 32 | 33 | Add-WindowsFeature ADCS-Enroll-Web-Pol -IncludeManagementTools 34 | Add-WindowsFeature Adcs-Enroll-Web-Svc -IncludeManagementTools 35 | Add-WindowsFeature ADCS-Web-Enrollment -IncludeManagementTools 36 | Add-WindowsFeature ADCS-Device-Enrollment -IncludeManagementTools 37 | Add-WindowsFeature ADCS-Online-Cert -IncludeManagementTools 38 | 39 | #Install-AdcsEnrollmentPolicyWebService -Force 40 | #Install-AdcsEnrollmentWebService -Force 41 | #Install-AdcsNetworkDeviceEnrollmentService -Force 42 | #Install-AdcsOnlineresponder -Force 43 | #Install-AdcsWebEnrollment -Force 44 | 45 | 46 | #Add Default templates 47 | Add-CATemplate "ClientAuth" -Force 48 | Add-CATemplate "CodeSigning" -Force 49 | Add-CATemplate "Workstation" -Force 50 | Add-CATemplate "SmartcardUser" -Force 51 | Add-CATemplate "ExchangeUser" -Force 52 | Add-CATemplate "EnrollmentAgent" -Force 53 | 54 | #Install module to manage import/export of templates 55 | Install-Module ADCSTemplate -Force 56 | #Export-ADCSTemplate vuln_Template > vuln_template.json 57 | 58 | #Download DOLAB templates 59 | $wc = new-object System.Net.WebClient 60 | $wc.DownloadFile('https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/ca_templates/vuln_template1.json', 'C:\ProgramData\vuln_template1.json') 61 | $wc.DownloadFile('https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/ca_templates/vuln_template4.json', 'C:\ProgramData\vuln_template4.json') 62 | 63 | #Import DOLAB templates 64 | New-ADCSTemplate -DisplayName Vuln_Template1 -JSON (Get-Content C:\ProgramData\vuln_template1.json -Raw) -Publish 65 | New-ADCSTemplate -DisplayName Vuln_Template4 -JSON (Get-Content C:\ProgramData\vuln_template4.json -Raw) -Publish 66 | 67 | #ESC6 68 | certutil -config "DC01.doazlab.com\doazlab-DC01-CA" -setreg policy\Editflags +EDITF_ATTRIBUTESUBJECTALTNAME2 69 | 70 | #Restart CertSrv 71 | Restart-Service -Name CertSvc 72 | 73 | } 74 | GetScript = 75 | { 76 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 77 | return @{ "Result" = "false" } 78 | } 79 | TestScript = 80 | { 81 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 82 | return $false 83 | } 84 | } 85 | 86 | PendingReboot RebootOnSignalFromAADConnect 87 | { 88 | Name = 'RebootOnSignalFromADCS' 89 | DependsOn = "[xScript]InstallADCS" 90 | } 91 | 92 | } 93 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Install-Sysmon.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | configuration Install-Sysmon { 3 | param 4 | ( 5 | [string]$SysmonConfigUrl = "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/sysmon.xml" 6 | ) 7 | 8 | Import-DscResource -ModuleName xPSDesiredStateConfiguration, ComputerManagementDsc 9 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 10 | 11 | Node localhost 12 | { 13 | LocalConfigurationManager 14 | { 15 | ConfigurationMode = 'ApplyOnly' 16 | RebootNodeIfNeeded = $true 17 | } 18 | 19 | xRegistry SchUseStrongCrypto 20 | { 21 | Key = 'HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319' 22 | ValueName = 'SchUseStrongCrypto' 23 | ValueType = 'Dword' 24 | ValueData = '1' 25 | Ensure = 'Present' 26 | } 27 | 28 | xRegistry SchUseStrongCrypto64 29 | { 30 | Key = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319' 31 | ValueName = 'SchUseStrongCrypto' 32 | ValueType = 'Dword' 33 | ValueData = '1' 34 | Ensure = 'Present' 35 | } 36 | 37 | # ***** Download Sysmon Installer ***** 38 | xRemoteFile DownloadSysmonInstaller 39 | { 40 | DestinationPath = "C:\ProgramData\Sysmon.zip" 41 | Uri = "https://download.sysinternals.com/files/Sysmon.zip" 42 | DependsOn = @("[xRegistry]SchUseStrongCrypto","[xRegistry]SchUseStrongCrypto64") 43 | } 44 | 45 | # ***** Unzip Sysmon Installer ***** 46 | xArchive UnzipSysmonInstaller 47 | { 48 | Path = "C:\ProgramData\Sysmon.zip" 49 | Destination = "C:\ProgramData\Sysmon" 50 | Ensure = "Present" 51 | DependsOn = "[xRemoteFile]DownloadSysmonInstaller" 52 | } 53 | 54 | # ***** Download Sysmon Configuration ***** 55 | xRemoteFile DownloadSysmonConfig 56 | { 57 | DestinationPath = "C:\ProgramData\sysmon.xml" 58 | Uri = $SysmonConfigUrl 59 | } 60 | # ***** Install Sysmon ***** 61 | xRegistry SysmonEula 62 | { 63 | Key = 'HKEY_USERS\S-1-5-18\Software\Sysinternals\System Monitor' 64 | ValueName = 'EulaAccepted'; 65 | ValueType = 'DWORD' 66 | ValueData = '1' 67 | Ensure = 'Present' 68 | Force = $true 69 | DependsOn = @("[xArchive]UnzipSysmonInstaller","[xRemoteFile]DownloadSysmonConfig") 70 | } 71 | xScript InstallSysmon 72 | { 73 | SetScript = 74 | { 75 | # Installing Sysmon 76 | start-process -FilePath "C:\ProgramData\Sysmon\sysmon.exe" -ArgumentList @('-i','C:\ProgramData\sysmon.xml','-accepteula') -PassThru -NoNewWindow -ErrorAction Stop | Wait-Process 77 | 78 | # Set Sysmon to start automatically 79 | sc.exe config Sysmon start= auto 80 | 81 | # Setting Sysmon Channel Access permissions 82 | wevtutil set-log Microsoft-Windows-Sysmon/Operational /ca:'O:BAG:SYD:(A;;0xf0005;;;SY)(A;;0x5;;;BA)(A;;0x1;;;S-1-5-32-573)(A;;0x1;;;NS)' 83 | #New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WINEVT\Channels\Microsoft-Windows-Sysmon/Operational" -Name "ChannelAccess" -PropertyType String -Value "O:BAG:SYD:(A;;0xf0005;;;SY)(A;;0x5;;;BA)(A;;0x1;;;S-1-5-32-573)(A;;0x1;;;NS)" -Force 84 | 85 | # Restart-Service -Name Sysmon -Force 86 | } 87 | GetScript = 88 | { 89 | # This block must return a hashtable. The hashtable must only contain one key Result and the value must be of type String. 90 | return @{ "Result" = "false" } 91 | } 92 | TestScript = 93 | { 94 | # If it returns $false, the SetScript block will run. If it returns $true, the SetScript block will not run. 95 | return $false 96 | } 97 | DependsOn = '[xRegistry]SysmonEula' 98 | } 99 | xService Sysmon 100 | { 101 | Name = "Sysmon" 102 | State = "Running" 103 | DependsOn = '[xScript]InstallSysmon' 104 | } 105 | PendingReboot RebootAfterSysmonInstall 106 | { 107 | #added to ensure sysmon is using the updated config, after v 15 it is not easily possible to restart sysmon inside DSC 108 | Name = "RebootServer" 109 | DependsOn = "[xService]Sysmon" 110 | } 111 | 112 | } 113 | } -------------------------------------------------------------------------------- /Deploy-AD/DesiredSateConfig/src/Join-Domain.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez @Cyb3rWard0g 2 | # License: GPLv3 3 | configuration Join-Domain { 4 | param 5 | ( 6 | [Parameter(Mandatory)] 7 | [String]$DomainFQDN, 8 | 9 | [Parameter(Mandatory)] 10 | [System.Management.Automation.PSCredential]$AdminCreds, 11 | 12 | [Parameter(Mandatory)] 13 | [String]$DCIPAddress, 14 | 15 | [Parameter(Mandatory)] 16 | [String]$JoinOU 17 | ) 18 | 19 | Import-DscResource -ModuleName NetworkingDsc, ActiveDirectoryDsc, xPSDesiredStateConfiguration, ComputerManagementDsc 20 | 21 | [String] $DomainNetbiosName = (Get-NetBIOSName -DomainFQDN $DomainFQDN) 22 | [System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainNetbiosName}\$($Admincreds.UserName)", $Admincreds.Password) 23 | 24 | $Interface = Get-NetAdapter | Where-Object Name -Like "Ethernet*" | Select-Object -First 1 25 | $InterfaceAlias = $($Interface.Name) 26 | $ComputerName = Get-Content env:computername 27 | 28 | Node localhost 29 | { 30 | LocalConfigurationManager 31 | { 32 | ConfigurationMode = 'ApplyOnly' 33 | RebootNodeIfNeeded = $true 34 | } 35 | 36 | DnsServerAddress SetDNS 37 | { 38 | Address = $DCIPAddress 39 | InterfaceAlias = $InterfaceAlias 40 | AddressFamily = 'IPv4' 41 | } 42 | 43 | # ***** Join Domain ***** 44 | WaitForADDomain WaitForDCReady 45 | { 46 | DomainName = $DomainFQDN 47 | WaitTimeout = 300 48 | RestartCount = 3 49 | Credential = $DomainCreds 50 | DependsOn = "[DnsServerAddress]SetDNS" 51 | } 52 | 53 | Computer JoinDomain 54 | { 55 | Name = $ComputerName 56 | DomainName = $DomainFQDN 57 | Credential = $DomainCreds 58 | JoinOU = $JoinOU 59 | DependsOn = "[WaitForADDomain]WaitForDCReady" 60 | } 61 | 62 | PendingReboot RebootAfterJoiningDomain 63 | { 64 | Name = "RebootServer" 65 | DependsOn = "[Computer]JoinDomain" 66 | } 67 | } 68 | } 69 | 70 | function Get-NetBIOSName { 71 | [OutputType([string])] 72 | param( 73 | [string]$DomainFQDN 74 | ) 75 | 76 | if ($DomainFQDN.Contains('.')) { 77 | $length = $DomainFQDN.IndexOf('.') 78 | if ( $length -ge 16) { 79 | $length = 15 80 | } 81 | return $DomainFQDN.Substring(0, $length) 82 | } 83 | else { 84 | if ($DomainFQDN.Length -gt 15) { 85 | return $DomainFQDN.Substring(0, 15) 86 | } 87 | else { 88 | return $DomainFQDN 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /Deploy-AD/resources/APT1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/APT1.jpg -------------------------------------------------------------------------------- /Deploy-AD/resources/CheckContext.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [string]$HostName 3 | ) 4 | 5 | # Check if running as Administrator 6 | $adminCheck = [System.Security.Principal.WindowsIdentity]::GetCurrent() 7 | $isAdmin = (New-Object System.Security.Principal.WindowsPrincipal $adminCheck).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) 8 | 9 | if (-not $isAdmin) { 10 | Write-Host "`n`nWARN: This script must be run as an Administrator. Exiting...`n`n" 11 | pause 12 | Stop-Process -Id $PID 13 | } 14 | 15 | 16 | if (-not $HostName) { 17 | Write-Host "No hostname provided. Exiting..." 18 | exit 19 | } 20 | 21 | if ($env:COMPUTERNAME -ne $HostName) { 22 | Write-Host "`n`nWARN: Wrong system. Expected: $HostName, Found: $env:COMPUTERNAME. Exiting...`n`n" 23 | pause 24 | Stop-Process -Id $PID 25 | } 26 | 27 | if ($env:USERNAME -ne "DOADMIN" -or $env:USERDOMAIN -ne "DOAZLAB") { 28 | Write-Host "`n`nWARN: Wrong user. Expected: DOAZLAB\DOADMIN, Found: $env:USERDOMAIN\$env:USERNAME. Exiting...`n`n" 29 | pause 30 | Stop-Process -Id $PID 31 | } 32 | 33 | Write-Host "`n`nINFO: Running on correct system: $env:COMPUTERNAME as $env:USERDOMAIN\$env:USERNAME with Administrator privileges.`n`n" 34 | -------------------------------------------------------------------------------- /Deploy-AD/resources/DOLAB.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/DOLAB.gif -------------------------------------------------------------------------------- /Deploy-AD/resources/ca_templates/DOAZLab_Computer.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/ca_templates/DOAZLab_Computer.json -------------------------------------------------------------------------------- /Deploy-AD/resources/ca_templates/DOAZLab_IPSec.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/ca_templates/DOAZLab_IPSec.json -------------------------------------------------------------------------------- /Deploy-AD/resources/ca_templates/DOAZLab_User.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/ca_templates/DOAZLab_User.json -------------------------------------------------------------------------------- /Deploy-AD/resources/ca_templates/vuln_template1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Vuln_Template", 3 | "displayName": "Vuln_Template", 4 | "objectClass": "pKICertificateTemplate", 5 | "flags": 131616, 6 | "revision": 100, 7 | "msPKI-Cert-Template-OID": "1.3.6.1.4.1.311.21.8.13682224.6469329.2444437.2343860.7697072.157.13380065.16765499", 8 | "msPKI-Certificate-Application-Policy": [ 9 | "1.3.6.1.5.5.7.3.2" 10 | ], 11 | "msPKI-Certificate-Name-Flag": 1, 12 | "msPKI-Enrollment-Flag": 0, 13 | "msPKI-Minimal-Key-Size": 2048, 14 | "msPKI-Private-Key-Flag": 16842752, 15 | "msPKI-RA-Signature": 0, 16 | "msPKI-Template-Minor-Revision": 2, 17 | "msPKI-Template-Schema-Version": 2, 18 | "pKICriticalExtensions": [ 19 | "2.5.29.7", 20 | "2.5.29.15" 21 | ], 22 | "pKIDefaultCSPs": [ 23 | "2,Microsoft Base Cryptographic Provider v1.0", 24 | "1,Microsoft Enhanced Cryptographic Provider v1.0" 25 | ], 26 | "pKIDefaultKeySpec": 2, 27 | "pKIExpirationPeriod": [ 28 | 0, 29 | 64, 30 | 57, 31 | 135, 32 | 46, 33 | 225, 34 | 254, 35 | 255 36 | ], 37 | "pKIExtendedKeyUsage": [ 38 | "1.3.6.1.5.5.7.3.2" 39 | ], 40 | "pKIKeyUsage": [ 41 | 128, 42 | 0 43 | ], 44 | "pKIMaxIssuingDepth": 0, 45 | "pKIOverlapPeriod": [ 46 | 0, 47 | 128, 48 | 166, 49 | 10, 50 | 255, 51 | 222, 52 | 255, 53 | 255 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /Deploy-AD/resources/ca_templates/vuln_template4.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuln_template4", 3 | "displayName": "vuln_template4", 4 | "objectClass": "pKICertificateTemplate", 5 | "flags": 131616, 6 | "revision": 100, 7 | "msPKI-Cert-Template-OID": "1.3.6.1.4.1.311.21.8.13682224.6469329.2444437.2343860.7697072.157.6696823.10934246", 8 | "msPKI-Certificate-Application-Policy": [ 9 | "1.3.6.1.5.5.7.3.2", 10 | "2.5.29.37.0" 11 | ], 12 | "msPKI-Certificate-Name-Flag": 1, 13 | "msPKI-Enrollment-Flag": 8, 14 | "msPKI-Minimal-Key-Size": 2048, 15 | "msPKI-Private-Key-Flag": 16842768, 16 | "msPKI-RA-Signature": 0, 17 | "msPKI-Template-Minor-Revision": 5, 18 | "msPKI-Template-Schema-Version": 2, 19 | "pKICriticalExtensions": [ 20 | "2.5.29.7", 21 | "2.5.29.15" 22 | ], 23 | "pKIDefaultCSPs": [ 24 | "2,Microsoft Base Cryptographic Provider v1.0", 25 | "1,Microsoft Enhanced Cryptographic Provider v1.0" 26 | ], 27 | "pKIDefaultKeySpec": 2, 28 | "pKIExpirationPeriod": [ 29 | 0, 30 | 128, 31 | 60, 32 | 72, 33 | 209, 34 | 203, 35 | 244, 36 | 255 37 | ], 38 | "pKIExtendedKeyUsage": [ 39 | "1.3.6.1.5.5.7.3.2", 40 | "2.5.29.37.0" 41 | ], 42 | "pKIKeyUsage": [ 43 | 128, 44 | 0 45 | ], 46 | "pKIMaxIssuingDepth": 0, 47 | "pKIOverlapPeriod": [ 48 | 0, 49 | 128, 50 | 166, 51 | 10, 52 | 255, 53 | 222, 54 | 255, 55 | 255 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /Deploy-AD/resources/doazlab_gpos.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/doazlab_gpos.zip -------------------------------------------------------------------------------- /Deploy-AD/resources/dolabs.bgi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/resources/dolabs.bgi -------------------------------------------------------------------------------- /Deploy-AD/resources/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Add-Browsers.ps1: -------------------------------------------------------------------------------- 1 | 2 | #setup directory 3 | $workdir = "C:\doazlab" 4 | if (-Not (Test-Path -Path $workdir)) { 5 | New-Item -Path $workdir -ItemType Directory | Out-Null 6 | } 7 | 8 | ## Add FF) 9 | $workdir = "c:\doazlab\" 10 | $source = "https://download.mozilla.org/?product=firefox-latest&os=win64&lang=en-US" 11 | $destination = "$workdir\firefox.exe" 12 | Invoke-WebRequest $source -OutFile $destination 13 | Start-Process -FilePath "$workdir\firefox.exe" -ArgumentList "/S" 14 | Start-Sleep -s 35 15 | 16 | #setup directory 17 | $workdir = "C:\doazlab" 18 | if (-Not (Test-Path -Path $workdir)) { 19 | New-Item -Path $workdir -ItemType Directory | Out-Null 20 | } 21 | 22 | ## Add Chrome 23 | $workdir = "c:\doazlab\" 24 | $source = "http://dl.google.com/chrome/install/375.126/chrome_installer.exe" 25 | $destination = "$workdir\ChromeInstaller.exe" 26 | Invoke-WebRequest $source -OutFile $destination 27 | Start-Process -FilePath "$workdir\ChromeInstaller.exe" -ArgumentList " /silent /install" 28 | 29 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Add-DoazLabGPOs.ps1: -------------------------------------------------------------------------------- 1 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 2 | $workdir = "C:\doazlab" 3 | if (-Not (Test-Path -Path $workdir)) { 4 | New-Item -Path $workdir -ItemType Directory | Out-Null 5 | } 6 | mkdir c:\doaz 7 | mkdir c:\doaz\gpo 8 | cd c:\doaz\gpo 9 | Invoke-WebRequest -URI https://github.com/DefensiveOrigins/DO-LAB/raw/main/Deploy-AD/resources/doazlab_gpos.zip -Outfile doazlab_gpos.zip 10 | Expand-Archive .\doazlab_gpos.zip 11 | Remove-Item doazlab_gpos.zip 12 | New-GPO "doaz-labsettings" 13 | Import-GPO -BackupGpoName "doaz-labsettings" -TargetName "doaz-labsettings" -Path c:\doaz\gpo\doazlab_gpos 14 | New-GPLink -Name "doaz-labsettings" -Target "dc=doazlab,dc=com" -LinkEnabled Yes 15 | cd c:\doaz\gpo 16 | Invoke-WebRequest -URI https://github.com/DefensiveOrigins/DO-LAB/raw/main/Deploy-AD/resources/layout.xml -Outfile layout.xml 17 | Copy-Item c:\doaz\gpo\layout.xml -Destination C:\SYSVOL\sysvol\doazlab.com\scripts\layout.xml 18 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Add-Shortcuts.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## ADD POWERSHELL DESKTOP ICON(ADMIN MODE) 4 | $ShortcutPath = "C:\Users\Public\Desktop\PowerShell (Admin).lnk" 5 | $PowerShellPath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" 6 | $WScriptShell = New-Object -ComObject WScript.Shell 7 | $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) 8 | $Shortcut.TargetPath = $PowerShellPath 9 | $Shortcut.Arguments = "-Command Start-Process PowerShell -Verb RunAs" 10 | $Shortcut.IconLocation = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe,0" 11 | $Shortcut.Save() 12 | Write-Host "Shortcut created successfully: $ShortcutPath" 13 | 14 | 15 | ## ADD EVENTLOG DESKTOP ICON(ADMIN MODE) 16 | $ShortcutPath = "C:\Users\Public\Desktop\Event Viewer.lnk" 17 | $EventViewerPath = "$env:SystemRoot\System32\eventvwr.msc" 18 | $WScriptShell = New-Object -ComObject WScript.Shell 19 | $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) 20 | $Shortcut.TargetPath = $EventViewerPath 21 | $Shortcut.IconLocation = "$env:SystemRoot\System32\eventvwr.msc,0" 22 | $Shortcut.Save() 23 | Write-Host "Shortcut created successfully: $ShortcutPath" 24 | 25 | ## ADD ICON FOR ADUC 26 | $ShortcutPath = "C:\Users\Public\Desktop\Active Directory Users and Computers.lnk" 27 | $TargetPath = "C:\Windows\System32\dsa.msc" 28 | $WScriptShell = New-Object -ComObject WScript.Shell 29 | $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) 30 | $Shortcut.TargetPath = $TargetPath 31 | $Shortcut.WorkingDirectory = "C:\Windows\System32" 32 | $Shortcut.Description = "Shortcut to Active Directory Users and Computers" 33 | $Shortcut.IconLocation = "C:\Windows\System32\dsa.msc,0" 34 | $Shortcut.Save() 35 | Write-Host "Shortcut to ADUC created on Public Desktop successfully." 36 | 37 | ### ADD ICON OR SSH 38 | $DesktopPath = "C:\Users\Public\Desktop\" 39 | $ShortcutPath = "$DesktopPath\SSH-to-C2.lnk" 40 | $sshCommand = "ssh doadmin@10.0.0.8 -i c:\ProgramData\DOAZLab\id_rsa" 41 | $WScriptShell = New-Object -ComObject WScript.Shell 42 | $Shortcut = $WScriptShell.CreateShortcut($ShortcutPath) 43 | $Shortcut.TargetPath = "cmd.exe" 44 | $Shortcut.Arguments = "/k $sshCommand" 45 | $Shortcut.WorkingDirectory = $DesktopPath 46 | $Shortcut.WindowStyle = 1 47 | $Shortcut.Description = "SSH to C2" 48 | $Shortcut.Save() 49 | Write-Host "Shortcut created at: $ShortcutPath" 50 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Enable-PowerShell-Logging.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez (@Cyb3rWard0g) 2 | # License: GPL-3.0 3 | 4 | # Enable PowerShell Logging 5 | $regConfig = @" 6 | regKey,name,value,type 7 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging","EnableScriptBlockLogging",1,"DWORD" 8 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging","EnableScriptBlockInvocationLogging",1,"DWORD" 9 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging","EnableModuleLogging",1,"DWORD" 10 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames",*,*,"String" 11 | "@ 12 | 13 | Write-host "Setting up PowerShell registry settings.." 14 | $regConfig | ConvertFrom-Csv | ForEach-Object { 15 | if(!(Test-Path $_.regKey)){ 16 | Write-Host $_.regKey " does not exist.." 17 | New-Item $_.regKey -Force 18 | } 19 | Write-Host "Setting " $_.regKey 20 | New-ItemProperty -Path $_.regKey -Name $_.name -Value $_.value -PropertyType $_.type -force 21 | } -------------------------------------------------------------------------------- /Deploy-AD/scripts/Enable-WinAuditCategories.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez (@Cyb3rWard0g) 2 | # License: GPL-3.0 3 | 4 | [CmdletBinding()] 5 | param ( 6 | [Parameter(Mandatory=$false)] 7 | [switch]$SetDC 8 | ) 9 | 10 | # Enabling Audit Policies 11 | write-Host "Enabling Sub-categories .." 12 | 13 | Write-host "Enabling Audit System Sub-Categories" 14 | # Not auditing: IPsec Driver 15 | & auditpol.exe /set /subcategory:"Security System Extension","System Integrity","Other System Events","Security State Change" /success:enable /failure:enable 16 | 17 | Write-host "Enabling Audit Logon/Logoff Sub-Categories" 18 | # Not auditing: IPsec Main Mode, IPsec Quick Mode, IPsec Extended Mode, Network Policy Server, "User / Device Claims" 19 | & auditpol.exe /set /subcategory:"Logon","Logoff","Account Lockout","Special Logon","Other Logon/Logoff Events","Group Membership" /success:enable /failure:enable 20 | 21 | Write-host "Enabling Audit Object Access Sub-Categories" 22 | # Not auditing: Application Generated, Filtering Platform Packet Drop 23 | & auditpol.exe /set /subcategory:"File System","Registry","Kernel Object","SAM","Certification Services","Handle Manipulation","File Share","Filtering Platform Connection","Other Object Access Events","Detailed File Share","Removable Storage","Central Policy Staging" /success:enable /failure:enable 24 | 25 | Write-host "Enabling Audit Privilege Use Sub-Categories" 26 | # Not auditing: 27 | & auditpol.exe /set /subcategory:"Non Sensitive Privilege Use","Other Privilege Use Events","Sensitive Privilege Use" /success:enable /failure:enable 28 | 29 | Write-host "Enabling Audit Detailed Tracking Sub-Categories" 30 | # Not auditing: 31 | & auditpol.exe /set /subcategory:"Process Creation","Process Termination","DPAPI Activity","RPC Events","Plug and Play Events","Token Right Adjusted Events" /success:enable /failure:enable 32 | 33 | Write-host "Enabling Audit Policy Change Sub-Categories" 34 | # Not auditing: 35 | & auditpol.exe /set /subcategory:"Audit Policy Change","Authentication Policy Change","Authorization Policy Change","MPSSVC Rule-Level Policy Change","Filtering Platform Policy Change","Other Policy Change Events" /success:enable /failure:enable 36 | 37 | Write-host "Enabling Audit Account Management Sub-Categories" 38 | # Not auditing: 39 | & auditpol.exe /set /subcategory:"Computer Account Management","Security Group Management","Distribution Group Management","Application Group Management","Other Account Management Events","User Account Management" /success:enable /failure:enable 40 | 41 | Write-host "Enabling Audit Account Logon Sub-Categories" 42 | # Not auditing: Kerberos Service Ticket Operations, Kerberos Authentication Service 43 | & auditpol.exe /set /subcategory:"Other Account Logon Events","Credential Validation" /success:enable /failure:enable 44 | 45 | if ($SetDC) 46 | { 47 | Write-host "Enabling Audit DS Access Sub-Categories" 48 | # Not auditing: 49 | & auditpol.exe /set /subcategory:"Directory Service Access","Directory Service Changes","Directory Service Replication","Detailed Directory Service Replication" /success:enable /failure:enable 50 | 51 | Write-host "Enabling Audit Account Logon Sub-Categories" 52 | # Not auditing: 53 | & auditpol.exe /set /subcategory:"Kerberos Service Ticket Operations","Other Account Logon Events","Kerberos Authentication Service","Credential Validation" /success:enable /failure:enable 54 | } 55 | 56 | $regConfig = @" 57 | regKey,name,value,type 58 | "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa","scenoapplylegacyauditpolicy",1,"DWord" 59 | "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit","ProcessCreationIncludeCmdLine_Enabled",1,"DWord" 60 | "@ 61 | 62 | Write-host "Setting up Registry keys for additional auditing settings.." 63 | $regConfig | ConvertFrom-Csv | ForEach-Object { 64 | if(!(Test-Path $_.regKey)){ 65 | Write-Host $_.regKey " does not exist.." 66 | New-Item $_.regKey -Force 67 | } 68 | Write-Host "Setting " $_.regKey 69 | New-ItemProperty -Path $_.regKey -Name $_.name -Value $_.value -PropertyType $_.type -force 70 | } -------------------------------------------------------------------------------- /Deploy-AD/scripts/Install-DSC-Modules.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 5 2 | 3 | [CmdletBinding()] 4 | param ( 5 | [Parameter(Mandatory)] 6 | [ValidateSet("DC",'Endpoint')] 7 | [string]$SetupType 8 | 9 | ) 10 | Set-ExecutionPolicy Unrestricted -Force 11 | 12 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 13 | 14 | Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force 15 | Set-PSRepository -Name PSGallery -InstallationPolicy Trusted 16 | 17 | Install-Module -Name ActiveDirectoryDsc -RequiredVersion 6.0.1 18 | Install-Module -Name NetworkingDsc -RequiredVersion 8.2.0 19 | Install-Module -Name xPSDesiredStateConfiguration -RequiredVersion 9.1.0 20 | Install-Module -Name ComputerManagementDsc -RequiredVersion 8.4.0 21 | 22 | if ($SetupType -ne 'Endpoint') 23 | { 24 | Install-Module -Name xDnsServer -RequiredVersion 1.16.0.0 25 | } -------------------------------------------------------------------------------- /Deploy-AD/scripts/Prepare-Box.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez (@Cyb3rWard0g) 2 | # License: GPL-3.0 3 | 4 | $ErrorActionPreference = "Stop" 5 | 6 | # Network Changes 7 | Write-host 'Setting network connection type to Private..' 8 | Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private 9 | 10 | # Stop Windows Update 11 | Write-Host "Disabling Windows Updates.." 12 | Set-Service wuauserv -StartupType Disabled 13 | Stop-Service wuauserv 14 | 15 | # Firewall Changes 16 | Write-Host "Allow ICMP Traffic through firewall" 17 | & netsh advfirewall firewall add rule name="ALL ICMP V4" protocol=icmpv4:any,any dir=in action=allow 18 | 19 | Write-Host "Enable WMI traffic through firewall" 20 | & netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes 21 | 22 | Write-Host "Enable Inbound RPC Dynamic Ports" 23 | # Reference: 24 | # https://serverfault.com/questions/430705/how-do-i-allow-remote-iisreset-through-the-firewall-on-win-server-2008 25 | # https://stackoverflow.com/questions/21092050/comexception-when-trying-to-get-application-pools-using-servermanager 26 | # Local port: Dynamic RPC 27 | # Remote port: ALL 28 | # Protocol number: 6 29 | # Executable: %windir%\\system32\\dllhost.exe 30 | # Remote privilege: Administrator 31 | & netsh advfirewall firewall add rule name="COM+ Remote Administration (All Programs)" dir=in action=allow description="" program="$Env:WinDir\system32\dllhost.exe" enable=yes localport=RPC protocol=tcp 32 | 33 | Write-Host "Enable Explorer.exe Inbound (i.e. COM Method ShellWindows)" 34 | & netsh advfirewall firewall add rule name="Windows Explorer UDP" dir=in action=allow description="" program="$Env:WinDir\explorer.exe" enable=yes localport=any protocol=udp remoteip=localsubnet 35 | & netsh advfirewall firewall add rule name="Windows Explorer TCP" dir=in action=allow description="" program="$Env:WinDir\explorer.exe" enable=yes localport=any protocol=tcp remoteip=localsubnet 36 | 37 | ## Configured firewall to allow SMB 38 | Write-Host "Enable File and Printer Sharing" 39 | & netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=Yes 40 | 41 | # Power Settings 42 | Write-Host "Setting Power Performance" 43 | $HPGuid = (Get-WmiObject -Class win32_powerplan -Namespace root\cimv2\power -Filter "ElementName='High performance'").InstanceID.tostring() 44 | $regex = [regex]"{(.*?)}$" 45 | $PowerConfig = $regex.Match($HPGuid).groups[1].value 46 | & powercfg -S $PowerConfig 47 | # Idle timeouts 48 | powercfg.exe -x -monitor-timeout-ac 0 49 | powercfg.exe -x -monitor-timeout-dc 0 50 | powercfg.exe -x -disk-timeout-ac 0 51 | powercfg.exe -x -disk-timeout-dc 0 52 | powercfg.exe -x -standby-timeout-ac 0 53 | powercfg.exe -x -standby-timeout-dc 0 54 | powercfg.exe -x -hibernate-timeout-ac 0 55 | powercfg.exe -x -hibernate-timeout-dc 0 56 | 57 | # Disable Hibernation 58 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Power\ -name HiberFileSizePercent -value 0 59 | Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Power\ -name HibernateEnabled -value 0 60 | 61 | # Set TimeZone 62 | Write-host "Setting Time Zone to Eastern Standard Time" 63 | Set-TimeZone -Name "Eastern Standard Time" 64 | 65 | # Removing OneDrive 66 | Write-Host "Removing OneDrive..." 67 | $onedrive = Get-Process onedrive -ErrorAction SilentlyContinue 68 | if ($onedrive) { 69 | taskkill /f /im OneDrive.exe 70 | } 71 | if (Test-Path "$env:systemroot\SysWOW64\OneDriveSetup.exe") { 72 | & $env:systemroot\SysWOW64\OneDriveSetup.exe /uninstall /q 73 | if (!(Test-Path HKCR:)) 74 | { 75 | New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT 76 | } 77 | if (Test-Path "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}") { 78 | Remove-Item -Force -Path "HKCR:\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" 79 | } 80 | if (Test-Path "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}") { 81 | Remove-Item -Force -Path "HKCR:\Wow6432Node\CLSID\{018D5C66-4533-4307-9B53-224DE2ED1FE6}" 82 | } 83 | } 84 | 85 | # Disabling A few Windows 10 Settings: 86 | # Reference: 87 | # https://docs.microsoft.com/en-us/windows/privacy/manage-connections-from-windows-operating-system-components-to-microsoft-services 88 | 89 | $regConfig = @" 90 | regKey,name,value,type 91 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OOBE","DisablePrivacyExperience",1,"DWord" 92 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search","AllowCortana",0,"DWord" 93 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search","AllowSearchToUseLocation",0,"DWord" 94 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search","DisableWebSearch",1,"DWord" 95 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search","ConnectedSearchUseWeb",0,"DWord" 96 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata","PreventDeviceMetadataFromNetwork",1,"DWord" 97 | "HKLM:\SOFTWARE\Policies\Microsoft\FindMyDevice","AllowFindMyDevice",0,"DWord" 98 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PreviewBuilds","AllowBuildPreview",0,"DWord" 99 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Suggested Sites","Enabled",0,"DWord" 100 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer","AllowServicePoweredQSA",0,"DWord" 101 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Explorer\AutoComplete","AutoSuggest","no","String" 102 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Geolocation","PolicyDisableGeolocation",1,"DWord" 103 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\PhishingFilter","EnabledV9",0,"DWord" 104 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\BrowserEmulation","DisableSiteListEditing",1,"DWord" 105 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\FlipAhead","Enabled",0,"DWord" 106 | "HKLM:\SOFTWARE\Policies\Microsoft\Internet Explorer\Feeds","BackgroundSyncStatus",0,"DWord" 107 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer","AllowOnlineTips",0,"DWord" 108 | "HKCU:\SOFTWARE\Microsoft\Internet Explorer\Main","Start Page","about:blank","String" 109 | "HKCU:\SOFTWARE\Microsoft\Internet Explorer\Control Panel","HomePage",1,"DWord" 110 | "HKCU:\SOFTWARE\Policies\Microsoft\Internet Explorer\Main","DisableFirstRunCustomize",1,"DWord" 111 | "HKLM:\SYSTEM\CurrentControlSet\Services\LicenseManager","Start",4,"DWord" 112 | "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main","PreventFirstRunPage",1,"DWord" 113 | "HKLM:\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main","AllowPrelaunch", 0, "Dword" 114 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications","NoCloudApplicationNotification",1,"DWord" 115 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\OneDrive","DisableFileSyncNGSC",1,"DWord" 116 | "HKLM:\SOFTWARE\Microsoft\OneDrive","PreventNetworkTrafficPreUserSignIn",1,"DWord" 117 | "HKCU:\SOFTWARE\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy","HasAccepted",0,"DWord" 118 | "HKLM:\SOFTWARE\Policies\Microsoft\Speech","AllowSpeechModelUpdate",0,"DWord" 119 | "HKCU:\SOFTWARE\Microsoft\InputPersonalization","RestrictImplicitTextCollection",1,"DWord" 120 | "HKCU:\SOFTWARE\Microsoft\InputPersonalization","RestrictImplicitInkCollection",1,"DWord" 121 | "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo","Enabled",0,"DWord" 122 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo","DisabledByGroupPolicy",1,"DWord" 123 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AppPrivacy","LetAppsAccessLocation",2,"DWord" 124 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors","DisableLocation",1,"DWord" 125 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection","DoNotShowFeedbackNotifications",1,"DWord" 126 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection","AllowTelemetry",0,"DWord" 127 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent","DisableWindowsConsumerFeatures",1,"DWord" 128 | "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent","DisableTailoredExperiencesWithDiagnosticData",1,"DWord" 129 | "HKLM:\SOFTWARE\Policies\Policies\Microsoft\Windows\System","EnableSmartScreen",0,"DWord" 130 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen","ConfigureAppInstallControlEnabled",1,"DWord" 131 | "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\SmartScreen","ConfigureAppInstallControl","Anywhere","String" 132 | "@ 133 | 134 | Write-host "Setting up Registry keys for additional settings.." 135 | $regConfig | ConvertFrom-Csv | ForEach-Object { 136 | if(!(Test-Path $_.regKey)){ 137 | Write-Host $_.regKey " does not exist.." 138 | New-Item $_.regKey -Force 139 | } 140 | Write-Host "Setting " $_.regKey 141 | New-ItemProperty -Path $_.regKey -Name $_.name -Value $_.value -PropertyType $_.type -force 142 | } 143 | 144 | # Additional registry configurations 145 | # References: 146 | # https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level 147 | # https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-restrict-ntlm-outgoing-ntlm-traffic-to-remote-servers 148 | # https://github.com/eladshamir/Internal-Monologue/blob/85134e4ebe5ea9e7f6b39d4b4ad467e40a0c9eca/InternalMonologue/InternalMonologue.cs 149 | 150 | $regConfig = @" 151 | regKey,name,value,type 152 | "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa","LmCompatibilityLevel",2,"DWord" 153 | "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0","NTLMMinClientSec",536870912,"DWord" 154 | "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0","RestrictSendingNTLMTraffic",0,"DWord" 155 | "@ 156 | 157 | Write-host "Setting up Registry keys for additional settings.." 158 | $regConfig | ConvertFrom-Csv | ForEach-Object { 159 | if(!(Test-Path $_.regKey)){ 160 | Write-Host $_.regKey " does not exist.." 161 | New-Item $_.regKey -Force 162 | } 163 | Write-Host "Setting " $_.regKey 164 | New-ItemProperty -Path $_.regKey -Name $_.name -Value $_.value -PropertyType $_.type -force 165 | } 166 | 167 | # Set up PSRemoting 168 | $ServiceName = 'WinRM' 169 | $arrService = Get-Service -Name $ServiceName 170 | 171 | if ($arrService.Status -eq 'Running') 172 | { 173 | Write-Host "$ServiceName Service is now Running" 174 | } 175 | else 176 | { 177 | Write-host 'Enabling WinRM..' 178 | winrm quickconfig -q 179 | write-Host "Setting WinRM to start automatically.." 180 | & sc.exe config WinRM start= auto 181 | } 182 | 183 | # Enable Remote Registry Service 184 | $ServiceName = 'remoteregistry' 185 | $arrService = Get-Service -Name $ServiceName 186 | 187 | if ($arrService.Status -eq 'Running') 188 | { 189 | Write-Host "$ServiceName Service is now Running" 190 | } 191 | else 192 | { 193 | Write-host 'Enabling Remote Registry..' 194 | & sc start remoteregistry 195 | write-Host "Setting Remote Registry to start automatically.." 196 | & sc.exe config remoteregistry start= auto 197 | } 198 | 199 | # Setting UAC level to Never Notify 200 | Write-Host "Setting UAC level to Never Notify.." 201 | Set-ItemProperty -Force -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 0 202 | 203 | # *** Registry modified to allow storage of wdigest credentials *** 204 | Write-Host "Setting WDigest to use logoncredential.." 205 | Set-ItemProperty -Force -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest" -Name "UseLogonCredential" -Value "1" 206 | 207 | # RDP enabled for all Windows hosts 208 | # Adding Authenticated Users to Remote Desktop Users 209 | write-Host "Adding Authenticated Users to Remote Desktop Users.." 210 | Add-LocalGroupMember -Group "Remote Desktop Users" -Member "Authenticated Users" -ErrorAction SilentlyContinue 211 | Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -name "fDenyTSConnections" -value 0 212 | Enable-NetFirewallRule -DisplayGroup "Remote Desktop" 213 | 214 | # Skip SmartScreen 215 | New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "Off" -PropertyType String -Force 216 | 217 | # Disable first logon animation 218 | New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name EnableFirstLogonAnimation -Value 0 -PropertyType DWord -Force 219 | 220 | # Set Detailed Logon Messages 221 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "VerboseStatus" -Type DWord -Value 1 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-AuditRule.ps1: -------------------------------------------------------------------------------- 1 | function Set-AuditRule 2 | { 3 | <# 4 | .SYNOPSIS 5 | 6 | Sets an access control entry (ACE) on a system access control list (SACL) of a file, registry or ad object security descriptor. 7 | 8 | .PARAMETER RegistryPath 9 | 10 | Path of the registry securable object 11 | 12 | .PARAMETER FilePath 13 | 14 | Path of the file securable object 15 | 16 | .PARAMETER AdObjectPath 17 | 18 | Path of the Ad securable object 19 | 20 | .PARAMETER WellKnownSidType 21 | 22 | Commonly used Security Identifier. We leverage the parameter attribute called ArgumentCompleter to add tab completion values. 23 | These values are obtained from the System.Security.Principal.WellKnownSidType enum. 24 | Examples: 25 | - WorldSid -> Indicates a SID that matches everyone. 26 | - NetworkSid -> Indicates a SID for a network account. This SID is added to the process of a token when it logs on across a network. 27 | - BuiltinAdministratorsSid -> Indicates a SID that matches the administrator account. 28 | - AccountDomainAdminsSid -> Indicates a SID that matches the account domain administrator group. 29 | - AccountDomainUsersSid -> Indicates a SID that matches the account domain users group. 30 | 31 | .PARAMETER Rights 32 | 33 | Specifies the types of access attempts to monitor. Access control rights that can be applied to a registry, file or ad objects. 34 | These values are served dynamically from the following Enums: System.Security.AccessControl.RegistryRights, System.Security.AccessControl.FileSystemRights and System.DirectoryServices.ActiveDirectoryRights. 35 | 36 | .PARAMETER InheritanceFlag 37 | 38 | Inheritance flags specify the semantics of inheritance for access control entries (ACEs). 39 | These values are served dynamically from the following Enums: System.DirectoryServices.ActiveDirectorySecurityInheritance and System.Security.AccessControl.InheritanceFlags. 40 | 41 | .PARAMETER PropagationFlags 42 | 43 | Specifies how Access Control Entries (ACEs) are propagated to child objects. These flags are significant only if inheritance flags are present. 44 | These values are serverd dynamically from the following Enum: System.Security.AccessControl.PropagationFlags. 45 | 46 | .PARAMETER AuditFlags 47 | 48 | Specifies the conditions for auditing attempts to access a securable object. Success or Failure. 49 | These values are served dynamically from the following Enum: System.Security.AccessControl.AuditFlags. 50 | 51 | .NOTES 52 | 53 | Author: Roberto Rodriguez (@Cyb3rWard0g) 54 | License: GPL-3.0 55 | 56 | Reference: 57 | - @adbertram - https://www.enowsoftware.com/solutions-engine/bid/185867/Powershell-Upping-your-Parameter-Validation-Game-with-Dynamic-Parameters-Part-II 58 | - https://social.technet.microsoft.com/Forums/ie/en-US/b012f66e-08d1-46d2-b659-6ee004e721c0/powershell-to-set-sacl-on-files?forum=ITCG 59 | - http://giuoco.org/security/configure-file-and-registry-auditing-with-powershell/ 60 | - https://medium.com/@cryps1s/detecting-windows-endpoint-compromise-with-sacls-cd748e10950 61 | - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7.1#argumentcompleter-attribute 62 | - https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.wellknownsidtype?view=net-5.0 63 | - https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings 64 | 65 | .EXAMPLE 66 | 67 | PS > Get-Acl -Path HKLM:\SYSTEM\CurrentControlSet\Services\Sysmondrv\Parameters\ -Audit | fl 68 | 69 | Path : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Sysmondrv\Parameters\ 70 | Owner : BUILTIN\Administrators 71 | Group : DESKTOP-WARDOG\None 72 | Access : BUILTIN\Administrators Allow FullControl 73 | .. 74 | ... 75 | Audit : 76 | Sddl : O:BAG:... 77 | 78 | PS > Set-AuditRule -RegistryPath HKLM:\SYSTEM\CurrentControlSet\Services\Sysmondrv\Parameters\ -WellKnownSidType WorldSid -Rights ReadKey,QueryValues -InheritanceFlags None -PropagationFlags None -AuditFlags Success 79 | 80 | PS > Get-Acl -Path HKLM:\SYSTEM\CurrentControlSet\Services\Sysmondrv\Parameters\ -Audit | fl 81 | 82 | Path : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Sysmondrv\Parameters\ 83 | Owner : BUILTIN\Administrators 84 | Group : DESKTOP-WARDOG\None 85 | Access : BUILTIN\Administrators Allow FullControl 86 | .. 87 | ... 88 | Audit : Everyone Success ReadKey 89 | Sddl : O:BAG:...S:AI(AU;SA;KR;;;WD) 90 | 91 | .EXAMPLE 92 | 93 | PS > Get-Acl -Path C:\tools\test.txt -Audit | fl 94 | 95 | Path : Microsoft.PowerShell.Core\FileSystem::C:\tools\test.txt 96 | Owner : RIVENDELL\cbrown 97 | Group : 98 | Access : BUILTIN\Administrators Allow FullControl 99 | NT AUTHORITY\SYSTEM Allow FullControl 100 | BUILTIN\Users Allow ReadAndExecute, Synchronize 101 | NT AUTHORITY\Authenticated Users Allow Modify, Synchronize 102 | Audit : 103 | Sddl : O:S-1-5... 104 | 105 | PS > Set-AuditRule -FilePath C:\tools\test4.txt.txt -WellKnownSidType WorldSid -Rights Read,Modify -InheritanceFlags None -PropagationFlags None -AuditFlags Success 106 | 107 | PS > Get-Acl -Path C:\tools\test.txt -Audit | fl 108 | 109 | Path : Microsoft.PowerShell.Core\FileSystem::C:\tools\test.txt 110 | Owner : RIVENDELL\cbrown 111 | Group : 112 | Access : BUILTIN\Administrators Allow FullControl 113 | NT AUTHORITY\SYSTEM Allow FullControl 114 | BUILTIN\Users Allow ReadAndExecute, Synchronize 115 | NT AUTHORITY\Authenticated Users Allow Modify, Synchronize 116 | Audit : Everyone Success Modify 117 | Sddl : O:S-1-5... S:AI(AU;SA;CCDCLCSWRPWPLOCRSDRC;;;WD) 118 | 119 | .EXAMPLE 120 | 121 | PS > Enter-PSSession MORDORDC -Credential theshire\pgustavo 122 | [MORDORDC]: PS > Import-Module activedirectory 123 | [MORDORDC]: PS > Get-Acl -Path 'AD:\CN=Domain Admins,CN=Users,DC=theshire,DC=local' -Audit | fl 124 | [MORDORDC]: PS > Set-AuditRule -AdObjectPath 'AD:\CN=Domain Admins,CN=Users,DC=theshire,DC=local' -WellKnownSidType WorldSid -Rights GenericRead -InheritanceFlags None -AuditFlags Success 125 | [MORDORDC]: PS > Get-Acl -Path 'AD:\CN=Domain Admins,CN=Users,DC=theshire,DC=local' -Audit | fl 126 | 127 | #> 128 | 129 | [CmdletBinding(DefaultParameterSetName='NoParam')] 130 | param 131 | ( 132 | [Parameter(Position=0,Mandatory=$true,ParameterSetname='RegistryAudit')] 133 | [ValidateScript({Test-Path $_})] 134 | [string]$RegistryPath, 135 | 136 | [Parameter(Position=0,Mandatory=$true,ParameterSetname='FileAudit')] 137 | [ValidateScript({Test-Path $_})] 138 | [string]$FilePath, 139 | 140 | [Parameter(Position=0,Mandatory=$true,ParameterSetname='AdObjectAudit')] 141 | [string]$AdObjectPath, 142 | 143 | [Parameter(Position=1,Mandatory=$true)] 144 | [ArgumentCompleter( { 145 | param ( 146 | $CommandName, 147 | $ParameterName, 148 | $WordToComplete, 149 | $CommandAst, 150 | $FakeBoundParameters 151 | ) 152 | [System.Security.Principal.WellKnownSidType].DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name | Where-object {$_ -like "$wordToComplete*"} 153 | })] 154 | [String]$WellKnownSidType 155 | ) 156 | DynamicParam { 157 | if ($PSCmdlet.ParameterSetName -eq 'AdObjectAudit') 158 | { 159 | $ParamOptions = @( 160 | @{ 161 | 'Name' = 'Rights'; 162 | 'Mandatory' = $true; 163 | 'ValidateSetOptions' = ([System.DirectoryServices.ActiveDirectoryRights]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 164 | }, 165 | @{ 166 | 'Name' = 'InheritanceFlags'; 167 | 'Mandatory' = $true; 168 | 'ValidateSetOptions' = ([System.DirectoryServices.ActiveDirectorySecurityInheritance]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 169 | }, 170 | @{ 171 | 'Name' = 'AuditFlags'; 172 | 'Mandatory' = $true; 173 | 'ValidateSetOptions' = ([System.Security.AccessControl.AuditFlags]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 174 | }, 175 | @{ 176 | 'Name' = 'AttributeGUID'; 177 | 'Mandatory' = $false; 178 | } 179 | ) 180 | 181 | $DomainSidArray = ("AccountAdministratorSid","AccountGuestSid","AccountKrbtgtSid","AccountDomainAdminsSid","AccountDomainUsersSid","AccountDomainGuestsSid","AccountComputersSid","AccountControllersSid","AccountCertAdminsSid","AccountSchemaAdminsSid","AccountEnterpriseAdminsSid","AccountPolicyAdminsSid","AccountRasAndIasServersSid") 182 | if ($DomainSidArray.Contains($WellKnownSidType)) 183 | { 184 | $DomainSidOption = @{ 185 | 'Name' = 'DomainSid'; 186 | 'Mandatory' = $true 187 | } 188 | $ParamOptions = @($DomainSidOption) + $ParamOptions 189 | } 190 | } 191 | else 192 | { 193 | If ($PSCmdlet.ParameterSetName -eq 'RegistryAudit'){$AccessRights = [System.Security.AccessControl.RegistryRights]} 194 | If ($PSCmdlet.ParameterSetName -eq 'FileAudit'){$AccessRights = [System.Security.AccessControl.FileSystemRights]} 195 | $ParamOptions = @( 196 | @{ 197 | 'Name' = 'Rights'; 198 | 'Mandatory' = $true; 199 | 'ValidateSetOptions' = ($AccessRights).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 200 | }, 201 | @{ 202 | 'Name' = 'InheritanceFlags'; 203 | 'Mandatory' = $true; 204 | 'ValidateSetOptions' = ([System.Security.AccessControl.InheritanceFlags]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 205 | }, 206 | @{ 207 | 'Name' = 'PropagationFlags'; 208 | 'Mandatory' = $true; 209 | 'ValidateSetOptions' = ([System.Security.AccessControl.PropagationFlags]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 210 | }, 211 | @{ 212 | 'Name' = 'AuditFlags'; 213 | 'Mandatory' = $true; 214 | 'ValidateSetOptions' = ([System.Security.AccessControl.AuditFlags]).DeclaredMembers | Where-object { $_.IsStatic } | Select-Object -ExpandProperty name 215 | } 216 | ) 217 | } 218 | 219 | $RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary 220 | foreach ($Param in $ParamOptions) { 221 | $RuntimeParam = New-DynamicParam @Param 222 | $RuntimeParamDic.Add($Param.Name, $RuntimeParam) 223 | } 224 | return $RuntimeParamDic 225 | } 226 | 227 | begin { 228 | $PsBoundParameters.GetEnumerator() | ForEach-Object { New-Variable -Name $_.Key -Value $_.Value -ea 'SilentlyContinue'} 229 | } 230 | 231 | process 232 | { 233 | try 234 | { 235 | if ($DomainSid) 236 | { 237 | $IdentityReference = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType]$WellKnownSidType, [System.Security.Principal.SecurityIdentifier]$DomainSid) 238 | } 239 | else 240 | { 241 | $IdentityReference = New-Object System.Security.Principal.SecurityIdentifier([System.Security.Principal.WellKnownSidType] $WellKnownSidType,$Null) 242 | } 243 | if ($PSCmdlet.ParameterSetName -eq 'AdObjectAudit') 244 | { 245 | if ($AttributeGUID) 246 | { 247 | $AuditRuleObject = New-Object System.DirectoryServices.ActiveDirectoryAuditRule($IdentityReference,$Rights,$AuditFlags,[guid]$AttributeGUID, $InheritanceFlags,[guid]'00000000-0000-0000-0000-000000000000') 248 | } 249 | else { 250 | $AuditRuleObject = New-Object System.DirectoryServices.ActiveDirectoryAuditRule($IdentityReference,$Rights,$AuditFlags,[guid]'00000000-0000-0000-0000-000000000000', $InheritanceFlags,[guid]'00000000-0000-0000-0000-000000000000') 251 | 252 | } 253 | $path = $AdObjectPath 254 | } 255 | else 256 | { 257 | If($PSCmdlet.ParameterSetName -eq 'RegistryAudit') 258 | { 259 | $AuditRule = "System.Security.AccessControl.RegistryAuditRule" 260 | $Path = $RegistryPath 261 | } 262 | If($PSCmdlet.ParameterSetName -eq 'FileAudit') 263 | { 264 | $AuditRule = "System.Security.AccessControl.FileSystemAuditRule" 265 | $Path = $FilePath 266 | } 267 | $AuditRuleObject = New-Object $AuditRule($IdentityReference,$Rights,$InheritanceFlags,$PropagationFlags,$AuditFlags) 268 | } 269 | $Acl = Get-Acl $Path -Audit 270 | Write-Verbose "[+] Old ACL: $($Acl | Format-List | Out-String)" 271 | Write-Verbose "[+] Adding ACE to SACL: $($AuditRuleObject | Out-String)" 272 | $Acl.SetAuditRule($AuditRuleObject) 273 | Set-Acl $Path $Acl 274 | Write-Verbose "[+] New ACL: $($Acl | Format-List | Out-String)" 275 | } 276 | catch 277 | { 278 | Write-Error $_.Exception.Message 279 | } 280 | } 281 | } 282 | 283 | function New-DynamicParam { 284 | [CmdletBinding()] 285 | [OutputType('System.Management.Automation.RuntimeDefinedParameter')] 286 | param ( 287 | [Parameter(Mandatory)] 288 | [ValidateNotNullOrEmpty()] 289 | [string]$Name, 290 | [Parameter(Mandatory=$false)] 291 | [array]$ValidateSetOptions, 292 | [Parameter()] 293 | [switch]$Mandatory = $false, 294 | [Parameter()] 295 | [switch]$ValueFromPipeline = $false, 296 | [Parameter()] 297 | [switch]$ValueFromPipelineByPropertyName = $false 298 | ) 299 | 300 | $Attrib = New-Object System.Management.Automation.ParameterAttribute 301 | $Attrib.Mandatory = $Mandatory.IsPresent 302 | $Attrib.ValueFromPipeline = $ValueFromPipeline.IsPresent 303 | $Attrib.ValueFromPipelineByPropertyName = $ValueFromPipelineByPropertyName.IsPresent 304 | 305 | # Create AttributeCollection object for the attribute 306 | $Collection = new-object System.Collections.ObjectModel.Collection[System.Attribute] 307 | # Add our custom attribute 308 | $Collection.Add($Attrib) 309 | # Add Validate Set 310 | if ($ValidateSetOptions) 311 | { 312 | $ValidateSet= new-object System.Management.Automation.ValidateSetAttribute($Param.ValidateSetOptions) 313 | $Collection.Add($ValidateSet) 314 | } 315 | 316 | # Create Runtime Parameter 317 | if ($Param.Name -eq 'Rights' -or $Param.Name -eq 'AuditFlags') 318 | { 319 | $DynParam = New-Object System.Management.Automation.RuntimeDefinedParameter($Param.Name, [array], $Collection) 320 | } 321 | else 322 | { 323 | $DynParam = New-Object System.Management.Automation.RuntimeDefinedParameter($Param.Name, [string], $Collection) 324 | } 325 | $DynParam 326 | } -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-ChromeFRU.ps1: -------------------------------------------------------------------------------- 1 | #Disable first run prompts 2 | # Disable First Run 3 | New-Item -Path "HKLM:\Software\Policies\Google\Chrome" -Force | Out-Null 4 | New-ItemProperty -Path "HKLM:\Software\Policies\Google\Chrome" -Name "SuppressFirstRunDefaultBrowserPrompt" -Value 1 -PropertyType DWord -Force 5 | New-ItemProperty -Path "HKLM:\Software\Policies\Google\Chrome" -Name "FirstRunTabs" -Value "" -PropertyType String -Force 6 | New-ItemProperty -Path "HKLM:\Software\Policies\Google\Chrome" -Name "SigninAllowed" -Value 0 -PropertyType DWord -Force 7 | New-ItemProperty -Path "HKLM:\Software\Policies\Google\Chrome" -Name "MetricsReportingEnabled" -Value 0 -PropertyType DWord -Force 8 | 9 | # mitigate for user based policies 10 | New-Item -Path "HKCU:\Software\Policies\Google\Chrome" -Force | Out-Null 11 | New-ItemProperty -Path "HKCU:\Software\Policies\Google\Chrome" -Name "SuppressFirstRunDefaultBrowserPrompt" -Value 1 -PropertyType DWord -Force 12 | 13 | # elimiante google account sign in prompt 14 | New-ItemProperty -Path "HKLM:\Software\Policies\Google\Chrome" -Name "BrowserSignin" -Value 0 -PropertyType DWord -Force 15 | 16 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-EdgeFRU.ps1: -------------------------------------------------------------------------------- 1 | # Define registry path 2 | $edgeRegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge" 3 | 4 | # Ensure the registry path exists 5 | if (!(Test-Path $edgeRegPath)) { 6 | New-Item -Path $edgeRegPath -Force | Out-Null 7 | } 8 | 9 | # Set the registry keys to disable first run experience 10 | Set-ItemProperty -Path $edgeRegPath -Name "HideFirstRunExperience" -Type DWord -Value 1 11 | Set-ItemProperty -Path $edgeRegPath -Name "PreventFirstRunPage" -Type DWord -Value 1 12 | 13 | ### Define blank tab & fav bar 14 | # Define the registry path for Edge policies 15 | $EdgePolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Edge" 16 | # Ensure the registry path exists 17 | if (-not (Test-Path $EdgePolicyPath)) { 18 | New-Item -Path $EdgePolicyPath -Force | Out-Null 19 | } 20 | # Set the homepage to "about:blank" 21 | Set-ItemProperty -Path $EdgePolicyPath -Name "HomepageLocation" -Value "about:blank" -Type String 22 | # Ensure Edge starts with the homepage (instead of restoring previous tabs) 23 | Set-ItemProperty -Path $EdgePolicyPath -Name "RestoreOnStartup" -Value 4 -Type DWord 24 | # Ensure Edge enforces the homepage setting 25 | Set-ItemProperty -Path $EdgePolicyPath -Name "HomepageIsNewTabPage" -Value 0 -Type DWord 26 | # Force a blank new tab page 27 | Set-ItemProperty -Path $EdgePolicyPath -Name "NewTabPageLocation" -Value "about:blank" -Type String 28 | # Ensure Edge enforces the new tab page setting 29 | Set-ItemProperty -Path $EdgePolicyPath -Name "NewTabPageSetFeedType" -Value 0 -Type DWord 30 | # Hide the Favorites Bar 31 | Set-ItemProperty -Path $EdgePolicyPath -Name "FavoritesBarEnabled" -Value 0 -Type DWord 32 | 33 | Write-Output "Edge homepage, new tab page, and Favorites Bar settings have been applied for all users." 34 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-Initial-Settings.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez (@Cyb3rWard0g) 2 | # License: GPL-3.0 3 | 4 | [CmdletBinding()] 5 | param ( 6 | [Parameter(Mandatory=$false)] 7 | [string]$SetupType 8 | ) 9 | 10 | # Install DSC Modules 11 | & .\Install-DSC-Modules.ps1 -SetupType $SetupType 12 | 13 | # Custom Settings applied 14 | & .\Prepare-Box.ps1 15 | 16 | # Windows Security Audit Categories 17 | if ($SetupType -eq 'DC') 18 | { 19 | & .\Enable-WinAuditCategories.ps1 -SetDC 20 | } 21 | else 22 | { 23 | & .\Enable-WinAuditCategories.ps1 24 | } 25 | 26 | # ADD RSAT 27 | if ($SetupType -eq 'DC') 28 | { 29 | Add-WindowsFeature -Name "RSAT-AD-Tools" -IncludeAllSubFeature 30 | } 31 | else 32 | { 33 | Add-WindowsCapability -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 -Online 34 | } 35 | 36 | # Quiet SM 37 | if ($SetupType -eq 'DC') 38 | { 39 | & .\Set-ServerManager.ps1 40 | } 41 | 42 | 43 | # PowerShell Logging 44 | & .\Enable-PowerShell-Logging.ps1 45 | 46 | # Set SACLs 47 | & .\Set-SACLs.ps1 48 | 49 | # Set Wallpaper 50 | & .\Set-WallPaper.ps1 51 | 52 | # Set Shortcuts 53 | & .\Add-Shortcuts.ps1 54 | 55 | # Add browsers 56 | if ($SetupType -eq 'DC') 57 | { 58 | } 59 | else 60 | { 61 | & .\Add-Browsers.ps1 62 | } 63 | 64 | # Quiet Browsers 65 | & .\Set-EdgeFRU.ps1 66 | & .\Set-ChromeFRU.ps1 67 | 68 | # Remove News/Weather/Ad bar 69 | if ($SetupType -eq 'DC') 70 | { 71 | } 72 | else 73 | { 74 | reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" /v "EnableFeeds" /t REG_DWORD /d 0 /f 75 | Stop-Process -Name explorer -Force 76 | } 77 | 78 | # Add the CheckContext.ps1 Script 79 | New-Item -ItemType Directory -Path "C:\DOAZLab\" -Force > $null 80 | New-Item -ItemType Directory -Path "C:\DOAZLab\Scripts\" -Force > $null 81 | Invoke-WebRequest -Uri "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/refs/heads/main/Deploy-AD/resources/CheckContext.ps1" -OutFile "C:\doazlab\Scripts\CheckContext.ps1" 82 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-SACLs.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/Deploy-AD/scripts/Set-SACLs.ps1 -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-ServerManager.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\ServerManager" -Name "DoNotOpenServerManagerAtLogon" -Value 1 -PropertyType DWORD -Force 4 | -------------------------------------------------------------------------------- /Deploy-AD/scripts/Set-WallPaper.ps1: -------------------------------------------------------------------------------- 1 | # Author: Roberto Rodriguez (@Cyb3rWard0g) 2 | # License: GPL-3.0 3 | 4 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 5 | 6 | Resolve-DnsName github.com 7 | Resolve-DnsName raw.githubusercontent.com 8 | Resolve-DnsName live.sysinternals.com 9 | 10 | $wc = new-object System.Net.WebClient 11 | # Download BgInfo 12 | $wc.DownloadFile('http://live.sysinternals.com/bginfo.exe', 'C:\ProgramData\bginfo.exe') 13 | 14 | # Copy Wallpaper 15 | $wc.DownloadFile('https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/APT1.jpg', 'C:\ProgramData\APT1.jpg') 16 | $wc.DownloadFile('https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/DOLAB.gif', 'C:\ProgramData\DOLAB.gif') 17 | 18 | # Copy BGInfo config 19 | $wc.DownloadFile('https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/resources/dolabs.bgi', 'C:\ProgramData\dolabs.bgi') 20 | 21 | # Set Run Key 22 | New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "BgInfo" -Value "C:\ProgramData\bginfo.exe C:\ProgramData\dolabs.bgi /silent /timer:0 /nolicprompt" -PropertyType "String" -force -------------------------------------------------------------------------------- /Deploy-AD/templates/AddSSHKey.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string" 7 | }, 8 | "addsshkeyscript": { 9 | "type": "string" 10 | }, 11 | "domainFQDN": { 12 | "type": "string" 13 | }, 14 | "adminUsername": { 15 | "type": "string" 16 | }, 17 | "adminPassword": { 18 | "type": "securestring" 19 | }, 20 | "location": { 21 | "type": "string", 22 | "metadata": { 23 | "description": "Location for all resources." 24 | } 25 | } 26 | }, 27 | "resources": [ 28 | { 29 | "name": "[concat(parameters('vmName'), '/PowerShellDSC')]", 30 | "type": "Microsoft.Compute/virtualMachines/extensions", 31 | "apiVersion": "2019-12-01", 32 | "location": "[parameters('location')]", 33 | "properties": { 34 | "publisher": "Microsoft.Powershell", 35 | "type": "DSC", 36 | "typeHandlerVersion": "2.77", 37 | "autoUpgradeMinorVersion": true, 38 | "settings": { 39 | "wmfVersion": "latest", 40 | "configuration": { 41 | "url": "[parameters('addsshkeyscript')]", 42 | "script": "Add-SSH-key.ps1", 43 | "function": "Add-Key" 44 | }, 45 | "configurationArguments": { 46 | "DomainFQDN": "[parameters('DomainFQDN')]" 47 | } 48 | }, 49 | "protectedSettings": { 50 | "configurationArguments": { 51 | "AdminCreds": { 52 | "UserName": "[parameters('adminUsername')]", 53 | "Password": "[parameters('adminPassword')]" 54 | } 55 | } 56 | } 57 | } 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /Deploy-AD/templates/createADForest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string" 7 | }, 8 | "createADForestScript": { 9 | "type": "string" 10 | }, 11 | "domainFQDN": { 12 | "type": "string" 13 | }, 14 | "adminUsername": { 15 | "type": "string" 16 | }, 17 | "adminPassword": { 18 | "type": "securestring" 19 | }, 20 | "domainUsers": { 21 | "type": "secureObject" 22 | }, 23 | "script": { 24 | "type": "string" 25 | }, 26 | "function": { 27 | "type": "string" 28 | }, 29 | "location": { 30 | "type": "string", 31 | "metadata": { 32 | "description": "Location for all resources." 33 | } 34 | } 35 | }, 36 | "resources": [ 37 | { 38 | "name": "[concat(parameters('vmName'), '/PowerShellDSC')]", 39 | "type": "Microsoft.Compute/virtualMachines/extensions", 40 | "apiVersion": "2019-12-01", 41 | "location": "[parameters('location')]", 42 | "properties": { 43 | "publisher": "Microsoft.Powershell", 44 | "type": "DSC", 45 | "typeHandlerVersion": "2.77", 46 | "autoUpgradeMinorVersion": true, 47 | "settings": { 48 | "wmfVersion": "latest", 49 | "configuration": { 50 | "url": "[parameters('createADForestScript')]", 51 | "script": "[parameters('script')]", 52 | "function": "[parameters('function')]" 53 | }, 54 | "configurationArguments": { 55 | "DomainFQDN": "[parameters('DomainFQDN')]" 56 | } 57 | }, 58 | "protectedSettings": { 59 | "configurationArguments": { 60 | "AdminCreds": { 61 | "UserName": "[parameters('adminUsername')]", 62 | "Password": "[parameters('adminPassword')]" 63 | }, 64 | "DomainUsers": "[parameters('domainUsers').array]" 65 | } 66 | } 67 | } 68 | } 69 | ] 70 | } -------------------------------------------------------------------------------- /Deploy-AD/templates/deployADCS.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string" 7 | }, 8 | "deployadcsscript": { 9 | "type": "string" 10 | }, 11 | "domainFQDN": { 12 | "type": "string" 13 | }, 14 | "adminUsername": { 15 | "type": "string" 16 | }, 17 | "adminPassword": { 18 | "type": "securestring" 19 | }, 20 | "location": { 21 | "type": "string", 22 | "metadata": { 23 | "description": "Location for all resources." 24 | } 25 | } 26 | }, 27 | "resources": [ 28 | { 29 | "name": "[concat(parameters('vmName'), '/PowerShellDSC')]", 30 | "type": "Microsoft.Compute/virtualMachines/extensions", 31 | "apiVersion": "2019-12-01", 32 | "location": "[parameters('location')]", 33 | "properties": { 34 | "publisher": "Microsoft.Powershell", 35 | "type": "DSC", 36 | "typeHandlerVersion": "2.77", 37 | "autoUpgradeMinorVersion": true, 38 | "settings": { 39 | "wmfVersion": "latest", 40 | "configuration": { 41 | "url": "[parameters('deployadcsscript')]", 42 | "script": "Deploy-ADCS.ps1", 43 | "function": "Deploy-ADCS" 44 | }, 45 | "configurationArguments": { 46 | "DomainFQDN": "[parameters('DomainFQDN')]" 47 | } 48 | }, 49 | "protectedSettings": { 50 | "configurationArguments": { 51 | "AdminCreds": { 52 | "UserName": "[parameters('adminUsername')]", 53 | "Password": "[parameters('adminPassword')]" 54 | } 55 | } 56 | } 57 | } 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /Deploy-AD/templates/joinDomain.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string" 7 | }, 8 | "joinDomainScript": { 9 | "type": "string" 10 | }, 11 | "domainFQDN": { 12 | "type": "string" 13 | }, 14 | "adminUsername": { 15 | "type": "string" 16 | }, 17 | "adminPassword": { 18 | "type": "securestring" 19 | }, 20 | "dcIpAddress": { 21 | "type": "string" 22 | }, 23 | "joinOU": { 24 | "type": "string" 25 | }, 26 | "location": { 27 | "type": "string", 28 | "metadata": { 29 | "description": "Location for all resources." 30 | } 31 | } 32 | }, 33 | "resources": [ 34 | { 35 | "name": "[concat(parameters('vmName'), '/PowerShellDSC')]", 36 | "type": "Microsoft.Compute/virtualMachines/extensions", 37 | "apiVersion": "2019-12-01", 38 | "location": "[parameters('location')]", 39 | "properties": { 40 | "publisher": "Microsoft.Powershell", 41 | "type": "DSC", 42 | "typeHandlerVersion": "2.77", 43 | "autoUpgradeMinorVersion": true, 44 | "settings": { 45 | "wmfVersion": "latest", 46 | "configuration": { 47 | "url": "[parameters('joinDomainScript')]", 48 | "script": "Join-Domain.ps1", 49 | "function": "Join-Domain" 50 | }, 51 | "configurationArguments": { 52 | "DomainFQDN": "[parameters('DomainFQDN')]", 53 | "DCIPAddress": "[parameters('dcIpAddress')]", 54 | "JoinOU": "[parameters('joinOU')]" 55 | } 56 | }, 57 | "protectedSettings": { 58 | "configurationArguments": { 59 | "AdminCreds": { 60 | "UserName": "[parameters('adminUsername')]", 61 | "Password": "[parameters('adminPassword')]" 62 | } 63 | } 64 | } 65 | } 66 | } 67 | ] 68 | } -------------------------------------------------------------------------------- /Deploy-AD/templates/sysmonInstall.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string" 7 | }, 8 | "installSysmonScript": { 9 | "type": "string" 10 | }, 11 | "location": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Location for all resources." 15 | } 16 | } 17 | }, 18 | "resources": [ 19 | { 20 | "name": "[concat(parameters('vmName'), '/PowerShellDSC')]", 21 | "type": "Microsoft.Compute/virtualMachines/extensions", 22 | "apiVersion": "2019-12-01", 23 | "location": "[parameters('location')]", 24 | "properties": { 25 | "publisher": "Microsoft.Powershell", 26 | "type": "DSC", 27 | "typeHandlerVersion": "2.77", 28 | "autoUpgradeMinorVersion": true, 29 | "settings": { 30 | "wmfVersion": "latest", 31 | "configuration": { 32 | "url": "[parameters('installSysmonScript')]", 33 | "script": "Install-Sysmon.ps1", 34 | "function": "Install-Sysmon" 35 | }, 36 | "configurationArguments": {} 37 | }, 38 | "protectedSettings": { 39 | "configurationArguments": {} 40 | } 41 | } 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /Deploy-AD/templates/vnet-dns-server.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "virtualNetworkName": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "The name of the Virtual Network to Create" 9 | } 10 | }, 11 | "virtualNetworkAddressRange": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "The address range of the new VNET in CIDR format" 15 | } 16 | }, 17 | "subnets": { 18 | "type": "array", 19 | "metadata": { 20 | "description": "all subnets available" 21 | } 22 | }, 23 | "DNSServerAddress": { 24 | "type": "array", 25 | "metadata": { 26 | "description": "The DNS address(es) of the DNS Server(s) used by the VNET" 27 | } 28 | }, 29 | "location": { 30 | "type": "string", 31 | "metadata": { 32 | "description": "Location for all resources." 33 | } 34 | } 35 | }, 36 | "resources": [ 37 | { 38 | "type": "Microsoft.Network/virtualNetworks", 39 | "apiVersion": "2019-02-01", 40 | "name": "[parameters('virtualNetworkName')]", 41 | "location": "[parameters('location')]", 42 | "properties": { 43 | "addressSpace": { 44 | "addressPrefixes": [ 45 | "[parameters('virtualNetworkAddressRange')]" 46 | ] 47 | }, 48 | "dhcpOptions": { 49 | "dnsServers": "[parameters('DNSServerAddress')]" 50 | }, 51 | "subnets": "[parameters('subnets')]" 52 | } 53 | } 54 | ] 55 | } -------------------------------------------------------------------------------- /Deploy-AMA/azuredeploy-ama.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "virtualMachines": { 6 | "type": "array", 7 | "metadata": { 8 | "description": "List of endpoints to install the Azure Monitor Agent. The format is an array of endpoints with a property/attribute named 'vmName'" 9 | } 10 | }, 11 | "workspaceId": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Log analytics workspace ID" 15 | }, 16 | "defaultValue": "" 17 | }, 18 | "workspaceKey": { 19 | "type": "securestring", 20 | "metadata": { 21 | "description": "Log analytics workspace keys" 22 | }, 23 | "defaultValue": "" 24 | }, 25 | "location": { 26 | "type": "string", 27 | "defaultValue": "[resourceGroup().location]", 28 | "metadata": { 29 | "description": "Location for all resources." 30 | } 31 | } 32 | }, 33 | "variables": {}, 34 | "resources": [ 35 | { 36 | "name": "[concat(parameters('virtualMachines')[copyIndex('AMACopy')].vmName,'/AzureMonitorAgent')]", 37 | "type": "Microsoft.Compute/virtualMachines/extensions", 38 | "apiVersion": "2020-06-01", 39 | "location": "[parameters('location')]", 40 | "copy": { 41 | "name": "AMACopy", 42 | "count": "[length(parameters('virtualMachines'))]" 43 | }, 44 | "properties": { 45 | "publisher": "Microsoft.Azure.Monitor", 46 | "type": "AzureMonitorWindowsAgent", 47 | "typeHandlerVersion": "1.0", 48 | "autoUpgradeMinorVersion": true, 49 | "settings": {}, 50 | "protectedSettings": {} 51 | } 52 | }, 53 | { 54 | "type": "Microsoft.Compute/virtualMachines/extensions", 55 | "apiVersion": "2020-06-01", 56 | "name": "[concat('Nux01','/AzureMonitorAgent')]", 57 | "location": "[parameters('location')]", 58 | "properties": { 59 | "publisher": "Microsoft.Azure.Monitor", 60 | "type": "AzureMonitorLinuxAgent", 61 | "typeHandlerVersion": "1.0", 62 | "autoUpgradeMinorVersion": true, 63 | "settings": {}, 64 | "protectedSettings": {} 65 | } 66 | } 67 | ], 68 | "outputs": {} 69 | } -------------------------------------------------------------------------------- /Deploy-DCRs/azuredeploy-DCRs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "virtualMachines": { 6 | "type": "array", 7 | "metadata": { 8 | "description": "List of endpoints to install the Azure Monitor Agent. The format is an array of endpoints with a property/attribute named 'vmName'" 9 | } 10 | }, 11 | "workspaceResourceIdOutput": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Log analytics workspace ID" 15 | }, 16 | "defaultValue": "" 17 | }, 18 | "location": { 19 | "type": "string", 20 | "defaultValue": "[resourceGroup().location]", 21 | "metadata": { 22 | "description": "Location for all resources." 23 | } 24 | } 25 | }, 26 | "variables": {}, 27 | "resources": [ 28 | { 29 | "type": "Microsoft.Insights/dataCollectionRules", 30 | "apiVersion": "2021-09-01-preview", 31 | "name": "SecurityEvents", 32 | "location": "[parameters('location')]", 33 | "properties": { 34 | "dataSources": { 35 | "windowsEventLogs": [ 36 | { 37 | "name": "eventLogsDataSource", 38 | "streams": [ "Microsoft-SecurityEvent" ], 39 | "xPathQueries": [ 40 | "Security!*" 41 | ] 42 | } 43 | ] 44 | }, 45 | "destinations": { 46 | "logAnalytics": [ 47 | { 48 | "name": "WindowsEvents", 49 | "workspaceResourceId": "[parameters('workspaceResourceIdOutput')]" 50 | } 51 | ] 52 | }, 53 | "dataFlows": [ 54 | { 55 | "streams": [ "Microsoft-SecurityEvent" ], 56 | "destinations": [ "WindowsEvents" ] 57 | } 58 | ] 59 | } 60 | }, 61 | { 62 | "type": "Microsoft.Insights/dataCollectionRules", 63 | "apiVersion": "2021-09-01-preview", 64 | "name": "Sysmon", 65 | "location": "[parameters('location')]", 66 | "properties": { 67 | "dataSources": { 68 | "windowsEventLogs": [ 69 | { 70 | "name": "SysmonLogs", 71 | "streams": [ "Microsoft-Event" ], 72 | "xPathQueries": [ 73 | "Microsoft-Windows-Sysmon/Operational!*" 74 | ] 75 | } 76 | ] 77 | }, 78 | "destinations": { 79 | "logAnalytics": [ 80 | { 81 | "name": "SysmonLogs", 82 | "workspaceResourceId": "[parameters('workspaceResourceIdOutput')]" 83 | } 84 | ] 85 | }, 86 | "dataFlows": [ 87 | { 88 | "streams": [ "Microsoft-Event" ], 89 | "destinations": [ "SysmonLogs" ] 90 | } 91 | ] 92 | } 93 | }, 94 | { 95 | "type": "Microsoft.Insights/dataCollectionRules", 96 | "apiVersion": "2021-09-01-preview", 97 | "name": "AdditionalLogs", 98 | "location": "[parameters('location')]", 99 | "properties": { 100 | "dataSources": { 101 | "windowsEventLogs": [ 102 | { 103 | "name": "AdditionalLogs", 104 | "streams": [ "Microsoft-Event" ], 105 | "xPathQueries": [ 106 | "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational!*", 107 | "Microsoft-Windows-Bits-Client/Operational!*", 108 | "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational!*", 109 | "Microsoft-Windows-DNS-Client/Operational!*", 110 | "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall!*", 111 | "Microsoft-Windows-PowerShell/Operational!*", 112 | "Microsoft-Windows-WMI-Activity/Operational!*", 113 | "Microsoft-Windows-TaskScheduler/Operational!*" 114 | ] 115 | } 116 | ] 117 | }, 118 | "destinations": { 119 | "logAnalytics": [ 120 | { 121 | "name": "AdditionalLogs", 122 | "workspaceResourceId": "[parameters('workspaceResourceIdOutput')]" 123 | } 124 | ] 125 | }, 126 | "dataFlows": [ 127 | { 128 | "streams": [ "Microsoft-Event" ], 129 | "destinations": [ "AdditionalLogs" ] 130 | } 131 | ] 132 | } 133 | }, 134 | { 135 | "type": "Microsoft.Insights/dataCollectionRules", 136 | "apiVersion": "2021-09-01-preview", 137 | "name": "Syslog", 138 | "location": "[parameters('location')]", 139 | "kind": "Linux", 140 | "properties": { 141 | "dataSources": { 142 | "syslog": [ 143 | { 144 | "name": "Syslog", 145 | "streams": [ 146 | "Microsoft-Syslog" 147 | ], 148 | "facilityNames": [ 149 | "auth", 150 | "authpriv", 151 | "alert" 152 | ], 153 | "logLevels": [ 154 | "Debug", 155 | "Info", 156 | "Notice", 157 | "Warning", 158 | "Error", 159 | "Critical", 160 | "Alert", 161 | "Emergency" 162 | ] 163 | } 164 | ] 165 | }, 166 | "destinations": { 167 | "logAnalytics": [ 168 | { 169 | "name": "Syslog", 170 | "workspaceResourceId": "[parameters('workspaceResourceIdOutput')]" 171 | } 172 | ] 173 | }, 174 | "dataFlows": [ 175 | { 176 | "streams": [ 177 | "Microsoft-Syslog" 178 | ], 179 | "destinations": [ 180 | "Syslog" 181 | ], 182 | "transformKql": "source", 183 | "outputStream": "Microsoft-Syslog" 184 | } 185 | ] 186 | } 187 | }, 188 | { 189 | "name": "[concat(parameters('virtualMachines')[copyIndex('vmDCRCopy')].vmName, '/microsoft.insights/', 'SecurityEvents')]", 190 | "dependsOn": [ "[resourceId('Microsoft.Insights/dataCollectionRules', 'SecurityEvents')]" ], 191 | "type": "Microsoft.Compute/virtualMachines/providers/dataCollectionRuleAssociations", 192 | "apiVersion": "2019-11-01-preview", 193 | "location": "[parameters('location')]", 194 | "copy": { 195 | "name": "vmDCRCopy", 196 | "count": "[length(parameters('virtualMachines'))]" 197 | }, 198 | "properties": { 199 | "description": "Association of data collection rule. Deleting this association will break the data collection for this virtual machine.", 200 | "dataCollectionRuleId": "[resourceId('Microsoft.Insights/dataCollectionRules', 'SecurityEvents')]" 201 | } 202 | }, 203 | { 204 | "name": "[concat(parameters('virtualMachines')[copyIndex('vmDCRCopy')].vmName, '/microsoft.insights/', 'Sysmon')]", 205 | "dependsOn": [ "[resourceId('Microsoft.Insights/dataCollectionRules', 'Sysmon')]" ], 206 | "type": "Microsoft.Compute/virtualMachines/providers/dataCollectionRuleAssociations", 207 | "apiVersion": "2019-11-01-preview", 208 | "location": "[parameters('location')]", 209 | "copy": { 210 | "name": "vmDCRCopy", 211 | "count": "[length(parameters('virtualMachines'))]" 212 | }, 213 | "properties": { 214 | "description": "Association of data collection rule. Deleting this association will break the data collection for this virtual machine.", 215 | "dataCollectionRuleId": "[resourceId('Microsoft.Insights/dataCollectionRules', 'Sysmon')]" 216 | } 217 | }, 218 | { 219 | "name": "[concat(parameters('virtualMachines')[copyIndex('vmDCRCopy')].vmName, '/microsoft.insights/', 'AdditionalLogs')]", 220 | "dependsOn": [ "[resourceId('Microsoft.Insights/dataCollectionRules', 'AdditionalLogs')]" ], 221 | "type": "Microsoft.Compute/virtualMachines/providers/dataCollectionRuleAssociations", 222 | "apiVersion": "2019-11-01-preview", 223 | "location": "[parameters('location')]", 224 | "copy": { 225 | "name": "vmDCRCopy", 226 | "count": "[length(parameters('virtualMachines'))]" 227 | }, 228 | "properties": { 229 | "description": "Association of data collection rule. Deleting this association will break the data collection for this virtual machine.", 230 | "dataCollectionRuleId": "[resourceId('Microsoft.Insights/dataCollectionRules', 'AdditionalLogs')]" 231 | } 232 | }, 233 | { 234 | "type": "Microsoft.Compute/virtualMachines/providers/dataCollectionRuleAssociations", 235 | "apiVersion": "2019-11-01-preview", 236 | "name": "[concat('Nux01', '/microsoft.insights/', 'Syslog')]", 237 | "location": "[parameters('location')]", 238 | "dependsOn": [ 239 | "[resourceId('Microsoft.Insights/dataCollectionRules', 'Syslog')]" 240 | ], 241 | "properties": { 242 | "description": "Association of data collection rule. Deleting this association will break the data collection for this virtual machine.", 243 | "dataCollectionRuleId": "[resourceId('Microsoft.Insights/dataCollectionRules', 'Syslog')]" 244 | } 245 | } 246 | ], 247 | "outputs": {} 248 | } -------------------------------------------------------------------------------- /Deploy-LAB/azure-deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "pricingTier": { 6 | "type": "string", 7 | "allowedValues": [ 8 | "PerGB2018", 9 | "Free", 10 | "Standalone", 11 | "PerNode", 12 | "Standard", 13 | "Premium" 14 | ], 15 | "defaultValue": "PerGB2018", 16 | "metadata": { 17 | "description": "Pricing tier: pergb2018 or legacy tiers (Free, Standalone, PerNode, Standard or Premium) which are not available to all customers." 18 | } 19 | }, 20 | "allowedIPAddresses": { 21 | "type": "string", 22 | "metadata": { 23 | "description": "The sourceAddressPrefixes allowed to connect to this deployment" 24 | } 25 | }, 26 | "vmSize": { 27 | "type": "string", 28 | "defaultValue": "Standard_B2s", 29 | "allowedValues": [ 30 | "Standard_B2s", 31 | "Standard_B2ms", 32 | "Standard_B4ms", 33 | "Standard_B8ms", 34 | "Standard_B2s_v2", 35 | "Standard_B2ls_v2", 36 | "Standard_B2als_v2", 37 | "Standard_B2as_v2", 38 | "Standard_DS2", 39 | "Standard_DS11", 40 | "Standard_D2s_v3", 41 | "Standard_D2s_v4", 42 | "Standard_D2s_v5" 43 | ], 44 | "metadata": { 45 | "description": "Size of the virtual machine. Reference: https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-general" 46 | } 47 | }, 48 | "location": { 49 | "type": "string", 50 | "defaultValue": "[resourceGroup().location]", 51 | "metadata": { 52 | "description": "Location for all resources." 53 | } 54 | } 55 | }, 56 | "variables": { 57 | "doadminusername": "dolabbuilder", 58 | "doadminpassword": "DOLabAdmin1!!", 59 | "dolinuxadminusername": "doadmin", 60 | "dolinuxadminpassword": "DOLabAdmin1!", 61 | "donameprefix": "WS0", 62 | "doWOffer": "Windows-10", 63 | "doWSKU": "win10-22h2-pro", 64 | "doWVersion": "19045.5487.250210", 65 | // "doWOffer": "Windows-11", 66 | // "doWSKU": "win11-24h2-pro", 67 | // "doWVersion": "26100.3194.250210", 68 | "doServerOffer": "WindowsServer", 69 | "doServerSKU": "2022-Datacenter", 70 | "doServerVersion": "20348.3207.250210", 71 | "dofqdn": "doazlab.com", 72 | "doc2": "metasploit", 73 | "doc2publisher": "Canonical", 74 | "doc2ubuntuoffer": "0001-com-ubuntu-server-jammy", 75 | "doc2ubuntusku": "22_04-lts", 76 | "doc2ubuntuversion": "22.04.202502280", 77 | "doworkspaceprefix": "LA-workspace", 78 | "doremoteaccessmode": "AllowPublicIP", 79 | "doimmediatePurgeDataOn30Days": true, 80 | "dataRetention": 30, 81 | "dowscount": 1 82 | }, 83 | "resources": [ 84 | { 85 | "name": "Deploy-Sentinel", 86 | "type": "Microsoft.Resources/deployments", 87 | "apiVersion": "2020-10-01", 88 | "properties": { 89 | "mode": "Incremental", 90 | "templateLink": { 91 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-Sentinel/azuredeploy-sentinel.json", 92 | "contentVersion": "1.0.0.0" 93 | }, 94 | "parameters": { 95 | "workspaceName": { 96 | "value": "[variables('doworkspaceprefix')]" 97 | }, 98 | "pricingTier": { 99 | "value": "[parameters('pricingTier')]" 100 | }, 101 | "dataRetention": { 102 | "value": "[variables('dataRetention')]" 103 | }, 104 | "immediatePurgeDataOn30Days": { 105 | "value": "[variables('doimmediatePurgeDataOn30Days')]" 106 | } 107 | } 108 | } 109 | }, 110 | { 111 | "name": "Deploy-AD", 112 | "type": "Microsoft.Resources/deployments", 113 | "apiVersion": "2020-10-01", 114 | "dependsOn": [ 115 | ], 116 | "properties": { 117 | "mode": "Incremental", 118 | "templateLink": { 119 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AD/azuredeploy-ad.json", 120 | "contentVersion": "1.0.0.0" 121 | }, 122 | "parameters": { 123 | "adminUsername": { 124 | "value": "[variables('doadminusername')]" 125 | }, 126 | "adminPassword": { 127 | "value": "[variables('doadminpassword')]" 128 | }, 129 | "numberOfWorkstations": { 130 | "value": "[variables('dowscount')]" 131 | }, 132 | "vmNamePrefix": { 133 | "value": "[variables('donameprefix')]" 134 | }, 135 | "windowsDesktopOffer": { 136 | "value": "[variables('doWOffer')]" 137 | }, 138 | "windowsDesktopSKU": { 139 | "value": "[variables('doWSKU')]" 140 | }, 141 | "windowsDesktopVersion": { 142 | "value": "[variables('doWVersion')]" 143 | }, 144 | "windowsServerOffer": { 145 | "value": "[variables('doServerOffer')]" 146 | }, 147 | "windowsServerSKU": { 148 | "value": "[variables('doServerSKU')]" 149 | }, 150 | "windowsServerVersion": { 151 | "value": "[variables('doServerVersion')]" 152 | }, 153 | "vmSize": { 154 | "value": "[parameters('vmSize')]" 155 | }, 156 | "domainFQDN": { 157 | "value": "[variables('dofqdn')]" 158 | }, 159 | "identityType": { 160 | "value": "SystemAssigned" 161 | }, 162 | "remoteAccessMode": { 163 | "value": "[variables('doremoteaccessmode')]" 164 | }, 165 | "allowedIPAddresses": { 166 | "value": "[parameters('allowedIPAddresses')]" 167 | }, 168 | "location": { 169 | "value": "[parameters('location')]" 170 | } 171 | } 172 | } 173 | }, 174 | { 175 | "name": "Deploy-AMA", 176 | "type": "Microsoft.Resources/deployments", 177 | "apiVersion": "2020-10-01", 178 | "dependsOn": [ 179 | "Deploy-Sentinel", 180 | "Deploy-AD", 181 | "Deploy-Linux" 182 | ], 183 | "properties": { 184 | "mode": "Incremental", 185 | "templateLink": { 186 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-AMA/azuredeploy-ama.json", 187 | "contentVersion": "1.0.0.0" 188 | }, 189 | "parameters": { 190 | "virtualMachines": { 191 | "value": "[reference('Deploy-AD').outputs.allWinVMsDeployed.value]" 192 | } 193 | } 194 | } 195 | }, 196 | { 197 | "name": "Deploy-Linux", 198 | "type": "Microsoft.Resources/deployments", 199 | "apiVersion": "2020-10-01", 200 | "properties": { 201 | "mode": "Incremental", 202 | "templateLink": { 203 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-Linux/azuredeploy-Linux.json", 204 | "contentVersion": "1.0.0.0" 205 | }, 206 | "parameters": { 207 | "adminUsername": { 208 | "value": "[variables('dolinuxadminusername')]" 209 | }, 210 | "authenticationType": { 211 | "value": "password" 212 | }, 213 | "adminPasswordOrKey": { 214 | "value": "[variables('dolinuxadminpassword')]" 215 | }, 216 | "vmName": { 217 | "value": "Nux01" 218 | }, 219 | 220 | "ubuntuPublisher": { 221 | "value": "[variables('doc2publisher')]" 222 | }, 223 | "ubuntuOffer": { 224 | "value": "[variables('doc2ubuntuoffer')]" 225 | }, 226 | "ubuntuSKU": { 227 | "value": "[variables('doc2ubuntusku')]" 228 | }, 229 | "ubuntuVersion": { 230 | "value": "[variables('doc2ubuntuversion')]" 231 | }, 232 | "vmSize": { 233 | "value": "[parameters('vmSize')]" 234 | }, 235 | "allowedIPAddresses": { 236 | "value": "[parameters('allowedIPAddresses')]" 237 | }, 238 | "c2Framework": { 239 | "value": "[variables('doc2')]" 240 | } 241 | } 242 | } 243 | }, 244 | { 245 | "name": "Deploy-DCRs", 246 | "type": "Microsoft.Resources/deployments", 247 | "apiVersion": "2020-10-01", 248 | "dependsOn": [ 249 | "Deploy-AMA" 250 | ], 251 | "properties": { 252 | "mode": "Incremental", 253 | "templateLink": { 254 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-DCRs/azuredeploy-DCRs.json", 255 | "contentVersion": "1.0.0.0" 256 | }, 257 | "parameters": { 258 | "virtualMachines": { 259 | "value": "[reference('Deploy-AD').outputs.allWinVMsDeployed.value]" 260 | }, 261 | "workspaceResourceIdOutput": { 262 | "value": "[reference('Deploy-Sentinel').outputs.workspaceResourceIdOutput.value]" 263 | } 264 | } 265 | } 266 | }, 267 | { 268 | "name": "Deploy-NetPeering", 269 | "type": "Microsoft.Resources/deployments", 270 | "apiVersion": "2020-10-01", 271 | "dependsOn": [ 272 | "Deploy-Linux", 273 | "Deploy-AD" 274 | ], 275 | "properties": { 276 | "mode": "Incremental", 277 | "templateLink": { 278 | "uri": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-NetPeering/azuredeploy-netpeering.json", 279 | "contentVersion": "1.0.0.0" 280 | }, 281 | "parameters": { 282 | "linux-net-id": { 283 | "value": "[reference('Deploy-Linux').outputs.virtualNetworkId.value]" 284 | }, 285 | "ad-net-id": { 286 | "value": "[reference('Deploy-AD').outputs.virtualNetworkId.value]" 287 | } 288 | } 289 | } 290 | } 291 | ], 292 | "outputs": { 293 | "C2PublicIP": { 294 | "type": "string", 295 | "value": "[reference('Deploy-Linux').outputs.C2PublicIP.value]" 296 | }, 297 | "DCPublicIP": { 298 | "type": "string", 299 | "value": "[reference('Deploy-AD').outputs.DCPublicIP.value]" 300 | }, 301 | "WSPublicIP": { 302 | "type": "string", 303 | "value": "[reference('Deploy-AD').outputs.WSPublicIP.value]" 304 | } 305 | } 306 | } -------------------------------------------------------------------------------- /Deploy-LAB/uidefinition.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", 3 | "handler": "Microsoft.Azure.CreateUIDef", 4 | "version": "0.1.2-preview", 5 | "parameters": { 6 | "config": { 7 | "isWizard": true, 8 | "basics": { 9 | "description": "\n\n\n Defensive Origins Azure Lab Environment\n https://www.doazlab.com", 10 | "location": { 11 | "label": "Location", 12 | "toolTip": "Location for all resources", 13 | "resourceTypes": [ 14 | "Microsoft.OperationalInsights" 15 | ], 16 | "allowedValues": [ 17 | "eastus", 18 | "eastus2", 19 | "southcentralus", 20 | "westus", 21 | "westus2", 22 | "westus3", 23 | "centralus", 24 | "northeurope", 25 | "westeurope" 26 | ] 27 | } 28 | } 29 | }, 30 | "basics": [ 31 | { 32 | "name": "workspaceName", 33 | "type": "Microsoft.Common.TextBox", 34 | "label": "Workspace Name", 35 | "placeholder": "", 36 | "defaultValue": "LA-workspace", 37 | "toolTip": "The workspace name should include 4-63 letters, digits or '-'. The '-' shouldn't be the first or the last symbol.", 38 | "constraints": { 39 | "required": true, 40 | "regex": "^[A-Za-z0-9][A-Za-z0-9-]+[A-Za-z0-9]$", 41 | "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." 42 | }, 43 | "visible": false 44 | } 45 | ], 46 | "steps": [ 47 | { 48 | "name": "vmParameters", 49 | "label": "VM Parameters", 50 | "elements": [ 51 | { 52 | "name": "vmSection", 53 | "type": "Microsoft.Common.Section", 54 | "label": "Customize your VM", 55 | "elements": [ 56 | { 57 | "name": "vmSize", 58 | "type": "Microsoft.Compute.SizeSelector", 59 | "label": "Size", 60 | "toolTip": "", 61 | "recommendedSizes": [ 62 | "Standard_B2s", 63 | "Standard_B2ms", 64 | "Standard_DS2", 65 | "Standard_DS11" 66 | ], 67 | "constraints": { 68 | "allowedSizes": [ 69 | "Standard_B2s", 70 | "Standard_B2ms", 71 | "Standard_DS2", 72 | "Standard_DS11" 73 | ] 74 | }, 75 | "options": { 76 | "hideDiskTypeFilter": false 77 | }, 78 | "osPlatform": "Windows", 79 | "imageReference": { 80 | "publisher": "MicrosoftWindowsServer", 81 | "offer": "WindowsServer", 82 | "sku": "2022-Datacenter" 83 | }, 84 | "count": 1, 85 | "visible": true 86 | } 87 | ], 88 | "visible": true 89 | } 90 | ] 91 | }, 92 | { 93 | "name": "networkParameters", 94 | "label": "Networking", 95 | "elements": [ 96 | { 97 | "name": "allowedIPAddresses", 98 | "type": "Microsoft.Common.TextBox", 99 | "label": "Allowed IP Addresses", 100 | "placeholder": "0.0.0.0/0", 101 | "defaultValue": "0.0.0.0/0", 102 | "toolTip": "The sourceAddressPrefixes allowed to connect to this deployment.", 103 | "constraints": { 104 | "required": true, 105 | "regex": "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\\/(\\d|[12]\\d|3[01]))?$", 106 | "validationMessage": "Please enter a valid CIDR." 107 | }, 108 | "visible": true 109 | } 110 | ] 111 | } 112 | ], 113 | "outputs": { 114 | "workspaceName": "[steps('basics').workspaceName]", 115 | "vmSize": "[steps('vmParameters').vmSection.vmSize]", 116 | "allowedIPAddresses": "[steps('networkParameters').allowedIPAddresses]" 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Deploy-Linux/azuredeploy-Linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "utcValue": { 6 | "type": "string", 7 | "defaultValue": "[utcNow()]", 8 | "metadata": { 9 | "description": "Returns the current (UTC) datetime value in the specified format. If no format is provided, the ISO 8601 (yyyyMMddTHHmmssZ) format is used" 10 | } 11 | }, 12 | "adminUsername": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "Username for the Virtual Machine." 16 | } 17 | }, 18 | "authenticationType": { 19 | "type": "string", 20 | "defaultValue": "password", 21 | "allowedValues": [ 22 | "sshPublicKey", 23 | "password" 24 | ], 25 | "metadata": { 26 | "description": "Type of authentication to use on the Virtual Machine. SSH key is recommended." 27 | } 28 | }, 29 | "adminPasswordOrKey": { 30 | "type": "securestring", 31 | "metadata": { 32 | "description": "SSH Key or password for the Virtual Machine. SSH key is recommended." 33 | } 34 | }, 35 | "remoteAccessMode": { 36 | "type": "string", 37 | "defaultValue": "AllowPublicIP", 38 | "allowedValues": [ 39 | "AllowPublicIP" 40 | ], 41 | "metadata": { 42 | "description": "Do you want to restrict access to your environment by a Public IP or set up an Azure Bastion Host. If the former, make sure you add your public IP address to the variable 'allowedIPAddresses'" 43 | } 44 | }, 45 | "allowedIPAddresses": { 46 | "type": "string", 47 | "metadata": { 48 | "description": "The sourceAddressPrefixes allowed to connect to this deployment" 49 | }, 50 | "defaultValue": "*" 51 | }, 52 | "vmName": { 53 | "type": "string", 54 | "defaultValue": "Nux01", 55 | "metadata": { 56 | "description": "Name of the virtual machine" 57 | } 58 | }, 59 | "vmSize": { 60 | "type": "string", 61 | "defaultValue": "Standard_B2s", 62 | "allowedValues": [ 63 | "Standard_B2s", 64 | "Standard_B2ms", 65 | "Standard_B2s_v2", 66 | "Standard_B2ls_v2", 67 | "Standard_B2ts_v2", 68 | "Standard_B2als_v2", 69 | "Standard_B2as_v2", 70 | "Standard_DS2", 71 | "Standard_DS11", 72 | "Standard_D2s_v3", 73 | "Standard_D2s_v4", 74 | "Standard_D2s_v5" 75 | ], 76 | "metadata": { 77 | "description": "Size of the virtual machine. Reference: https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-general" 78 | } 79 | }, 80 | "ubuntuPublisher": { 81 | "type": "string", 82 | "defaultValue": "Canonical", 83 | "metadata": { 84 | "description": "C2 image Publisher." 85 | } 86 | }, 87 | "ubuntuOffer": { 88 | "type": "string", 89 | "defaultValue": "0001-com-ubuntu-server-jammy", 90 | "metadata": { 91 | "description": "C2 image offer code." 92 | } 93 | }, 94 | "ubuntuSKU": { 95 | "type": "string", 96 | "defaultValue": "22_04-lts", 97 | "metadata": { 98 | "description": "The Ubuntu version for the VM." 99 | } 100 | }, 101 | "ubuntuVersion": { 102 | "type": "string", 103 | "defaultValue": "22.04.202502280", 104 | "metadata": { 105 | "description": "C2 image version" 106 | } 107 | }, 108 | "virtualNetworkName": { 109 | "type": "string", 110 | "metadata": { 111 | "description": "Name of the Virtual Network" 112 | }, 113 | "defaultValue": "vnet-c2" 114 | }, 115 | "virtualNetworkAddressRange": { 116 | "type": "string", 117 | "metadata": { 118 | "description": "Virtual Network address range" 119 | }, 120 | "defaultValue": "10.0.0.0/16" 121 | }, 122 | "subnetRange": { 123 | "type": "string", 124 | "metadata": { 125 | "description": "subnet range" 126 | }, 127 | "defaultValue": "10.0.0.0/24" 128 | }, 129 | "VMPrivateIPAddress": { 130 | "type": "string", 131 | "metadata": { 132 | "description": "Private IP for the C2 VM" 133 | }, 134 | "defaultValue": "10.0.0.8" 135 | }, 136 | "subnetName": { 137 | "type": "string", 138 | "metadata": { 139 | "description": "Name of the subnet" 140 | }, 141 | "defaultValue": "snet-c2" 142 | }, 143 | "c2Framework": { 144 | "type": "string", 145 | "defaultValue": "metasploit", 146 | "allowedValues": [ 147 | "empire", 148 | "covenant", 149 | "metasploit" 150 | ], 151 | "metadata": { 152 | "description": "C2 framework to deploy" 153 | } 154 | }, 155 | "location": { 156 | "type": "string", 157 | "defaultValue": "[resourceGroup().location]", 158 | "metadata": { 159 | "description": "Location for all resources." 160 | } 161 | } 162 | }, 163 | "variables": { 164 | "storageAccountName": "[concat('saln',uniquestring(resourceGroup().id, parameters('utcValue')))]", 165 | "doc2pipname": "[concat('pip-', variables('vmName'))]", 166 | "virtualNetworkName": "[parameters('virtualNetworkName')]", 167 | "virtualNetworkAddressRange": "[parameters('virtualNetworkAddressRange')]", 168 | 169 | "subnetName": "[parameters('subnetName')]", 170 | "subnetRange": "[parameters('subnetRange')]", 171 | "vmPrivateIPPrefixArray": "[take(split(variables('subnetRange'),'.'),3)]", 172 | "vmPrivateIPAddresPrefix": "[format('{0}.{1}.{2}.',variables('vmPrivateIPPrefixArray')[0], variables('vmPrivateIPPrefixArray')[1], variables('vmPrivateIPPrefixArray')[2])]", 173 | "subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]", 174 | "nsg-id": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-ssh-allow')]" }, 175 | "networkSecurityGroup": "[if(equals(parameters('remoteAccessMode'), 'AllowPublicIP'), variables('nsg-id'), json('null'))]", 176 | 177 | "subnets": [ 178 | { 179 | "name": "[variables('subnetName')]", 180 | "properties": { 181 | "addressPrefix": "[variables('subnetRange')]", 182 | "networkSecurityGroup": "[variables('networkSecurityGroup')]" 183 | } 184 | } 185 | ], 186 | "allSubnets": "[variables('subnets')]", 187 | "linuxConfiguration": { 188 | "disablePasswordAuthentication": true, 189 | "ssh": { 190 | "publicKeys": [ 191 | { 192 | "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", 193 | "keyData": "[parameters('adminPasswordOrKey')]" 194 | } 195 | ] 196 | } 197 | }, 198 | 199 | "c2SetupScript": "https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-Linux/scripts/Install-C2.sh", 200 | "vmName": "[parameters('vmName')]" 201 | }, 202 | "resources": [ 203 | { 204 | "type": "Microsoft.Storage/storageAccounts", 205 | "apiVersion": "2018-11-01", 206 | "name": "[variables('storageAccountName')]", 207 | "location": "[parameters('location')]", 208 | "sku": { 209 | "name": "Standard_LRS" 210 | }, 211 | "kind": "Storage", 212 | "properties": { 213 | } 214 | }, 215 | { 216 | "name": "nsg-ssh-allow", 217 | "comments": "Default Network Security Group for Linux endpoints", 218 | "type": "Microsoft.Network/networkSecurityGroups", 219 | "apiVersion": "2019-08-01", 220 | "location": "[parameters('location')]", 221 | "properties": { 222 | "securityRules": [ 223 | { 224 | "name": "default-allow-22", 225 | "properties": { 226 | "priority": 100, 227 | "access": "Allow", 228 | "direction": "Inbound", 229 | "destinationPortRange": "22", 230 | "protocol": "Tcp", 231 | "sourcePortRange": "*", 232 | "sourceAddressPrefix": "[parameters('allowedIPAddresses')]", 233 | "destinationAddressPrefix": "*" 234 | } 235 | } 236 | ] 237 | } 238 | }, 239 | { 240 | "type": "Microsoft.Network/virtualNetworks", 241 | "apiVersion": "2019-02-01", 242 | "name": "[parameters('virtualNetworkName')]", 243 | "location": "[parameters('location')]", 244 | "dependsOn": [ 245 | "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-ssh-allow')]" 246 | ], 247 | "properties": { 248 | "addressSpace": { 249 | "addressPrefixes": [ 250 | "[variables('virtualNetworkAddressRange')]" 251 | ] 252 | }, 253 | "subnets": "[variables('allSubnets')]" 254 | } 255 | }, 256 | { 257 | "type": "Microsoft.Network/publicIPAddresses", 258 | "apiVersion": "2018-11-01", 259 | "name": "[variables('doc2pipname')]", 260 | "location": "[parameters('location')]", 261 | "properties": { 262 | "publicIPAllocationMethod": "Static", 263 | "dnsSettings": { 264 | "domainNameLabel": "[toLower(concat(variables('vmName'), '-', uniquestring(resourceGroup().id, parameters('utcValue'))))]" 265 | } 266 | } 267 | }, 268 | { 269 | "type": "Microsoft.Network/networkInterfaces", 270 | "apiVersion": "2019-11-01", 271 | "name": "[concat('nic-', variables('vmName'))]", 272 | "location": "[parameters('location')]", 273 | "dependsOn": [ 274 | "[resourceId('Microsoft.Network/publicIPAddresses/', concat('pip-', variables('vmName')))]", 275 | "[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" 276 | ], 277 | "properties": { 278 | "ipConfigurations": [ 279 | { 280 | "name": "ipconfig1", 281 | "properties": { 282 | "privateIPAllocationMethod": "Static", 283 | "privateIPAddress": "[parameters('VMPrivateIPAddress')]", 284 | "publicIPAddress": "[if(equals(parameters('remoteAccessMode'),'AllowPublicIP'), json(concat('{\"id\":', '\"', resourceId('Microsoft.Network/publicIPAddresses/', concat('pip-', variables('vmName'))),'\"}')),json('null'))]", 285 | "subnet": { 286 | "id": "[variables('subnetRef')]" 287 | } 288 | } 289 | } 290 | ] 291 | } 292 | }, 293 | { 294 | "type": "Microsoft.Compute/virtualMachines", 295 | "apiVersion": "2019-03-01", 296 | "name": "[variables('vmName')]", 297 | "location": "[parameters('location')]", 298 | "identity": { "type": "SystemAssigned" }, 299 | "dependsOn": [ 300 | "[resourceId('Microsoft.Network/networkInterfaces/', concat('nic-', variables('vmName')))]" 301 | ], 302 | "properties": { 303 | "hardwareProfile": { 304 | "vmSize": "[parameters('vmSize')]" 305 | }, 306 | "storageProfile": { 307 | "osDisk": { 308 | "createOption": "fromImage" 309 | }, 310 | "imageReference": { 311 | "publisher": "[parameters('ubuntuPublisher')]", 312 | "offer": "[parameters('ubuntuOffer')]", 313 | "sku": "[parameters('ubuntuSKU')]", 314 | "version": "[parameters('ubuntuVersion')]" 315 | } 316 | }, 317 | "networkProfile": { 318 | "networkInterfaces": [ 319 | { 320 | "id": "[resourceId('Microsoft.Network/networkInterfaces/', concat('nic-', variables('vmName')))]" 321 | } 322 | ] 323 | }, 324 | "osProfile": { 325 | "computerName": "[variables('vmName')]", 326 | "adminUsername": "[parameters('adminUsername')]", 327 | "adminPassword": "[parameters('adminPasswordOrKey')]", 328 | "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), json('null'), variables('linuxConfiguration'))]" 329 | } 330 | } 331 | }, 332 | { 333 | "type": "Microsoft.Compute/virtualMachines/extensions", 334 | "apiVersion": "2019-03-01", 335 | "name": "[concat(variables('vmName'), '/C2Setup')]", 336 | "location": "[parameters('location')]", 337 | "dependsOn": [ 338 | "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]" 339 | ], 340 | "properties": { 341 | "publisher": "Microsoft.Azure.Extensions", 342 | "type": "CustomScript", 343 | "typeHandlerVersion": "2.1", 344 | "autoUpgradeMinorVersion": true, 345 | "settings": {}, 346 | "protectedSettings": { 347 | "commandToExecute": "bash Install-C2.sh", 348 | "fileUris": [ 349 | "[variables('c2SetupScript')]" 350 | ] 351 | } 352 | } 353 | } 354 | ], 355 | "outputs": { 356 | "vmName": { 357 | "type": "string", 358 | "value": "[variables('vmName')]" 359 | }, 360 | "vmResourceID": { 361 | "type": "string", 362 | "value": "[resourceId('Microsoft.Compute/virtualMachines/', variables('vmName'))]" 363 | }, 364 | "virtualNetworkName": { 365 | "type": "string", 366 | "value": "[parameters('virtualNetworkName')]" 367 | }, 368 | "virtualNetworkId": { 369 | "type": "string", 370 | "value": "[resourceId('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" 371 | }, 372 | "C2PublicIP": { 373 | "type": "string", 374 | "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('doc2pipname'))).IpAddress]" 375 | } 376 | } 377 | } -------------------------------------------------------------------------------- /Deploy-Linux/scripts/.zshrc: -------------------------------------------------------------------------------- 1 | # If you come from bash you might have to change your $PATH. 2 | # export PATH=$HOME/bin:/usr/local/bin:$PATH 3 | 4 | # Path to your oh-my-zsh installation. 5 | export ZSH="$HOME/.oh-my-zsh" 6 | 7 | # Set name of the theme to load --- if set to "random", it will 8 | # load a random theme each time oh-my-zsh is loaded, in which case, 9 | # to know which specific one was loaded, run: echo $RANDOM_THEME 10 | # See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes 11 | ZSH_THEME="afowler" 12 | 13 | # Set list of themes to pick from when loading at random 14 | # Setting this variable when ZSH_THEME=random will cause zsh to load 15 | # a theme from this variable instead of looking in $ZSH/themes/ 16 | # If set to an empty array, this variable will have no effect. 17 | # ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) 18 | 19 | # Uncomment the following line to use case-sensitive completion. 20 | # CASE_SENSITIVE="true" 21 | 22 | # Uncomment the following line to use hyphen-insensitive completion. 23 | # Case-sensitive completion must be off. _ and - will be interchangeable. 24 | # HYPHEN_INSENSITIVE="true" 25 | 26 | # Uncomment one of the following lines to change the auto-update behavior 27 | # zstyle ':omz:update' mode disabled # disable automatic updates 28 | # zstyle ':omz:update' mode auto # update automatically without asking 29 | # zstyle ':omz:update' mode reminder # just remind me to update when it's time 30 | 31 | # Uncomment the following line to change how often to auto-update (in days). 32 | # zstyle ':omz:update' frequency 13 33 | 34 | # Uncomment the following line if pasting URLs and other text is messed up. 35 | # DISABLE_MAGIC_FUNCTIONS="true" 36 | 37 | # Uncomment the following line to disable colors in ls. 38 | # DISABLE_LS_COLORS="true" 39 | 40 | # Uncomment the following line to disable auto-setting terminal title. 41 | # DISABLE_AUTO_TITLE="true" 42 | 43 | # Uncomment the following line to enable command auto-correction. 44 | # ENABLE_CORRECTION="true" 45 | 46 | # Uncomment the following line to display red dots whilst waiting for completion. 47 | # You can also set it to another string to have that shown instead of the default red dots. 48 | # e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" 49 | # Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) 50 | # COMPLETION_WAITING_DOTS="true" 51 | 52 | # Uncomment the following line if you want to disable marking untracked files 53 | # under VCS as dirty. This makes repository status check for large repositories 54 | # much, much faster. 55 | # DISABLE_UNTRACKED_FILES_DIRTY="true" 56 | 57 | # Uncomment the following line if you want to change the command execution time 58 | # stamp shown in the history command output. 59 | # You can set one of the optional three formats: 60 | # "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" 61 | # or set a custom format using the strftime function format specifications, 62 | # see 'man strftime' for details. 63 | # HIST_STAMPS="mm/dd/yyyy" 64 | 65 | # Would you like to use another custom folder than $ZSH/custom? 66 | # ZSH_CUSTOM=/path/to/new-custom-folder 67 | 68 | # Which plugins would you like to load? 69 | # Standard plugins can be found in $ZSH/plugins/ 70 | # Custom plugins may be added to $ZSH_CUSTOM/plugins/ 71 | # Example format: plugins=(rails git textmate ruby lighthouse) 72 | # Add wisely, as too many plugins slow down shell startup. 73 | plugins=(git) 74 | 75 | source $ZSH/oh-my-zsh.sh 76 | 77 | # User configuration 78 | 79 | # export MANPATH="/usr/local/man:$MANPATH" 80 | 81 | # You may need to manually set your language environment 82 | # export LANG=en_US.UTF-8 83 | 84 | # Preferred editor for local and remote sessions 85 | # if [[ -n $SSH_CONNECTION ]]; then 86 | # export EDITOR='vim' 87 | # else 88 | # export EDITOR='mvim' 89 | # fi 90 | 91 | # Compilation flags 92 | # export ARCHFLAGS="-arch x86_64" 93 | 94 | # Set personal aliases, overriding those provided by oh-my-zsh libs, 95 | # plugins, and themes. Aliases can be placed here, though oh-my-zsh 96 | # users are encouraged to define aliases within the ZSH_CUSTOM folder. 97 | # For a full list of active aliases, run `alias`. 98 | # 99 | # Example aliases 100 | # alias zshconfig="mate ~/.zshrc" 101 | # alias ohmyzsh="mate ~/.oh-my-zsh" 102 | -------------------------------------------------------------------------------- /Deploy-Linux/scripts/Install-C2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Run as root, please, it's just easier that way 5 | sudo -s 6 | 7 | 8 | # Add folder, Download Scripts 9 | mkdir /etc/DOAZLAB 10 | cd /etc/DOAZLAB 11 | wget https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-Linux/scripts/Install-Tools.sh 12 | wget https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/main/Deploy-Linux/scripts/RunAtReboot.sh 13 | chmod +x Install-Tools.sh 14 | chmod +x RunAtReboot.sh 15 | 16 | 17 | # Add key 18 | sudo -u doadmin mkdir -p "/home/doadmin/.ssh" 19 | sudo chmod 700 "/home/doadmin/.ssh" 20 | echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1XxoXD/oHJU9hcJc4Gv0+1ZKXZrd4eyoqbG0RVMBwXfylc45OjI4oQswK0sQGthzw+kjUZb90dckPIOl0GFPZCsEvInnvBJaCjsS5wKsq7bohnRJUP8cDXXOh4yrCScMvBd8o1xKbPQvarf+kSrbp4pF3sdhqwPjfMOq0fjvUMuprfjiWVxOCmCefhyOtUgvRhFEQSSbtPN6SMtPqgRKmtXwsMNwUWWvOJXfrOQl5WJRoDcvHsz9NlR2NXLeBvAZw/XnYeUyCv2Qwl5TaFk6/L1uxshAgt1n86HOoJDnAdcXieHA3Hr6iAY+YhW5TIWN4OMp1MpJUHBCD67n8ANBa5tgByhcafNMPqHFiE2bo/zEHKz9nTkjNImChu/0n4hAWjrfJgooTC9oLa1ZyuvGLneYcuNasZBkBw255l0AFgrZez7rWqLDhyCxb4T1HHwcj0GScpyttAFAEKNTRVfy3DsNFaWkvwoa1a0Mghcvz/D07jL4vqW6gcvgvQ6aYABCFNMrF+3PFnAz/LUH7d0ntplXInM2pZmqHI4dacYUgf1bJI+aUFkT6X9weZZdwVoDyfK8m2Kp3WkZr3r8oKz65fw8q2nUtmuCDgOfUwOL8PNwl3orJsJn9kDVebKmbodP7TUILHJ4etbSaoIrlcmaO+KMbdjdX+hJ2b34SkIMpXQ== doadmin@Nux01" >> /home/doadmin/.ssh/authorized_keys 21 | sudo chmod 600 "/home/doadmin/.ssh/authorized_keys" 22 | sudo chown -R doadmin:doadmin "/home/doadmin/.ssh" 23 | 24 | # Add Log 25 | touch /etc/DOAZLAB/DOAZLABLog 26 | 27 | ## Add Crontab for RunAtReboot 28 | echo "Time: $(date). Updating Crontab for RunAtReboot" >> /etc/DOAZLAB/DOAZLABLog 29 | echo @reboot root /etc/DOAZLAB/RunAtReboot.sh >> /etc/crontab 30 | 31 | #add RunOnceTrigger 32 | echo "Time: $(date). Adding Tool Install Trigger RunAtReboot" >> /etc/DOAZLAB/DOAZLABLog 33 | touch /etc/DOAZLAB/RunInstallToolsAtNextReboot 34 | 35 | # Get updated APT Packages and Upgrade 36 | echo "Time: $(date). Updating Packages and Upgrading" >> /etc/DOAZLAB/DOAZLABLog 37 | export DEBIAN_FRONTEND=noninteractive 38 | apt-get update 39 | apt-get upgrade -y 40 | 41 | # Reboot 42 | echo "Time: $(date). Rebooting" >> /etc/DOAZLAB/DOAZLABLog 43 | shutdown -r +1 -------------------------------------------------------------------------------- /Deploy-Linux/scripts/Install-Tools.sh: -------------------------------------------------------------------------------- 1 | ## Script is currently choking on a kernel mismatch and pending reboot 2 | 3 | #!/bin/bash 4 | 5 | # Check if user is root 6 | if [[ $EUID -ne 0 ]]; then 7 | echo "This script must be run as root" 1>&2 8 | exit 1 9 | fi 10 | 11 | # apt packages 12 | # apt-get update -y && apt-get full-upgrade -y 13 | apt-get update -y 14 | apt-get install python3 -y 15 | apt-get install virtualenv -y 16 | apt-get install python3-distutils python3-virtualenv libssl-dev libffi-dev python-dev-is-python3 build-essential smbclient libpcap-dev apt-transport-https -y 17 | apt-get install vim-nox htop ncat rlwrap golang jq feroxbuster silversearcher-ag testssl.sh nmap masscan proxychains4 -y 18 | apt-get install python3.11-venv -y 19 | apt-get install golang-go -y 20 | apt-get install proxychains -y 21 | apt-get install onesixtyone snmp-mibs-downloader -y 22 | apt-get install net-tools 23 | apt-get install zsh 24 | # Install latest metasploit 25 | gem install bundler 26 | apt-get install metasploit-framework -y 27 | 28 | # remove outdated packages 29 | apt-get autoremove -y 30 | 31 | # Install neo4j 32 | echo "deb http://httpredir.debian.org/debian stretch-backports main" | sudo tee -a /etc/apt/sources.list.d/stretch-backports.list 33 | wget -O - https://debian.neo4j.com/neotechnology.gpg.key | sudo apt-key add - 34 | echo 'deb https://debian.neo4j.com stable 4.0' > /etc/apt/sources.list.d/neo4j.list 35 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0E98404D386FA1D9 648ACFD622F3D138 36 | apt update 37 | apt install neo4j -y 38 | systemctl stop neo4j 39 | echo "dbms.default_listen_address=10.0.0.8" >> /etc/neo4j/neo4j.conf 40 | # don't open the console dave. especially not during bootstrap 41 | systemctl start neo4j 42 | 43 | # update snmp.conf 44 | sed -e '/mibs/ s/^#*/#/' -i /etc/snmp/snmp.conf 45 | 46 | # Repos 47 | [[ ! -d /opt/testssl.sh ]] && git clone --depth 1 https://github.com/drwetter/testssl.sh.git /opt/testssl.sh 48 | [[ ! -d /opt/Responder ]] && git clone https://github.com/lgandx/Responder.git /opt/Responder 49 | [[ ! -d /opt/impacket ]] && git clone https://github.com/fortra/impacket.git /opt/impacket 50 | [[ ! -d /opt/BloodHound.py ]] && git clone https://github.com/fox-it/BloodHound.py.git /opt/BloodHound.py 51 | [[ ! -d /opt/Certipy ]] && git clone https://github.com/DefensiveOrigins/certipy.git /opt/Certipy 52 | [[ ! -d /opt/Coercer ]] && git clone https://github.com/p0dalirius/Coercer.git /opt/Coercer 53 | [[ ! -d /opt/mitm6 ]] && git clone https://github.com/dirkjanm/mitm6.git /opt/mitm6 54 | [[ ! -d /opt/PCredz ]] && git clone https://github.com/lgandx/PCredz.git /opt/PCredz 55 | [[ ! -d /opt/certsync ]] && git clone https://github.com/zblurx/certsync.git /opt/certsync 56 | [[ ! -d /opt/pyLAPS ]] && git clone https://github.com/p0dalirius/pyLAPS.git /opt/pyLAPS 57 | [[ ! -d /opt/PlumHound ]] && git clone https://github.com/PlumHound/PlumHound.git /opt/PlumHound 58 | [[ ! -d /opt/CrackMapExec ]] && git clone https://github.com/byt3bl33d3r/CrackMapExec.git /opt/CrackMapExec 59 | 60 | cat << 'EOF' >> "${HOME}/.screenrc" 61 | termcapinfo * ti@:te@ 62 | caption always 63 | caption string "%{kw}%-w%{wr}%n %t%{-}%+w" 64 | startup_message off 65 | defscrollback 1000000 66 | EOF 67 | 68 | # setup GOPATH. Lots of confusion about GOPATH and GOMODULES 69 | # this will need rectified for bash or the implant / nux build needs shell swapped to zsh 70 | # see https://zchee.github.io/golang-wiki/GOPATH/ and https://maelvls.dev/go111module-everywhere/ for more info 71 | # TL:DR 72 | # GOPATH is still supported even though it has been replaced by Go modules and is technically deprecated since Go 1.16, BUT, you can still use GOPATH to specify where you want your go binaries installed. 73 | wget https://go.dev/dl/go1.21.4.linux-amd64.tar.gz 74 | tar -C ~/ -xzf go1.21.4.linux-amd64.tar.gz 75 | 76 | [[ ! -d "${HOME}/go" ]] && mkdir "${HOME}/go" 77 | if [[ -z "${GOPATH}" ]]; then 78 | cat << 'EOF' >> "${HOME}/.zshrc" 79 | 80 | # Add ~/go/bin to path 81 | [[ ":$PATH:" != *":${HOME}/go/bin:"* ]] && export PATH="${PATH}:${HOME}/go/bin" 82 | # Set GOPATH 83 | if [[ -z "${GOPATH}" ]]; then export GOPATH="${HOME}/go"; fi 84 | EOF 85 | fi 86 | 87 | [[ ":$PATH:" != *":${HOME}/go/bin:"* ]] && export PATH="${PATH}:${HOME}/go/bin" 88 | # Set GOPATH 89 | if [[ -z "${GOPATH}" ]]; then export GOPATH="${HOME}/go"; fi 90 | 91 | # Install your favorite Go binaries 92 | # GO111MODULE=on go install github.com/mr-pmillz/gorecon/v2@latest Use the private version from our Gitlab 93 | GO111MODULE=on go install github.com/ropnop/kerbrute@latest 94 | GO111MODULE=on go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest 95 | GO111MODULE=on go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest 96 | GO111MODULE=on go install -v github.com/OJ/gobuster/v3@latest 97 | GO111MODULE=on go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest 98 | [[ -f "${HOME}/go/bin/nuclei" ]] && nuclei -ut || echo "nuclei not in ${HOME}/go/bin/" 99 | 100 | # create virtualenv dir. 101 | [[ ! -d "${HOME}/pyenv" ]] && mkdir "${HOME}/pyenv" 102 | 103 | # ignore shellcheck warnings for source commands 104 | # shellcheck source=/dev/null 105 | install_with_virtualenv() { 106 | REPO_NAME="$1" 107 | PYENV="${HOME}/pyenv" 108 | if [ -d "/opt/${REPO_NAME}" ]; then 109 | cd "/opt/${REPO_NAME}" || exit 1 110 | virtualenv -p python3 "${PYENV}/${REPO_NAME}" 111 | . "${PYENV}/${REPO_NAME}/bin/activate" 112 | python3 -m pip install -U wheel setuptools 113 | # first, ensure that requirements.txt deps are installed. 114 | [[ -f requirements.txt ]] && python3 -m pip install -r requirements.txt 115 | # python3 setup.py install is deprecated in versions >= python3.9.X 116 | # python3 -m pip install . will handle the setup.py file for you. 117 | [[ -f setup.py || -f pyproject.toml ]] && python3 -m pip install . 118 | deactivate 119 | cd - &>/dev/null || exit 1 120 | else 121 | echo -e "${REPO_NAME} does not exist." 122 | fi 123 | } 124 | 125 | install_with_virtualenv Responder 126 | install_with_virtualenv impacket 127 | install_with_virtualenv BloodHound.py 128 | install_with_virtualenv PlumHound 129 | install_with_virtualenv Certipy 130 | install_with_virtualenv Coercer 131 | install_with_virtualenv mitm6 132 | 133 | install_pipx() { 134 | # check if pipx is already installed 135 | PIPX_EXISTS=$(which pipx) 136 | if [ -z "$PIPX_EXISTS" ]; then 137 | # Get the Python 3 version 138 | python_version_output=$(python3 --version 2>&1) 139 | python_version=$(echo "$python_version_output" | awk '{print $2}' | cut -d '.' -f 1,2) 140 | 141 | if [ "$python_version" == "3.10" ] || [ "$python_version" == "3.11" ] || [ "$python_version" == "3.12" ]; then 142 | python3 -m pip install pipx --break-system-packages || python3 -m pip install pipx 143 | elseapt update 144 | 145 | } 146 | 147 | install_pipx 148 | 149 | #Fix Certipy 150 | cd /opt/Certipy 151 | source /root/pyenv/Certipy/bin/activate 152 | pip3 uninstall pyOpenSSL -y 153 | pip3 install pyOpenSSL==24.0.0 154 | python3 setup.py install 155 | deactivate 156 | -------------------------------------------------------------------------------- /Deploy-Linux/scripts/RunAtReboot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | # Log Entering Script 6 | echo "Time: $(date). RunAtReboot Starting" >> /etc/DOAZLAB/DOAZLABLog 7 | 8 | 9 | # If RunOnce trigger file (RunInstallToolsAtNextReboot) exists, run Install-Tools and delete trigger -- else do nothing except update log 10 | if test -f /etc/DOAZLAB/RunInstallToolsAtNextReboot; then 11 | echo "Time: $(date). Triggering Tool Install." >> /etc/DOAZLAB/DOAZLABLog 12 | /bin/bash /etc/DOAZLAB/Install-Tools.sh 13 | echo "Time: $(date). Removing Install Trigger" >> /etc/DOAZLAB/DOAZLABLog 14 | rm /etc/DOAZLAB/RunInstallToolsAtNextReboot 15 | fi 16 | 17 | # Log Exiting Script 18 | echo "Time: $(date). RunAtReboot Finishing" >> /etc/DOAZLAB/DOAZLABLog 19 | -------------------------------------------------------------------------------- /Deploy-Linux/scripts/makekey.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the target user 4 | USER="doadmin" 5 | USER_HOME="/home/$USER" 6 | 7 | # Generate a new SSH key pair (without passphrase) 8 | sudo -u $USER ssh-keygen -t rsa -b 4096 -f "$USER_HOME/.ssh/id_rsa" -N "" 9 | 10 | # Ensure the .ssh directory exists and has the correct permissions 11 | sudo -u $USER mkdir -p "$USER_HOME/.ssh" 12 | sudo chmod 700 "$USER_HOME/.ssh" 13 | 14 | # Add the new public key to authorized_keys 15 | sudo -u $USER cat "$USER_HOME/.ssh/id_rsa.pub" >> "$USER_HOME/.ssh/authorized_keys" 16 | 17 | # Set appropriate permissions for authorized_keys 18 | sudo chmod 600 "$USER_HOME/.ssh/authorized_keys" 19 | 20 | # Ensure ownership is correct 21 | sudo chown -R $USER:$USER "$USER_HOME/.ssh" 22 | 23 | echo "SSH key has been generated and added to authorized_keys for $USER." 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Deploy-NetPeering/azuredeploy-netpeering.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "ad-net-id": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "AD Network ID" 9 | } 10 | }, 11 | "linux-net-id": { 12 | "type": "string", 13 | "metadata": { 14 | "description": "Linux Network ID" 15 | } 16 | }, 17 | "location": { 18 | "type": "string", 19 | "defaultValue": "[resourceGroup().location]", 20 | "metadata": { 21 | "description": "Location for all resources." 22 | } 23 | } 24 | }, 25 | "variables": {}, 26 | "resources": [ 27 | { 28 | "name": "vnet-c2/peering-to-remote-vnet-win", 29 | "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", 30 | "apiVersion": "2019-11-01", 31 | "location": "[parameters('location')]", 32 | "properties": { 33 | "allowVirtualNetworkAccess": true, 34 | "allowForwardedTraffic": false, 35 | "allowGatewayTransit": false, 36 | "useRemoteGateways": false, 37 | "remoteVirtualNetwork": { 38 | "id": "[parameters('ad-net-id')]" 39 | } 40 | } 41 | }, 42 | { 43 | "name": "vnet-win/peering-to-remote-vnet-c2", 44 | "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", 45 | "apiVersion": "2019-11-01", 46 | "location": "[parameters('location')]", 47 | "properties": { 48 | "allowVirtualNetworkAccess": true, 49 | "allowForwardedTraffic": false, 50 | "allowGatewayTransit": false, 51 | "useRemoteGateways": false, 52 | "remoteVirtualNetwork": { 53 | "id": "[parameters('linux-net-id')]" 54 | } 55 | } 56 | } 57 | ], 58 | "outputs": {} 59 | } -------------------------------------------------------------------------------- /Deploy-Sentinel/deploy-sysmonparser.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "Workspace": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "The Microsoft Sentinel workspace into which the function will be deployed. Has to be in the selected Resource Group." 9 | } 10 | }, 11 | "WorkspaceRegion": { 12 | "type": "string", 13 | "defaultValue": "[resourceGroup().location]", 14 | "metadata": { 15 | "description": "The region of the selected workspace. The default value will use the Region selection above." 16 | } 17 | } 18 | }, 19 | "resources": [ 20 | { 21 | "type": "Microsoft.OperationalInsights/workspaces/savedSearches", 22 | "apiVersion": "2020-08-01", 23 | "name": "[concat(parameters('Workspace'), '/SysmonParser2')]", 24 | "location": "[parameters('WorkspaceRegion')]", 25 | "properties": { 26 | "etag": "*", 27 | "displayName": "SysmonParser2", 28 | "category": "Sysmon", 29 | "FunctionAlias": "SysmonParser2", 30 | "query": "let timeframe = \"{time_range}\"; \nlet EventData = Event \n| where Source == \"Microsoft-Windows-Sysmon\" \n| extend RenderedDescription = tostring(split(RenderedDescription, \":\")[0]) \n| project TimeGenerated, Source, EventID, Computer, UserName, EventData, RenderedDescription \n| extend EvData = parse_xml(EventData) \n| extend EventDetail = EvData.DataItem.EventData.Data \n| project-away EventData, EvData; \nlet SysmonEvent1_ProcessCreate=() { \nlet processEvents = EventData \n| where EventID == 1 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], \nfile_version = EventDetail.[5].[\"#text\"], file_description = EventDetail.[6].[\"#text\"], file_product = EventDetail.[7].[\"#text\"], file_company = EventDetail.[8].[\"#text\"], file_name = EventDetail.[9].[\"#text\"], \nprocess_command_line = EventDetail.[10].[\"#text\"], file_directory = EventDetail.[11].[\"#text\"], user_name = EventDetail.[12].[\"#text\"], user_logon_guid = EventDetail.[13].[\"#text\"], \nuser_logon_id = EventDetail.[14].[\"#text\"], user_session_id = EventDetail.[15].[\"#text\"], process_integrity_level = EventDetail.[16].[\"#text\"], Hashes = EventDetail.[17].[\"#text\"], \nprocess_parent_guid = EventDetail.[18].[\"#text\"], process_parent_id = EventDetail.[19].[\"#text\"], process_parent_path = EventDetail.[20].[\"#text\"], process_parent_command_line = EventDetail.[21].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash \n| project-away EventDetail, rule_name, Hashes \n; \nprocessEvents; \n}; \nlet SysmonEvent2_FileCreateTime=() { \nlet processEvents = EventData \n| where EventID == 2 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], \nfile_path = EventDetail.[5].[\"#text\"], file_creation_time = EventDetail.[6].[\"#text\"], file_previous_creation_time = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash \n| project-away EventDetail, rule_name, Hashes \n; \nprocessEvents; \n}; \nlet SysmonEvent3_NetworkConnect=() { \nlet processEvents = EventData \n| where EventID == 3 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], \nuser_name = EventDetail.[5].[\"#text\"], network_protocol = EventDetail.[6].[\"#text\"], network_connection_initiated = EventDetail.[7].[\"#text\"], src_is_ipv6 = EventDetail.[8].[\"#text\"], src_ip = EventDetail.[9].[\"#text\"], \nsrc_host_name = EventDetail.[10].[\"#text\"], src_port = EventDetail.[11].[\"#text\"], src_port_name = EventDetail.[12].[\"#text\"], dst_is_ipv6 = EventDetail.[13].[\"#text\"], \ndst_ip = EventDetail.[14].[\"#text\"], dst_host_name = EventDetail.[15].[\"#text\"], dst_port = EventDetail.[16].[\"#text\"], dst_port_name = EventDetail.[17].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent4_ServiceStateChange=() { \nlet processEvents = EventData \n| where EventID == 4 \n| extend event_creation_time = EventDetail.[0].[\"#text\"], service_state = EventDetail.[1].[\"#text\"], sysmon_schema = EventDetail.[2].[\"#text\"], sysmon_schema_version = EventDetail.[3].[\"#text\"] \n| project-away EventDetail \n; \nprocessEvents; \n}; \nlet SysmonEvent5_ProcessTerminate=() { \nlet processEvents = EventData \n| where EventID == 5 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent6_DriverLoad=() { \nlet processEvents = EventData \n| where EventID == 6 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_pathLoaded = EventDetail.[2].[\"#text\"], Hashes = EventDetail.[3].[\"#text\"], \ndriver_is_signed = EventDetail.[4].[\"#text\"], driver_signature = EventDetail.[5].[\"#text\"], driver_signature_status = EventDetail.[6].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent7_ImageLoad=() { \nlet processEvents = EventData \n| where EventID == 7 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], \nmodule_loaded = EventDetail.[5].[\"#text\"], file_version = EventDetail.[6].[\"#text\"],file_description = EventDetail.[7].[\"#text\"], file_product = EventDetail.[8].[\"#text\"], file_company = EventDetail.[9].[\"#text\"], \nHashes = EventDetail.[11].[\"#text\"], module_is_signed = EventDetail.[12].[\"#text\"], module_signature = EventDetail.[13].[\"#text\"], module_signature_status = EventDetail.[14].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent8_CreateRemoteThread=() { \nlet processEvents = EventData \n| where EventID == 8 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], \nprocess_path = EventDetail.[4].[\"#text\"], target_process_guid = EventDetail.[5].[\"#text\"], target_process_id = EventDetail.[6].[\"#text\"], target_process_path = EventDetail.[7].[\"#text\"], \nthread_new_id = EventDetail.[8].[\"#text\"], thread_start_address = EventDetail.[9].[\"#text\"], thread_start_module = EventDetail.[10].[\"#text\"], thread_start_function = EventDetail.[11].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent9_RawAccessRead=() { \nlet processEvents = EventData \n| where EventID == 9 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], target_device = EventDetail.[5].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent10_ProcessAccess=() { \nlet processEvents = EventData \n| where EventID == 10 \n| extend rule_name = EventDetail.[0].[\"#text\"],UtcTime = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], \nthread_id = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"], target_process_guid = EventDetail.[6].[\"#text\"], target_process_id = EventDetail.[7].[\"#text\"], \ntarget_process_path = EventDetail.[8].[\"#text\"],process_granted_access = EventDetail.[9].[\"#text\"], process_call_trace = EventDetail.[10].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent11_FileCreate=() { \nlet processEvents = EventData \n| where EventID == 11 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], \nprocess_path = EventDetail.[4].[\"#text\"], file_name = EventDetail.[5].[\"#text\"], file_creation_time = EventDetail.[6].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent12_RegistryObjectAddDel=() { \nlet processEvents = EventData \n| where EventID == 12 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], process_guid = EventDetail.[3].[\"#text\"], \nprocess_id = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],registry_key_path = EventDetail.[6].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent13_RegistrySetValue=() { \nlet processEvents = EventData \n| where EventID == 13 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], process_guid = EventDetail.[3].[\"#text\"], \nprocess_id = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],registry_key_path = EventDetail.[6].[\"#text\"],registry_key_details = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent14_RegistryObjectRename=() { \nlet processEvents = EventData \n| where EventID == 14 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], process_guid = EventDetail.[3].[\"#text\"], \nprocess_id = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],registry_key_path = EventDetail.[6].[\"#text\"],registry_key_new_name = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent15_FileCreateStreamHash=() { \nlet processEvents = EventData \n| where EventID == 15 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], \nprocess_path = EventDetail.[4].[\"#text\"],file_name = EventDetail.[5].[\"#text\"],file_creation_time = EventDetail.[6].[\"#text\"],hash = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent16_ConfigChange=() { \nlet processEvents = EventData \n| where EventID == 16 \n| extend event_creation_time = EventDetail.[0].[\"#text\"], sysmon_configuration = EventDetail.[1].[\"#text\"], sysmon_configuration_hash = EventDetail.[2].[\"#text\"] \n| project-away EventDetail \n; \nprocessEvents; \n}; \nlet SysmonEvent17_CreateNamedPipe=() { \nlet processEvents = EventData \n| where EventID == 17 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], process_guid = EventDetail.[3].[\"#text\"], process_id = EventDetail.[4].[\"#text\"], pipe_name = EventDetail.[5].[\"#text\"], \nprocess_path = EventDetail.[6].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent18_ConnectNamedPipe=() { \nlet processEvents = EventData \n| where EventID == 18 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], process_guid = EventDetail.[3].[\"#text\"], process_id = EventDetail.[4].[\"#text\"], pipe_name = EventDetail.[5].[\"#text\"], \nprocess_path = EventDetail.[6].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent19_WMIEventFilter=() { \nlet processEvents = EventData \n| where EventID == 19 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], wmi_operation = EventDetail.[3].[\"#text\"], \nuser_name = EventDetail.[4].[\"#text\"],wmi_namespace = EventDetail.[5].[\"#text\"],wmi_filter_name = EventDetail.[6].[\"#text\"],wmi_query = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent20_WMIEventConsumer=() { \nlet processEvents = EventData \n| where EventID == 20 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], wmi_operation = EventDetail.[3].[\"#text\"], \nuser_name = EventDetail.[4].[\"#text\"],wmi_consumer_name = EventDetail.[5].[\"#text\"],wmi_consumer_type = EventDetail.[6].[\"#text\"],wmi_consumer_destination = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent21_WMIEventConsumerToFilter=() { \nlet processEvents = EventData \n| where EventID == 21 \n| extend rule_name = EventDetail.[0].[\"#text\"], EventType = EventDetail.[1].[\"#text\"], event_creation_time = EventDetail.[2].[\"#text\"], wmi_operation = EventDetail.[3].[\"#text\"], \nuser_name = EventDetail.[4].[\"#text\"],wmi_consumer_path = EventDetail.[5].[\"#text\"],Type = EventDetail.[6].[\"#text\"],wmi_filter_path = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent22_DNSEvents=() { \nlet processEvents = EventData \n| where EventID == 22 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], dns_query_name = EventDetail.[4].[\"#text\"],dns_query_status = EventDetail.[5].[\"#text\"],dns_query_results = EventDetail.[6].[\"#text\"],process_path = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent23_FileDeleteArchived=() { \nlet processEvents = EventData \n| where EventID == 23 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], user_name = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],target_filename = EventDetail.[6].[\"#text\"],file_hashes = EventDetail.[7].[\"#text\"],is_executable = EventDetail.[8].[\"#text\"],is_archived = EventDetail.[9].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent24_ClipboardChange=() { \nlet processEvents = EventData \n| where EventID == 24 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], session = EventDetail.[5].[\"#text\"], client_info = EventDetail.[6].[\"#text\"], hashes = EventDetail.[7].[\"#text\"], is_archived = EventDetail.[8].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent25_ProcessTampering=() { \nlet processEvents = EventData \n| where EventID == 25 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], process_path = EventDetail.[4].[\"#text\"], type = EventDetail.[5].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent26_FileDeleteLogged=() { \nlet processEvents = EventData \n| where EventID == 26 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], user_name = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],target_filename = EventDetail.[6].[\"#text\"],file_hashes = EventDetail.[7].[\"#text\"], is_executable = EventDetail.[8].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent27_FileBlockExecutable=() { \nlet processEvents = EventData \n| where EventID == 27 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], user_name = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],target_filename = EventDetail.[6].[\"#text\"],file_hashes = EventDetail.[7].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \nlet SysmonEvent28_FileBlockShredding=() { \nlet processEvents = EventData \n| where EventID == 28 \n| extend rule_name = EventDetail.[0].[\"#text\"], event_creation_time = EventDetail.[1].[\"#text\"], process_guid = EventDetail.[2].[\"#text\"], process_id = EventDetail.[3].[\"#text\"], user_name = EventDetail.[4].[\"#text\"],process_path = EventDetail.[5].[\"#text\"],target_filename = EventDetail.[6].[\"#text\"],file_hashes = EventDetail.[7].[\"#text\"], is_executable = EventDetail.[8].[\"#text\"] \n| parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name \n| project-away EventDetail, rule_name \n; \nprocessEvents; \n}; \n(union isfuzzy=true \nSysmonEvent1_ProcessCreate,SysmonEvent2_FileCreateTime,SysmonEvent3_NetworkConnect,SysmonEvent4_ServiceStateChange,SysmonEvent5_ProcessTerminate, \nSysmonEvent6_DriverLoad,SysmonEvent7_ImageLoad,SysmonEvent8_CreateRemoteThread,SysmonEvent9_RawAccessRead,SysmonEvent10_ProcessAccess, \nSysmonEvent11_FileCreate,SysmonEvent12_RegistryObjectAddDel,SysmonEvent13_RegistrySetValue,SysmonEvent14_RegistryObjectRename, \nSysmonEvent15_FileCreateStreamHash,SysmonEvent16_ConfigChange,SysmonEvent17_CreateNamedPipe,SysmonEvent18_ConnectNamedPipe, \nSysmonEvent19_WMIEventFilter,SysmonEvent20_WMIEventConsumer,SysmonEvent21_WMIEventConsumerToFilter,SysmonEvent22_DNSEvents,SysmonEvent23_FileDeleteArchived,SysmonEvent24_ClipboardChange,SysmonEvent25_ProcessTampering,SysmonEvent26_FileDeleteLogged,SysmonEvent27_FileBlockExecutable,SysmonEvent28_FileBlockShredding)", 31 | "version": 1, 32 | "functionParameters": "starttime:datetime=datetime(null),endtime:datetime=datetime(null),eventtype_in:dynamic=dynamic([]),srcipaddr_has_any_prefix:dynamic=dynamic([]),actorusername_has_any:dynamic=dynamic([]),targetfilepath_has_any:dynamic=dynamic([]),srcfilepath_has_any:dynamic=dynamic([]),hashes_has_any:dynamic=dynamic([]),dvchostname_has_any:dynamic=dynamic([]),disabled:bool=False" 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /Deploy-Sentinel/deploy-sysmonparser_new.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "Workspace": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "The Microsoft Sentinel workspace into which the function will be deployed. Has to be in the selected Resource Group." 9 | } 10 | }, 11 | "WorkspaceRegion": { 12 | "type": "string", 13 | "defaultValue": "[resourceGroup().location]", 14 | "metadata": { 15 | "description": "The region of the selected workspace. The default value will use the Region selection above." 16 | } 17 | } 18 | }, 19 | "resources": [ 20 | { 21 | "type": "Microsoft.OperationalInsights/workspaces/savedSearches", 22 | "apiVersion": "2020-08-01", 23 | "name": "[concat(parameters('Workspace'), '/SysmonParser3')]", 24 | "location": "[parameters('WorkspaceRegion')]", 25 | "properties": { 26 | "etag": "*", 27 | "displayName": "SysmonParser3", 28 | "category": "Sysmon", 29 | "FunctionAlias": "SysmonParser3", 30 | "query": "// KQL Sysmon Event Parser\r\n// Last Updated Date: October 19, 2022\r\n// Sysmon Version: Applicable to all versions\r\n//\r\n// Sysmon Instructions:\r\n// If you want to print configuration schema definition of sysmon. Execute below command from command shell or powershell terminal\r\n// Sysmon.exe -s\r\n//\r\n// You can further customize config XML definition and install sysmon with it via below command. \r\n// Sample Sysmon config XML from Swift on Security's GitHub page : https://github.com/SwiftOnSecurity/sysmon-config/blob/master/sysmonconfig-export.xml\r\n// Sysmon.exe -i sysmonconfig-export.xml -accepteula -h sha1,md5,sha256 -n -l \r\n// -n : Log all network connections and -l: log loading of modules.\r\n//\r\n// Parser Notes:\r\n// This parser works against all versions unless original event manifest is changed\r\n// \r\n//\r\n// Usage Instruction : \r\n// Paste below query in log analytics, click on Save button and select as Function from drop down by specifying function name and alias (e.g. Sysmon_Normalized).\r\n// Function usually takes 10-15 minutes to activate. You can then use function alias from any other queries (e.g. Sysmon_Normalized | take 10).\r\n// Reference :\r\n// Using functions in Azure monitor log queries : https://docs.microsoft.com/azure/azure-monitor/log-query/functions\r\n// Tech Community Blog on KQL Functions : https://techcommunity.microsoft.com/t5/Azure-Sentinel/Using-KQL-functions-to-speed-up-analysis-in-Azure-Sentinel/ba-p/712381\r\n//\r\nEvent\r\n| where Source == \"Microsoft-Windows-Sysmon\"\r\n| extend RenderedDescription = tostring(split(RenderedDescription, \":\")[0])\r\n| extend EventData = parse_xml(EventData).DataItem.EventData.Data\r\n| mv-expand bagexpansion=array EventData\r\n| evaluate bag_unpack(EventData)\r\n| extend Key = tostring(column_ifexists('@Name', \"\")), Value = tostring(column_ifexists('#text', \"\"))\r\n| evaluate pivot(Key, any(Value), TimeGenerated, Source, EventLog, Computer, EventLevel, EventLevelName, EventID, UserName, RenderedDescription, MG, ManagementGroupName, _ResourceId)\r\n| extend TimeGenerated = column_ifexists(\"TimeGenerated\", \"\"), Source = column_ifexists(\"Source\", \"\"), EventLog = column_ifexists(\"EventLog\", \"\"), Computer = column_ifexists(\"Computer\", \"\"), EventLevel = column_ifexists(\"EventLevel\", \"\"), EventLevelName = column_ifexists(\"EventLevelName\", \"\"), EventID = column_ifexists(\"EventID\", \"\"), UserName = column_ifexists(\"UserName\", \"\"), RenderedDescription = column_ifexists(\"RenderedDescription\", \"\"), MG = column_ifexists(\"MG\", \"\"), ManagementGroupName = column_ifexists(\"ManagementGroupName\", \"\"), _ResourceId = column_ifexists(\"_ResourceId\", \"\"), UtcTime = column_ifexists(\"UtcTime\", \"\"), ID = column_ifexists(\"ID\", \"\"), Description = column_ifexists(\"Description\", \"\"), RuleName = column_ifexists(\"RuleName\", \"\"), ProcessGuid = column_ifexists(\"ProcessGuid\", \"\"), ProcessId = column_ifexists(\"ProcessId\", \"\"), Image = column_ifexists(\"Image\", \"\"), FileVersion = column_ifexists(\"FileVersion\", \"\"), Product = column_ifexists(\"Product\", \"\"), Company = column_ifexists(\"Company\", \"\"), OriginalFileName = column_ifexists(\"OriginalFileName\", \"\"), CommandLine = column_ifexists(\"CommandLine\", \"\"), CurrentDirectory = column_ifexists(\"CurrentDirectory\", \"\"), User = column_ifexists(\"User\", \"\"), LogonGuid = column_ifexists(\"LogonGuid\", \"\"), LogonId = column_ifexists(\"LogonId\", \"\"), TerminalSessionId = column_ifexists(\"TerminalSessionId\", \"\"), IntegrityLevel = column_ifexists(\"IntegrityLevel\", \"\"), Hashes = column_ifexists(\"Hashes\", \"\"), ParentProcessGuid = column_ifexists(\"ParentProcessGuid\", \"\"), ParentProcessId = column_ifexists(\"ParentProcessId\", \"\"), ParentImage = column_ifexists(\"ParentImage\", \"\"), ParentCommandLine = column_ifexists(\"ParentCommandLine\", \"\"), ParentUser = column_ifexists(\"ParentUser\", \"\"), TargetFilename = column_ifexists(\"TargetFilename\", \"\"), CreationUtcTime = column_ifexists(\"CreationUtcTime\", \"\"), PreviousCreationUtcTime = column_ifexists(\"PreviousCreationUtcTime\", \"\"), Protocol = column_ifexists(\"Protocol\", \"\"), Initiated = column_ifexists(\"Initiated\", \"\"), SourceIsIpv6 = column_ifexists(\"SourceIsIpv6\", \"\"), SourceIp = column_ifexists(\"SourceIp\", \"\"), SourceHostname = column_ifexists(\"SourceHostname\", \"\"), SourcePort = column_ifexists(\"SourcePort\", \"\"), SourcePortName = column_ifexists(\"SourcePortName\", \"\"), DestinationIsIpv6 = column_ifexists(\"DestinationIsIpv6\", \"\"), DestinationIp = column_ifexists(\"DestinationIp\", \"\"), DestinationHostname = column_ifexists(\"DestinationHostname\", \"\"), DestinationPort = column_ifexists(\"DestinationPort\", \"\"), DestinationPortName = column_ifexists(\"DestinationPortName\", \"\"), State = column_ifexists(\"State\", \"\"), Version = column_ifexists(\"Version\", \"\"), SchemaVersion = column_ifexists(\"SchemaVersion\", \"\"), ImageLoaded = column_ifexists(\"ImageLoaded\", \"\"), Signed = column_ifexists(\"Signed\", \"\"), Signature = column_ifexists(\"Signature\", \"\"), SignatureStatus = column_ifexists(\"SignatureStatus\", \"\"), SourceProcessGuid = column_ifexists(\"SourceProcessGuid\", \"\"), SourceProcessId = column_ifexists(\"SourceProcessId\", \"\"), SourceImage = column_ifexists(\"SourceImage\", \"\"), TargetProcessGuid = column_ifexists(\"TargetProcessGuid\", \"\"), TargetProcessId = column_ifexists(\"TargetProcessId\", \"\"), TargetImage = column_ifexists(\"TargetImage\", \"\"), NewThreadId = column_ifexists(\"NewThreadId\", \"\"), StartAddress = column_ifexists(\"StartAddress\", \"\"), StartModule = column_ifexists(\"StartModule\", \"\"), StartFunction = column_ifexists(\"StartFunction\", \"\"), SourceUser = column_ifexists(\"SourceUser\", \"\"), TargetUser = column_ifexists(\"TargetUser\", \"\"), Device = column_ifexists(\"Device\", \"\"), SourceProcessGUID = column_ifexists(\"SourceProcessGUID\", \"\"), SourceThreadId = column_ifexists(\"SourceThreadId\", \"\"), TargetProcessGUID = column_ifexists(\"TargetProcessGUID\", \"\"), GrantedAccess = column_ifexists(\"GrantedAccess\", \"\"), CallTrace = column_ifexists(\"CallTrace\", \"\"), EventType = column_ifexists(\"EventType\", \"\"), TargetObject = column_ifexists(\"TargetObject\", \"\"), Details = column_ifexists(\"Details\", \"\"), NewName = column_ifexists(\"NewName\", \"\"), Hash = column_ifexists(\"Hash\", \"\"), Contents = column_ifexists(\"Contents\", \"\"), Configuration = column_ifexists(\"Configuration\", \"\"), ConfigurationFileHash = column_ifexists(\"ConfigurationFileHash\", \"\"), PipeName = column_ifexists(\"PipeName\", \"\"), Operation = column_ifexists(\"Operation\", \"\"), EventNamespace = column_ifexists(\"EventNamespace\", \"\"), Name = column_ifexists(\"Name\", \"\"), Query = column_ifexists(\"Query\", \"\"), Type = column_ifexists(\"Type\", \"\"), Destination = column_ifexists(\"Destination\", \"\"), Consumer = column_ifexists(\"Consumer\", \"\"), Filter = column_ifexists(\"Filter\", \"\"), QueryName = column_ifexists(\"QueryName\", \"\"), QueryStatus = column_ifexists(\"QueryStatus\", \"\"), QueryResults = column_ifexists(\"QueryResults\", \"\"), IsExecutable = column_ifexists(\"IsExecutable\", \"\"), Archived = column_ifexists(\"Archived\", \"\"), Session = column_ifexists(\"Session\", \"\"), ClientInfo = column_ifexists(\"ClientInfo\", \"\")\r\n// Fix for wrong casing in EventID10\r\n| extend SourceProcessGuid=iff(isnotempty(SourceProcessGUID),SourceProcessGUID,SourceProcessGuid), TargetProcessGuid=iff(isnotempty(TargetProcessGUID),TargetProcessGUID,TargetProcessGuid)\r\n| project-away SourceProcessGUID, TargetProcessGUID \r\n// end fix\r\n| parse RuleName with * 'technique_id=' TechniqueId ',' * 'technique_name=' TechniqueName\r\n| parse Hashes with * 'SHA1=' SHA1 ',' * 'MD5=' MD5 ',' * 'SHA256=' SHA256 ',' * 'IMPHASH=' IMPHASH", 31 | "version": 1, 32 | "functionParameters": "starttime:datetime=datetime(null),endtime:datetime=datetime(null),eventtype_in:dynamic=dynamic([]),srcipaddr_has_any_prefix:dynamic=dynamic([]),actorusername_has_any:dynamic=dynamic([]),targetfilepath_has_any:dynamic=dynamic([]),srcfilepath_has_any:dynamic=dynamic([]),hashes_has_any:dynamic=dynamic([]),dvchostname_has_any:dynamic=dynamic([]),disabled:bool=False" 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /Deploy-Sentinel/resources/sentinelparser.kql: -------------------------------------------------------------------------------- 1 | let timeframe = "{time_range}"; 2 | let EventData = Event 3 | | where Source == "Microsoft-Windows-Sysmon" 4 | | extend RenderedDescription = tostring(split(RenderedDescription, ":")[0]) 5 | | project TimeGenerated, Source, EventID, Computer, UserName, EventData, RenderedDescription 6 | | extend EvData = parse_xml(EventData) 7 | | extend EventDetail = EvData.DataItem.EventData.Data 8 | | project-away EventData, EvData; 9 | let SysmonEvent1_ProcessCreate=() { 10 | let processEvents = EventData 11 | | where EventID == 1 12 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], 13 | file_version = EventDetail.[5].["#text"], file_description = EventDetail.[6].["#text"], file_product = EventDetail.[7].["#text"], file_company = EventDetail.[8].["#text"], file_name = EventDetail.[9].["#text"], 14 | process_command_line = EventDetail.[10].["#text"], file_directory = EventDetail.[11].["#text"], user_name = EventDetail.[12].["#text"], user_logon_guid = EventDetail.[13].["#text"], 15 | user_logon_id = EventDetail.[14].["#text"], user_session_id = EventDetail.[15].["#text"], process_integrity_level = EventDetail.[16].["#text"], Hashes = EventDetail.[17].["#text"], 16 | process_parent_guid = EventDetail.[18].["#text"], process_parent_id = EventDetail.[19].["#text"], process_parent_path = EventDetail.[20].["#text"], process_parent_command_line = EventDetail.[21].["#text"] 17 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 18 | | parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash 19 | | project-away EventDetail, rule_name, Hashes 20 | ; 21 | processEvents; 22 | }; 23 | let SysmonEvent2_FileCreateTime=() { 24 | let processEvents = EventData 25 | | where EventID == 2 26 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], 27 | file_path = EventDetail.[5].["#text"], file_creation_time = EventDetail.[6].["#text"], file_previous_creation_time = EventDetail.[7].["#text"] 28 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 29 | | parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash 30 | | project-away EventDetail, rule_name, Hashes 31 | ; 32 | processEvents; 33 | }; 34 | let SysmonEvent3_NetworkConnect=() { 35 | let processEvents = EventData 36 | | where EventID == 3 37 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], 38 | user_name = EventDetail.[5].["#text"], network_protocol = EventDetail.[6].["#text"], network_connection_initiated = EventDetail.[7].["#text"], src_is_ipv6 = EventDetail.[8].["#text"], src_ip = EventDetail.[9].["#text"], 39 | src_host_name = EventDetail.[10].["#text"], src_port = EventDetail.[11].["#text"], src_port_name = EventDetail.[12].["#text"], dst_is_ipv6 = EventDetail.[13].["#text"], 40 | dst_ip = EventDetail.[14].["#text"], dst_host_name = EventDetail.[15].["#text"], dst_port = EventDetail.[16].["#text"], dst_port_name = EventDetail.[17].["#text"] 41 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 42 | | project-away EventDetail, rule_name 43 | ; 44 | processEvents; 45 | }; 46 | let SysmonEvent4_ServiceStateChange=() { 47 | let processEvents = EventData 48 | | where EventID == 4 49 | | extend event_creation_time = EventDetail.[0].["#text"], service_state = EventDetail.[1].["#text"], sysmon_schema = EventDetail.[2].["#text"], sysmon_schema_version = EventDetail.[3].["#text"] 50 | | project-away EventDetail 51 | ; 52 | processEvents; 53 | }; 54 | let SysmonEvent5_ProcessTerminate=() { 55 | let processEvents = EventData 56 | | where EventID == 5 57 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"] 58 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 59 | | project-away EventDetail, rule_name 60 | ; 61 | processEvents; 62 | }; 63 | let SysmonEvent6_DriverLoad=() { 64 | let processEvents = EventData 65 | | where EventID == 6 66 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_pathLoaded = EventDetail.[2].["#text"], Hashes = EventDetail.[3].["#text"], 67 | driver_is_signed = EventDetail.[4].["#text"], driver_signature = EventDetail.[5].["#text"], driver_signature_status = EventDetail.[6].["#text"] 68 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 69 | | parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash 70 | | project-away EventDetail, rule_name 71 | ; 72 | processEvents; 73 | }; 74 | let SysmonEvent7_ImageLoad=() { 75 | let processEvents = EventData 76 | | where EventID == 7 77 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], 78 | module_loaded = EventDetail.[5].["#text"], file_version = EventDetail.[6].["#text"],file_description = EventDetail.[7].["#text"], file_product = EventDetail.[8].["#text"], file_company = EventDetail.[9].["#text"], 79 | Hashes = EventDetail.[11].["#text"], module_is_signed = EventDetail.[12].["#text"], module_signature = EventDetail.[13].["#text"], module_signature_status = EventDetail.[14].["#text"] 80 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 81 | | parse Hashes with * 'SHA1=' hash_sha1 ',' * 'MD5=' hash_md5 ',' * 'SHA256=' hash_sha256 ',' * 'IMPHASH=' hash_imphash 82 | | project-away EventDetail, rule_name 83 | ; 84 | processEvents; 85 | }; 86 | let SysmonEvent8_CreateRemoteThread=() { 87 | let processEvents = EventData 88 | | where EventID == 8 89 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], 90 | process_path = EventDetail.[4].["#text"], target_process_guid = EventDetail.[5].["#text"], target_process_id = EventDetail.[6].["#text"], target_process_path = EventDetail.[7].["#text"], 91 | thread_new_id = EventDetail.[8].["#text"], thread_start_address = EventDetail.[9].["#text"], thread_start_module = EventDetail.[10].["#text"], thread_start_function = EventDetail.[11].["#text"] 92 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 93 | | project-away EventDetail, rule_name 94 | ; 95 | processEvents; 96 | }; 97 | let SysmonEvent9_RawAccessRead=() { 98 | let processEvents = EventData 99 | | where EventID == 9 100 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], target_device = EventDetail.[5].["#text"] 101 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 102 | | project-away EventDetail, rule_name 103 | ; 104 | processEvents; 105 | }; 106 | let SysmonEvent10_ProcessAccess=() { 107 | let processEvents = EventData 108 | | where EventID == 10 109 | | extend rule_name = EventDetail.[0].["#text"],UtcTime = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], 110 | thread_id = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"], target_process_guid = EventDetail.[6].["#text"], target_process_id = EventDetail.[7].["#text"], 111 | target_process_path = EventDetail.[8].["#text"],process_granted_access = EventDetail.[9].["#text"], process_call_trace = EventDetail.[10].["#text"] 112 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 113 | | project-away EventDetail, rule_name 114 | ; 115 | processEvents; 116 | }; 117 | let SysmonEvent11_FileCreate=() { 118 | let processEvents = EventData 119 | | where EventID == 11 120 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], 121 | process_path = EventDetail.[4].["#text"], file_name = EventDetail.[5].["#text"], file_creation_time = EventDetail.[6].["#text"] 122 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 123 | | project-away EventDetail, rule_name 124 | ; 125 | processEvents; 126 | }; 127 | let SysmonEvent12_RegistryObjectAddDel=() { 128 | let processEvents = EventData 129 | | where EventID == 12 130 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], process_guid = EventDetail.[3].["#text"], 131 | process_id = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],registry_key_path = EventDetail.[6].["#text"] 132 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 133 | | project-away EventDetail, rule_name 134 | ; 135 | processEvents; 136 | }; 137 | let SysmonEvent13_RegistrySetValue=() { 138 | let processEvents = EventData 139 | | where EventID == 13 140 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], process_guid = EventDetail.[3].["#text"], 141 | process_id = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],registry_key_path = EventDetail.[6].["#text"],registry_key_details = EventDetail.[7].["#text"] 142 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 143 | | project-away EventDetail, rule_name 144 | ; 145 | processEvents; 146 | }; 147 | let SysmonEvent14_RegistryObjectRename=() { 148 | let processEvents = EventData 149 | | where EventID == 14 150 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], process_guid = EventDetail.[3].["#text"], 151 | process_id = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],registry_key_path = EventDetail.[6].["#text"],registry_key_new_name = EventDetail.[7].["#text"] 152 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 153 | | project-away EventDetail, rule_name 154 | ; 155 | processEvents; 156 | }; 157 | let SysmonEvent15_FileCreateStreamHash=() { 158 | let processEvents = EventData 159 | | where EventID == 15 160 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], 161 | process_path = EventDetail.[4].["#text"],file_name = EventDetail.[5].["#text"],file_creation_time = EventDetail.[6].["#text"],hash = EventDetail.[7].["#text"] 162 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 163 | | project-away EventDetail, rule_name 164 | ; 165 | processEvents; 166 | }; 167 | let SysmonEvent16_ConfigChange=() { 168 | let processEvents = EventData 169 | | where EventID == 16 170 | | extend event_creation_time = EventDetail.[0].["#text"], sysmon_configuration = EventDetail.[1].["#text"], sysmon_configuration_hash = EventDetail.[2].["#text"] 171 | | project-away EventDetail 172 | ; 173 | processEvents; 174 | }; 175 | let SysmonEvent17_CreateNamedPipe=() { 176 | let processEvents = EventData 177 | | where EventID == 17 178 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[2].["#text"], process_guid = EventDetail.[3].["#text"], process_id = EventDetail.[4].["#text"], pipe_name = EventDetail.[5].["#text"], 179 | process_path = EventDetail.[6].["#text"] 180 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 181 | | project-away EventDetail, rule_name 182 | ; 183 | processEvents; 184 | }; 185 | let SysmonEvent18_ConnectNamedPipe=() { 186 | let processEvents = EventData 187 | | where EventID == 18 188 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[2].["#text"], process_guid = EventDetail.[3].["#text"], process_id = EventDetail.[4].["#text"], pipe_name = EventDetail.[5].["#text"], 189 | process_path = EventDetail.[6].["#text"] 190 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 191 | | project-away EventDetail, rule_name 192 | ; 193 | processEvents; 194 | }; 195 | let SysmonEvent19_WMIEventFilter=() { 196 | let processEvents = EventData 197 | | where EventID == 19 198 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], wmi_operation = EventDetail.[3].["#text"], 199 | user_name = EventDetail.[4].["#text"],wmi_namespace = EventDetail.[5].["#text"],wmi_filter_name = EventDetail.[6].["#text"],wmi_query = EventDetail.[7].["#text"] 200 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 201 | | project-away EventDetail, rule_name 202 | ; 203 | processEvents; 204 | }; 205 | let SysmonEvent20_WMIEventConsumer=() { 206 | let processEvents = EventData 207 | | where EventID == 20 208 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], wmi_operation = EventDetail.[3].["#text"], 209 | user_name = EventDetail.[4].["#text"],wmi_consumer_name = EventDetail.[5].["#text"],wmi_consumer_type = EventDetail.[6].["#text"],wmi_consumer_destination = EventDetail.[7].["#text"] 210 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 211 | | project-away EventDetail, rule_name 212 | ; 213 | processEvents; 214 | }; 215 | let SysmonEvent21_WMIEventConsumerToFilter=() { 216 | let processEvents = EventData 217 | | where EventID == 21 218 | | extend rule_name = EventDetail.[0].["#text"], EventType = EventDetail.[1].["#text"], event_creation_time = EventDetail.[2].["#text"], wmi_operation = EventDetail.[3].["#text"], 219 | user_name = EventDetail.[4].["#text"],wmi_consumer_path = EventDetail.[5].["#text"],Type = EventDetail.[6].["#text"],wmi_filter_path = EventDetail.[7].["#text"] 220 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 221 | | project-away EventDetail, rule_name 222 | ; 223 | processEvents; 224 | }; 225 | let SysmonEvent22_DNSEvents=() { 226 | let processEvents = EventData 227 | | where EventID == 22 228 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], dns_query_name = EventDetail.[4].["#text"],dns_query_status = EventDetail.[5].["#text"],dns_query_results = EventDetail.[6].["#text"],process_path = EventDetail.[7].["#text"] 229 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 230 | | project-away EventDetail, rule_name 231 | ; 232 | processEvents; 233 | }; 234 | let SysmonEvent23_FileDeleteArchived=() { 235 | let processEvents = EventData 236 | | where EventID == 23 237 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], user_name = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],target_filename = EventDetail.[6].["#text"],file_hashes = EventDetail.[7].["#text"],is_executable = EventDetail.[8].["#text"],is_archived = EventDetail.[9].["#text"] 238 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 239 | | project-away EventDetail, rule_name 240 | ; 241 | processEvents; 242 | }; 243 | let SysmonEvent24_ClipboardChange=() { 244 | let processEvents = EventData 245 | | where EventID == 24 246 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], session = EventDetail.[5].["#text"], client_info = EventDetail.[6].["#text"], hashes = EventDetail.[7].["#text"], is_archived = EventDetail.[8].["#text"] 247 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 248 | | project-away EventDetail, rule_name 249 | ; 250 | processEvents; 251 | }; 252 | let SysmonEvent25_ProcessTampering=() { 253 | let processEvents = EventData 254 | | where EventID == 25 255 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], process_path = EventDetail.[4].["#text"], type = EventDetail.[5].["#text"] 256 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 257 | | project-away EventDetail, rule_name 258 | ; 259 | processEvents; 260 | }; 261 | let SysmonEvent26_FileDeleteLogged=() { 262 | let processEvents = EventData 263 | | where EventID == 26 264 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], user_name = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],target_filename = EventDetail.[6].["#text"],file_hashes = EventDetail.[7].["#text"], is_executable = EventDetail.[8].["#text"] 265 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 266 | | project-away EventDetail, rule_name 267 | ; 268 | processEvents; 269 | }; 270 | let SysmonEvent27_FileBlockExecutable=() { 271 | let processEvents = EventData 272 | | where EventID == 27 273 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], user_name = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],target_filename = EventDetail.[6].["#text"],file_hashes = EventDetail.[7].["#text"] 274 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 275 | | project-away EventDetail, rule_name 276 | ; 277 | processEvents; 278 | }; 279 | let SysmonEvent28_FileBlockShredding=() { 280 | let processEvents = EventData 281 | | where EventID == 28 282 | | extend rule_name = EventDetail.[0].["#text"], event_creation_time = EventDetail.[1].["#text"], process_guid = EventDetail.[2].["#text"], process_id = EventDetail.[3].["#text"], user_name = EventDetail.[4].["#text"],process_path = EventDetail.[5].["#text"],target_filename = EventDetail.[6].["#text"],file_hashes = EventDetail.[7].["#text"], is_executable = EventDetail.[8].["#text"] 283 | | parse rule_name with * 'technique_id=' technique_id ',' * 'technique_name=' technique_name ',' * 'phase_name=' phase_name 284 | | project-away EventDetail, rule_name 285 | ; 286 | processEvents; 287 | }; 288 | (union isfuzzy=true 289 | SysmonEvent1_ProcessCreate,SysmonEvent2_FileCreateTime,SysmonEvent3_NetworkConnect,SysmonEvent4_ServiceStateChange,SysmonEvent5_ProcessTerminate, 290 | SysmonEvent6_DriverLoad,SysmonEvent7_ImageLoad,SysmonEvent8_CreateRemoteThread,SysmonEvent9_RawAccessRead,SysmonEvent10_ProcessAccess, 291 | SysmonEvent11_FileCreate,SysmonEvent12_RegistryObjectAddDel,SysmonEvent13_RegistrySetValue,SysmonEvent14_RegistryObjectRename, 292 | SysmonEvent15_FileCreateStreamHash,SysmonEvent16_ConfigChange,SysmonEvent17_CreateNamedPipe,SysmonEvent18_ConnectNamedPipe, 293 | SysmonEvent19_WMIEventFilter,SysmonEvent20_WMIEventConsumer,SysmonEvent21_WMIEventConsumerToFilter,SysmonEvent22_DNSEvents,SysmonEvent23_FileDeleteArchived,SysmonEvent24_ClipboardChange,SysmonEvent25_ProcessTampering,SysmonEvent26_FileDeleteLogged,SysmonEvent27_FileBlockExecutable,SysmonEvent28_FileBlockShredding) -------------------------------------------------------------------------------- /README.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Defensive Origins Lab Environment 5 | 6 | 7 | 8 |

9 |

Defensive Origins Lab Environment

10 |

The Defensive Origins Lab (DO-LAB) Environment is used during the Defensive Origins training classes by Defensive Origins, AntiSyphon Training, and Black Hills Information Security.

11 | 12 | 24 | 25 |

Deploy Lab Environment

26 |

Click the button below to start the deployment of the Defensive Origins Lab Environment within your Azure account.

27 |

Deploy DO-LAB Azure

28 |

Azure Cloud Locations/Regions

29 |

While the deployment within Azure should be region agnostic, some deployed resources may not be available in all regions. 30 | The following locations have specifically been tested:

31 | 36 |

Training Course Pre-Requisites

37 |

Are you attending a Defensive Origins training course that utilizes the Defensive Origins Azure Lab Environment? See the below links for additional information on the DOAZLab Pre-Requisites for Defensive Origins training courses.

38 |

Assumed Compromise - Methodology With Detections and Microsoft Sentinel

39 | 42 |

Attack Detect Defend:

43 | 46 |

Applied Purple Teaming:

47 | 50 |

Lab Environment

51 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Labenv
69 |

Acknowledgments

70 | 77 |

License

78 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](images/APT1.jpg) 2 | 3 | # Defensive Origins Lab Environment 4 | The Defensive Origins Lab (DO-LAB) Environment is used during the Defensive Origins training classes by Defensive Origins, AntiSyphon Training, and Black Hills Information Security. 5 | 6 | 7 | * [Deploy Lab Environment](#deploy-lab-environment) 8 | * [Azure Cloud Locations/Regions](#azure-cloud-locationsregions) 9 | * [Training Course Pre-Requisites](#training-course-pre-requisites) 10 | * [Lab Environment](#lab-environment) 11 | * [Upcoming Classes](#upcoming-classes) 12 | * [Acknowledgments](#acknowledgments) 13 | * [License](#license) 14 | 15 | 16 | 17 | 18 | 19 | # Deploy Lab Environment 20 | 21 | Click the button below to start the deployment of the Defensive Origins Lab Environment within your Azure account. 22 | 23 | [![Deploy DO-LAB Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/%68%74%74%70%73%3A%2F%2F%72%61%77%2E%67%69%74%68%75%62%75%73%65%72%63%6F%6E%74%65%6E%74%2E%63%6F%6D%2F%44%65%66%65%6E%73%69%76%65%4F%72%69%67%69%6E%73%2F%44%4F%2D%4C%41%42%2F%6D%61%69%6E%2F%44%65%70%6C%6F%79%2D%4C%41%42%2F%61%7A%75%72%65%2D%64%65%70%6C%6F%79%2E%6A%73%6F%6E/createUIDefinitionUri/%68%74%74%70%73%3A%2F%2F%72%61%77%2E%67%69%74%68%75%62%75%73%65%72%63%6F%6E%74%65%6E%74%2E%63%6F%6D%2F%44%65%66%65%6E%73%69%76%65%4F%72%69%67%69%6E%73%2F%44%4F%2D%4C%41%42%2F%6D%61%69%6E%2F%44%65%70%6C%6F%79%2D%4C%41%42%2F%75%69%64%65%66%69%6E%69%74%69%6F%6E%2E%6A%73%6F%6E) 24 | 25 | ## Azure Cloud Locations/Regions 26 | While the deployment within Azure should be region agnostic, some deployed resources may not be available in all regions. 27 | The following locations have specifically been tested: 28 | * US East (any) 29 | * US West (any) 30 | * US Central (any) 31 | 32 | ## Training Course Pre-Requisites 33 | Are you attending a Defensive Origins training course that utilizes the Defensive Origins Azure Lab Environment? See the below links for additional information on the DOAZLab Pre-Requisites for Defensive Origins training courses. 34 | 35 | Assumed Compromise - Methodology With Detections and Microsoft Sentinel 36 | * https://github.com/DefensiveOrigins/AC-PreReqs 37 | 38 | Attack Detect Defend: 39 | * https://github.com/DefensiveOrigins/ADD-PreReqs 40 | 41 | Applied Purple Teaming: 42 | * https://github.com/DefensiveOrigins/APT-PreReqs 43 | 44 | ## Lab Environment 45 | * Windows Server 2022 /w Active Directory. 46 | * Domain: doazlab.com 47 | * Windows Workstation 48 | * Ubuntu 22.04LTS 49 | * Sysmon Installation on Server and Workstation 50 | * Microsoft Sentinel & Log Analytics 51 | 52 | | ![Labenv](images/labenv.png) | 53 | |----------------------------------------------------------| 54 | 55 | 56 | # Acknowledgments 57 | * Open Threat Research Forge: https://github.com/DefensiveOrigins/DO-LAB 58 | * Microsoft Sentinel2Go: https://github.com/OTRF/Microsoft-Sentinel2Go 59 | * OTRF Blacksmith Components: https://github.com/OTRF/Blacksmith 60 | * Roberto Rodriguez (@Cyb3rWard0g) 61 | * Sysmon Modular: https://github.com/olafhartong/sysmon-modular/wiki 62 | 63 | # License 64 | * GPLv3 65 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /images/APT1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/images/APT1.jpg -------------------------------------------------------------------------------- /images/labenv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DefensiveOrigins/DO-LAB/fbdf8b517755c9773a2f86c02748dd4c88e3f800/images/labenv.png --------------------------------------------------------------------------------