Skip to content

Instantly share code, notes, and snippets.

@altima
Created April 1, 2025 12:46
Show Gist options
  • Save altima/b53d2992db18f954af27d36a8d566eff to your computer and use it in GitHub Desktop.
Save altima/b53d2992db18f954af27d36a8d566eff to your computer and use it in GitHub Desktop.
Powershell Script for checking SPF
$domain = "example.com"
$ip2check = "127.0.0.1"
$Global:SPFLookups = 0
$Global:SenderIsAllowedviaSPF = ""
$Global:SenderIsAllowed = $false
if($ip2check -notmatch "((?:\d{1,3}\.){3}\d{1,3}|(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4})"){
$ip2check = (Resolve-DnsName $ip2check).IPAddress
}
Write-host ("Checking SPF on [{0}] for Sender [{1}]" -f $domain, $ip2check) -ForegroundColor Blue
function doSPFLookup($domain, $spfPattern = "v=spf1 (.*) [+\-~?]all"){
$Global:SPFLookups++
try{
return @(resolve-dnsname $domain -Type TXT -ErrorAction SilentlyContinue | Where Strings -Match $spfPattern)[0]
}
catch{
}
return $false
}
function Get-SubnetRange {
param (
[string]$Subnet = "192.168.1.0",
[int]$MaskLength = 24
)
$ipAddress = [System.Net.IPAddress]::Parse($Subnet)
$ipBytes = $ipAddress.GetAddressBytes()
[Array]::Reverse($ipBytes)
$ipNum = [BitConverter]::ToUInt32($ipBytes, 0)
$hostBits = 32 - $MaskLength
$numHosts = [math]::Pow(2, $hostBits) - 2 # Subtracting network & broadcast address
$startIP = $ipNum + 1
$endIP = $ipNum + $numHosts
for ($i = $startIP; $i -le $endIP; $i++) {
$ipBytes = [BitConverter]::GetBytes([uint32]$i)
[Array]::Reverse($ipBytes)
[System.Net.IPAddress]::new($ipBytes) | Select-Object -ExpandProperty IPAddressToString
}
}
function Test-IPInSubnet($ip, $subnet) {
$range = Get-SubnetRange $subnet.split("/")[0] $subnet.split("/")[1]
return ($range -contains $ip)
}
function Test-IPv6InSubnet($ip, $subnet) {
return $false
}
function doCheck($domain, $ip2check, $spfPattern = "v=spf1 (.*) [+\-~?]all"){
$allowedIPs = @()
$entry = doSPFLookup $domain
if(!$entry){
Write-host "No SPF Record found" -ForegroundColor Red
return $allowedIPs
}
Write-Host ("SPFRecord ""$domain"" --> ""{0}""" -f $entry.strings) -ForegroundColor Yellow
$entries = ($entry.strings | select-string -Pattern $spfPattern).Matches.Groups[1].value.split(" ")
foreach($entry in $entries){
if($entry -eq "MX"){
$mx = (Resolve-DnsName $domain -Type MX).NameExchange
$mxResolve = (Resolve-DnsName $mx)
if($mxResolve | Where Type -eq "A"){
$allowedIPs += ((Resolve-DnsName $mx) | Where Type -eq "A").ipAddress
}
if($mxResolve | Where Type -eq "AAAA"){
$allowedIPs += ((Resolve-DnsName $mx) | Where Type -eq "AAAA").ipAddress
}
}
if($entry -match "^ip4:"){
$allowedIPs += ($entry | Select-String -Pattern "^ip4:(.*)").Matches.Groups[1].value
}
if($entry -match "^ip6:(.*)"){
$allowedIPs += ($entry | Select-String -Pattern "^ip6:(.*)").Matches.Groups[1].value
}
if($entry -match "^include:"){
$include = ($entry | Select-String -Pattern "^include:(.*)").Matches.Groups[1].value
$allowedIPs += @(doCheck $include $ip2check)
}
if($entry -match "^exists:"){
$exists = ($entry | Select-String -Pattern "^exists:(.*)").Matches.Groups[1].value
$test = $exists.Replace("%{i}", "$ip2check")
Write-Host ("%{{i}} is a macro which checks the existance of DNS Records, like this [{0}]" -f $test) -ForegroundColor Blue
if(Resolve-DnsName $test -ErrorAction SilentlyContinue){
$allowedIPs += $ip2check
}
}
}
foreach($net in $allowedIPs){
if((Test-IPInSubnet $ip2check $net) -or (Test-IPv6InSubnet $ip2check $net)){
$Global:SenderIsAllowed = $true
$Global:SenderIsAllowedviaSPF = $domain
}
}
Write-Host ($allowedIPs -join "`r`n") -ForegroundColor Green
}
doCheck $domain $ip2check
Write-Host "---------------------------------------------------" -ForegroundColor Green
if($Global:SPFLookups -le 10){
Write-Host "Did "$Global:SPFLookups" SPF Lookups" -ForegroundColor Green
}else{
Write-Host "Did "$Global:SPFLookups" SPF Lookups. Only 10 allowed!" -ForegroundColor Red
}
Write-Host "---------------------------------------------------" -ForegroundColor Green
if($Global:SenderIsAllowed){
Write-Host ("Sender [{0}] is allowed with SPF [{1}]" -f $ip2check, $Global:SenderIsAllowedviaSPF) -ForegroundColor Green
}else{
Write-Host ("Sender [{0}] is not allowed" -f $ip2check) -ForegroundColor Red
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment