diff --git a/powershell/public/cisa/exchange/ConvertFrom-MailAuthenticationRecordDmarc.ps1 b/powershell/public/cisa/exchange/ConvertFrom-MailAuthenticationRecordDmarc.ps1 index a5cf2bf2..f8b45fee 100644 --- a/powershell/public/cisa/exchange/ConvertFrom-MailAuthenticationRecordDmarc.ps1 +++ b/powershell/public/cisa/exchange/ConvertFrom-MailAuthenticationRecordDmarc.ps1 @@ -115,7 +115,6 @@ function ConvertFrom-MailAuthenticationRecordDmarc { $this.valid = $init if (-not $init) { $this.warnings += "v/p: Record version (v) and policy (p) configuration is not proper" - exit } $this.version = $Matches["v"] $this.policy = $Matches["p"] @@ -217,8 +216,9 @@ function ConvertFrom-MailAuthenticationRecordDmarc { } process { - $dmarcPrefix = "_dmarc." - $matchRecord = "^v\s*=\s*(?'v'DMARC1)\s*;\s*p\s*=\s*(?'p'none|quarantine|reject)(?:$|\s*;\s*)" + $dmarcPrefix = "_dmarc." + $matchRecord = "^v\s*=\s*(?'v'DMARC1)\s*;\s*p\s*=\s*(?'p'none|quarantine|reject)(?:$|\s*;\s*)" + $regexOptions = [Text.RegularExpressions.RegexOptions]'IgnoreCase,Multiline' $dmarcSplat = @{ Name = "$dmarcPrefix$DomainName" @@ -232,7 +232,7 @@ function ConvertFrom-MailAuthenticationRecordDmarc { if ( $isWindows -or $PSVersionTable.PSEdition -eq "Desktop") { $dmarcRecord = [DMARCRecord]::new((Resolve-DnsName @dmarcSplat | ` Where-Object { $_.Type -eq "TXT" } | ` - Where-Object { $_.Strings -match $matchRecord }).Strings) + Where-Object { [regex]::Match($_.Strings,$matchRecord,$regexOptions) }).Strings) } else { $cmdletCheck = Get-Command "Resolve-Dns" -ErrorAction SilentlyContinue if ($cmdletCheck) { @@ -244,7 +244,7 @@ function ConvertFrom-MailAuthenticationRecordDmarc { } $record = ((Resolve-Dns @dmarcSplatAlt).Answers | ` Where-Object { $_.RecordType -eq "TXT" } | ` - Where-Object { $_.Text -imatch $matchRecord }).Text + Where-Object { [regex]::Match($_.Text,$matchRecord,$regexOptions) }).Text if ($record) { $dmarcRecord = [DMARCRecord]::new($record) } else { diff --git a/powershell/public/cisa/exchange/Test-MtCisaDmarcAggregateCisa.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDmarcAggregateCisa.ps1 index 839a0e91..535e901b 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDmarcAggregateCisa.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDmarcAggregateCisa.ps1 @@ -23,7 +23,10 @@ function Test-MtCisaDmarcAggregateCisa { [OutputType([bool])] param( # Check all domains, not only .gov domains. - [switch]$Force + [switch]$Force, + + # Check 2nd Level Domains Explicitly per CISA + [switch]$Strict ) if(!(Test-MtConnection ExchangeOnline)){ @@ -87,8 +90,14 @@ function Test-MtCisaDmarcAggregateCisa { $dmarcRecords += $dmarcRecord } - if("Failed" -in $dmarcRecords.pass){ + if("Failed" -in $dmarcRecords.pass -and $Strict){ $testResult = $false + }elseif("Failed" -in $dmarcRecords.pass -and -not $Strict){ + if("Failed" -in ($dmarcRecords|Where-Object{$_.domain -in $acceptedDomains.DomainName}).pass){ + $testResult = $false + }else{ + $testResult = $true + } }elseif("Failed" -notin $dmarcRecords.pass -and "Passed" -notin $dmarcRecords.pass){ Add-MtTestResultDetail -SkippedBecause NotSupported return $null diff --git a/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordExist.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordExist.ps1 index 757eeb03..764cd1d2 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordExist.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordExist.ps1 @@ -16,7 +16,10 @@ function Test-MtCisaDmarcRecordExist { [CmdletBinding()] [OutputType([bool])] - param() + param( + # Check 2nd Level Domains Explicitly per CISA + [switch]$Strict + ) if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange @@ -58,8 +61,14 @@ function Test-MtCisaDmarcRecordExist { $dmarcRecords += $dmarcRecord } - if("Failed" -in $dmarcRecords.pass){ + if("Failed" -in $dmarcRecords.pass -and $Strict){ $testResult = $false + }elseif("Failed" -in $dmarcRecords.pass -and -not $Strict){ + if("Failed" -in ($dmarcRecords|Where-Object{$_.domain -in $acceptedDomains.DomainName}).pass){ + $testResult = $false + }else{ + $testResult = $true + } }elseif("Failed" -notin $dmarcRecords.pass -and "Passed" -notin $dmarcRecords.pass){ Add-MtTestResultDetail -SkippedBecause NotSupported return $null diff --git a/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordReject.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordReject.ps1 index ff28ffa0..fb08bb40 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordReject.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDmarcRecordReject.ps1 @@ -16,7 +16,10 @@ function Test-MtCisaDmarcRecordReject { [CmdletBinding()] [OutputType([bool])] - param() + param( + # Check 2nd Level Domains Explicitly per CISA + [switch]$Strict + ) if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange @@ -69,8 +72,14 @@ function Test-MtCisaDmarcRecordReject { $dmarcRecords += $dmarcRecord } - if("Failed" -in $dmarcRecords.pass){ + if("Failed" -in $dmarcRecords.pass -and $Strict){ $testResult = $false + }elseif("Failed" -in $dmarcRecords.pass -and -not $Strict){ + if("Failed" -in ($dmarcRecords|Where-Object{$_.domain -in $acceptedDomains.DomainName}).pass){ + $testResult = $false + }else{ + $testResult = $true + } }elseif("Failed" -notin $dmarcRecords.pass -and "Passed" -notin $dmarcRecords.pass){ Add-MtTestResultDetail -SkippedBecause NotSupported return $null diff --git a/powershell/public/cisa/exchange/Test-MtCisaDmarcReport.ps1 b/powershell/public/cisa/exchange/Test-MtCisaDmarcReport.ps1 index 57128aa2..6211de6f 100644 --- a/powershell/public/cisa/exchange/Test-MtCisaDmarcReport.ps1 +++ b/powershell/public/cisa/exchange/Test-MtCisaDmarcReport.ps1 @@ -10,13 +10,19 @@ Returns true if DMARC record inlcudes report targets within same domain +.PARAMETER Strict + Require the CISA explicit 2nd level validation + .LINK https://maester.dev/docs/commands/Test-MtCisaDmarcReport #> function Test-MtCisaDmarcReport { [CmdletBinding()] [OutputType([bool])] - param() + param( + # Check 2nd Level Domains Explicitly per CISA + [switch]$Strict + ) if(!(Test-MtConnection ExchangeOnline)){ Add-MtTestResultDetail -SkippedBecause NotConnectedExchange @@ -46,8 +52,8 @@ function Test-MtCisaDmarcReport { } $dmarcRecords = @() - foreach($domain in $expandedDomains){ - $dmarcRecord = Get-MailAuthenticationRecord -DomainName $domainName -Records DMARC + foreach($expandedDomain in $expandedDomains){ + $dmarcRecord = Get-MailAuthenticationRecord -DomainName $expandedDomain -Records DMARC $dmarcRecord | Add-Member -MemberType NoteProperty -Name "pass" -Value "Failed" $dmarcRecord | Add-Member -MemberType NoteProperty -Name "reason" -Value "" @@ -55,7 +61,7 @@ function Test-MtCisaDmarcReport { $hostsAggregate = $dmarcRecord.dmarcRecord.reportAggregate.mailAddress.Host $hostsForensic = $dmarcRecord.dmarcRecord.reportForensic.mailAddress.Host - if($checkType -and $domain -in $hostsAggregate -and $domain -in $hostsForensic){ + if($checkType -and $expandedDomain -in $hostsAggregate -and $expandedDomain -in $hostsForensic){ $dmarcRecord.pass = "Passed" }elseif($checkType){ $dmarcRecord.reason = "No target in domain" @@ -69,8 +75,14 @@ function Test-MtCisaDmarcReport { $dmarcRecords += $dmarcRecord } - if("Failed" -in $dmarcRecords.pass){ + if("Failed" -in $dmarcRecords.pass -and $Strict){ $testResult = $false + }elseif("Failed" -in $dmarcRecords.pass -and -not $Strict){ + if("Failed" -in ($dmarcRecords|Where-Object{$_.domain -in $acceptedDomains.DomainName}).pass){ + $testResult = $false + }else{ + $testResult = $true + } }elseif("Failed" -notin $dmarcRecords.pass -and "Passed" -notin $dmarcRecords.pass){ Add-MtTestResultDetail -SkippedBecause NotSupported return $null @@ -98,7 +110,7 @@ function Test-MtCisaDmarcReport { if($aggregatesCount -ge 3){ $aggregates = "$($aggregates[0]), $($aggregates[1]), " $aggregates += "& ...$aggregatesCount targets" - }elseif(aggregatesCount -gt 1){ + }elseif($aggregatesCount -gt 1){ $aggregates = $aggregates -join "
" } $forensics = $item.dmarcRecord.reportForensic.mailAddress @@ -106,7 +118,7 @@ function Test-MtCisaDmarcReport { if($forensicsCount -ge 3){ $forensics = "$($forensics[0]), $($forensics[1]), " $forensics += "& ...$forensicsCount targets" - }elseif(aggregatesCount -gt 1){ + }elseif($aggregatesCount -gt 1){ $forensics = $forensics -join ", " }