Monitoring with PowerShell: Typosquat domain checking

One of my team members was following Blackhat today and showed me a pretty cool tool they demonstrated during the conference. The presenters showed a method of checking if your O365 domain was being Typosquated. The tool can be found here. The presenters made a Python tool, and I figured to create an alternative in PowerShell.

I’ve checked their method and found they use two different typosquating detection techniques; they’ve applied homoglyphs and BitSquating. These two techniques are most common in Typosquats, its either replacing characters with similar looking ones, or minor typos in the URL.

In my version, I’ve also introduced pluralization and omission, just to get a bit more domain names, I’m not saying this is a 100% extensive list. If you have any suggested changes feel free to make a GitHub PR here.

The script

To run the script, simply change the domain name at the end of the script and execute it. The script contains two functions; New-TypoSquatDomain which generate a list of typosquated domains and Get-O365TypoSquats which checks if the .onmicrosoft.com, .sharepoint.com and the domain itself are available.

So what can you do with this information? if the .onmicrosoft.com version exists, you can add this to your spamfilter to prevent spam, If the .sharepoint.com version exist people might be phishing you using SharePoint online URLS, and if the domain exists you could add it to the spamfilter or check what’s running there and notify your users.

function New-TypoSquatDomain {
    param (
        $DomainName
    )
    $ReplacementGylph = [pscustomobject]@{
        0  = 'b', 'd' 
        1  = 'b', 'lb' 
        2  = 'c', 'e'
        3  = 'd', 'b'
        4  = 'd', 'cl'
        5  = 'd', 'dl' 
        6  = 'e', 'c' 
        7  = 'g', 'q' 
        8  = 'h', 'lh' 
        9  = 'i', '1'
        10 = 'i', 'l' 
        11 = 'k', 'lk'
        12 = 'k', 'ik'
        13 = 'k', 'lc' 
        14 = 'l', '1'
        15 = 'l', 'i' 
        16 = 'm', 'n'
        17 = 'm', 'nn'
        18 = 'm', 'rn'
        19 = 'm', 'rr' 
        20 = 'n', 'r'
        21 = 'n', 'm'
        22 = 'o', '0'
        23 = 'o', 'q'
        24 = 'q', 'g' 
        25 = 'u', 'v' 
        26 = 'v', 'u'
        27 = 'w', 'vv'
        28 = 'w', 'uu' 
        29 = 'z', 's' 
        30 = 'n', 'r' 
        31 = 'r', 'n'
    }
    $i = 0

    $TLD = $DomainName -split '\.' | Select-Object -last 1
    $DomainName = $DomainName -split '\.' | Select-Object -First 1
    $HomoGlyph = do {
        $NewDomain = $DomainName -replace $ReplacementGylph.$i
        $NewDomain
        $NewDomain + 's'
        $NewDomain + 'a'
        $NewDomain + 't'
        $NewDomain + 'en'
        $i++
    } while ($i -lt 29)

    $i = 0
    $BitSquatAndOmission = do {
        $($DomainName[0..($i)] -join '') + $($DomainName[($i + 2)..$DomainName.Length] -join '')
        $($DomainName[0..$i] -join '') + $DomainName[$i + 2] + $DomainName[$i + 1] + $($DomainName[($i + 3)..$DomainName.Length] -join '')
        $i++
    } while ($i -lt $DomainName.Length)
    $Plurals = $DomainName + 's'; $DomainName + 'a'; $domainname + 'en' ;  ; $DomainName + 't'

    $CombinedDomains = $HomoGlyph + $BitSquatAndOmission + $Plurals | ForEach-Object { "$($_).$($TLD)" }
    return ( $CombinedDomains | Sort-Object -Unique | Where-Object { $_ -ne $DomainName })
}

function Get-O365TypoSquats {
    param (
        $TypoSquatedDomain
    )
    $DomainWithoutTLD = $TypoSquatedDomain -split '.' | Select-Object -First 1
    $DomainTest = Resolve-DnsName -Type A "$($TypoSquatedDomain)" -ErrorAction SilentlyContinue
    $Onmicrosoft = Resolve-DnsName -Type A "$($DomainWithoutTLD).onmicrosoft.com" -ErrorAction SilentlyContinue
    $Sharepoint = Resolve-DnsName -Type A "$($DomainWithoutTLD).sharepoint.com" -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        'Onmicrosoft test' = [boolean]$Onmicrosoft
        'Sharepoint test'  = [boolean]$Sharepoint
        'Domain test'      = [boolean]$DomainTest
        Domain             = $TypoSquatedDomain
    }
}

New-TypoSquatDomain -DomainName 'Google.com' | ForEach-Object { Get-O365TypoSquats -TypoSquatedDomain $_ }

You can load this script into your RMM system and alert whenever results are found.

And that’s it! as always, Happy PowerShelling!

3 thoughts on “Monitoring with PowerShell: Typosquat domain checking

  1. Steve

    This is a great script; thanks for building it. The only thing I could think to add is only outputting when any item is true.

    Reply
  2. Joe K

    Neat. The output column Domain is too short, it only shows a few letters, then… Is that by design? I’d like to see the domain on True for Domain test.

    Reply
  3. Andy

    @Joe – that was my first thought too.
    You can fix this by adding
    | ft -autosize
    to the end of the script, or load it into out-gridview for a quick way to filter out the yes/no’s.

    Fwiw I found that we have a domain that is effectively typosquatting ours. However the domain is onhold due to non payment (I guess) so it does not not show up as a squatted domain as no NS records exist for the domain. I put an issue on the original Github as a feature.

    Also this tool does not catch .org/.com squatters

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.