While building Erudite I had to write a report, in said report I discuss the dominance Microsoft and their services hold on the Education sector. As a vouch I wrote a script that did a best-guess on whether the university FOI email addresses were associated with Microsoft. The script is on GitHub, but it’s tiny, so I’ll save you the hassle :).
require 'resolv'
require 'json'
require 'timeout'
def safe_dns_lookup(seconds = 5)
Timeout.timeout(seconds) { yield }
rescue Timeout::Error
[]
end
def likely_using_m365?(domain)
# Check MX Records
mx_records = safe_dns_lookup { Resolv::DNS.open { |dns| dns.getresources(domain, Resolv::DNS::Resource::IN::MX) } }
mx_points_to_m365 = mx_records.any? { |mx| mx.exchange.to_s.include?('protection.outlook.com') }
# Check Autodiscover CNAME
autodiscover_record = safe_dns_lookup { Resolv::DNS.open { |dns| dns.getresources("autodiscover.#{domain}", Resolv::DNS::Resource::IN::CNAME) } }
autodiscover_points_to_m365 = autodiscover_record.any? { |cname| cname.name.to_s.include?('autodiscover.outlook.com') }
# Check TXT Records (SPF)
txt_records = safe_dns_lookup { Resolv::DNS.open { |dns| dns.getresources(domain, Resolv::DNS::Resource::IN::TXT) } }
spf_points_to_m365 = txt_records.any? { |txt| txt.strings.join.include?('spf.protection.outlook.com') }
# Determine if domain is likely using M365
mx_points_to_m365 || autodiscover_points_to_m365 || spf_points_to_m365
end
# Reduced for readability, but you get the idea
input = {
"emails" => [
"[email protected]",
]
}
results = {
"likely_using_m365" => [],
"not_using_m365" => []
}
input["emails"].each do |email|
if likely_using_m365?(domain)
results["likely_using_m365"] << email
else
results["not_using_m365"] << email
end
end
puts "Likely: #{results["likely_using_m365"].size} vs Unlikely: #{results["not_using_m365"].size}"