Public/Security/Get-EmailSecurityRecords.ps1
function Get-EmailSecurityRecords { <# .DESCRIPTION All credit to: AUTHOR: Daniel Streefkerk WWW: https://daniel.streefkerkonline.com Twitter: @dstreefkerk This function that he put together is amazing!! Please check out his blog - also fantastic. I removed [ordered] type and used [pscustomobject] instead. I also added in kitterman spf validation and detail (if fails) Here is Daniel's description... A quick and dirty script to be used to automate the collection of publicly-available email-related records For example: MX, SPF, DMARC, MTA-STS records. It'll also try to make a determination about who's handling mail flow, and whether the domain is hosted on Exchange Online (sometimes ExOnline tenants pass their mail through filtering services like ProofPoint, Mimecast, etc) If the domain is hosted on Exchange Online, it'll also check whether DKIM is configured, and determine whether the domain is federated or not. .SYNOPSIS Perform email-based reconnaissance on a single domain, or a collection of domains .PARAMETER DomainName PrimarySmtpAddress Domain to check .EXAMPLE Get-EmailSecurityRecords -DomainName contoso.com .EXAMPLE (Import-Csv c:\scripts\domains.csv).DomainName | Get-EmailSecurityRecords #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string[]] $EmailDomain ) begin { } process { foreach ($domain in $EmailDomain) { Write-Verbose "Testing domain:`t$domain" # Attempt to find the SOA domain record, skip the domain if we can't locate one DNS try { $null = Resolve-DnsName -Name $domain -Type SOA -ErrorAction Stop Write-Verbose "Successfully located SOA record for $domain" } catch { Write-Verbose "Failed to locate SOA record for $domain" continue } # Collect data $ErrorActionPreference = 'SilentlyContinue' $dataCollection = [PSCustomObject]@{ DMARC = Resolve-DnsName -Name "_dmarc.$($domain)" -Type TXT -Server 8.8.8.8 MX = Resolve-DnsName -Name $domain -Type MX -Server 8.8.8.8 MTASTS = Get-MTASTSDetails -DomainName $domain MSOID = Resolve-DnsName "msoid.$($domain)" -Server 8.8.8.8 TXT = Resolve-DnsName $domain -Type TXT -Server 8.8.8.8 ENTERPRISEREGISTRATION = Resolve-DnsName -Name "enterpriseregistration.$domain" -Type CNAME -Server 8.8.8.8 AUTODISCOVER = Resolve-DnsName -Name "autodiscover.$domain" -Type CNAME -Server 8.8.8.8 SOA = Resolve-DnsName -Type SOA -Name $domain -Server 8.8.8.8 NS = Resolve-DnsName $domain -Type NS -Server 8.8.8.8 O365DKIM = [PSCustomObject]@{ SELECTOR1 = Resolve-DnsName "selector1._domainkey.$domain" -Type CNAME -Server 8.8.8.8 SELECTOR2 = Resolve-DnsName "selector2._domainkey.$domain" -Type CNAME -Server 8.8.8.8 } FEDERATION = Get-DomainFederationDataFromO365 -DomainName $domain DNSSEC = Get-DNSSECDetails -DomainName $domain } $ErrorActionPreference = 'Continue' # Finish collecting data # Analyse the collected data $SPFResult = Test-SPFRecord $domain [PSCustomObject]@{ 'Domain' = $domain 'MX Records Exist' = $dataCollection.mx.NameExchange.Count -gt 0 'MX Provider' = Test-MXHandler $dataCollection 'MX Lowest Preference' = Get-LowestPreferenceMX $dataCollection 'SPF Record Exists' = Test-SpfRecordExists $dataCollection 'SPF Record' = Get-SpfRecordText $dataCollection 'SPF Mechanism Mode' = Get-SpfRecordMode $dataCollection 'SPF Validity' = $SPFResult.Result 'SPF Result' = $SPFResult.Detail 'DMARC Record Exists' = Test-DmarcRecordExists $dataCollection 'DMARC Record' = Get-DmarcRecordText $dataCollection 'DMARC Domain Policy Mode' = Get-DmarcPolicy $dataCollection 'DMARC Subdomain Policy Mode' = Get-DmarcSubdomainPolicy $dataCollection 'O365 Exchange Online' = Test-ExchangeOnlineDomain $dataCollection 'O365 Tenant Name' = Test-O365DomainTenantName $dataCollection 'O365 DKIM Enabled' = Test-O365Dkim $dataCollection 'O365 Federated' = Test-O365IsFederated $dataCollection 'O365 Federation Provider' = Test-O365FederationProvider $dataCollection 'O365 Federation Hostname' = Get-O365FederationHostname $dataCollection 'O365 Federation Brand Name' = $dataCollection.FEDERATION.FederationBrandName 'O365/AzureAD Directory ID' = Test-O365DirectoryID $domain 'O365/AzureAD is Unmanaged' = Test-AADIsUnmanaged $dataCollection 'MTA-STS Record Exists' = $dataCollection.MTASTS.DNSRecord -ne $null 'MTA-STS Policy Mode' = $dataCollection.MTASTS.Mode 'MTA-STS Allowed MX Hosts' = $dataCollection.MTASTS.AllowedMX 'DNS Registrar' = Test-DnsNameAdministrator $dataCollection 'DNS Host' = Test-DnsHostingProvider $dataCollection 'DNSSEC DNSKEY Record Exists' = $dataCollection.DNSSEC.DNSKeyExists #'ADFS Host' = (Test-AdfsFederationMetadataUrl $domain) } } } end { } } |