Skip to content

Commit

Permalink
Merge pull request #599 from soulemike/fix549
Browse files Browse the repository at this point in the history
Fix a couple bugs in record lookups and allowed for a CISA Strict par…
  • Loading branch information
merill authored Jan 7, 2025
2 parents 3342af0 + 2b1cf6f commit 3b6ab18
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down Expand Up @@ -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"
Expand All @@ -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) {
Expand All @@ -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 {
Expand Down
13 changes: 11 additions & 2 deletions powershell/public/cisa/exchange/Test-MtCisaDmarcAggregateCisa.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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)){
Expand Down Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions powershell/public/cisa/exchange/Test-MtCisaDmarcRecordExist.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions powershell/public/cisa/exchange/Test-MtCisaDmarcRecordReject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
26 changes: 19 additions & 7 deletions powershell/public/cisa/exchange/Test-MtCisaDmarcReport.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -46,16 +52,16 @@ 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 ""

$checkType = $dmarcRecord.dmarcRecord.GetType().Name -eq "DMARCRecord"
$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"
Expand All @@ -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
Expand Down Expand Up @@ -98,15 +110,15 @@ 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 "<br />"
}
$forensics = $item.dmarcRecord.reportForensic.mailAddress
$forensicsCount = ($forensics|Measure-Object).Count
if($forensicsCount -ge 3){
$forensics = "$($forensics[0]), $($forensics[1]), "
$forensics += "& ...$forensicsCount targets"
}elseif(aggregatesCount -gt 1){
}elseif($aggregatesCount -gt 1){
$forensics = $forensics -join ", "
}

Expand Down

0 comments on commit 3b6ab18

Please sign in to comment.