├── .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 | \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 |
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 |Click the button below to start the deployment of the Defensive Origins Lab Environment within your Azure account.
27 | 28 |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 |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 |![]() |
66 |
---|