(Ok, maybe not ponies.)
I’ve stolen and edited a fantastic telnet powershell function from here and am using it to directly telnet to an MX server and check for the existence of a user.
The edited powerful powershell generic telnet method is here:
Function Get-Telnet { Param ( [Parameter(ValueFromPipeline=$true)] [String[]]$Commands = @("helo hi"), [string]$RemoteHost = "HostnameOrIPAddress", [string]$Port = "25", [int]$WaitTime = 1000 ) #Attach to the remote device, setup streaming requirements $Socket = New-Object System.Net.Sockets.TcpClient($RemoteHost, $Port) If ($Socket) { $Stream = $Socket.GetStream() $Writer = New-Object System.IO.StreamWriter($Stream) $Buffer = New-Object System.Byte[] 1024 $Encoding = New-Object System.Text.AsciiEncoding #Now start issuing the commands ForEach ($Command in $Commands) { Write-Host $Command $Writer.WriteLine($Command) $Writer.Flush() Start-Sleep -Milliseconds $WaitTime } $Result = "" #Save all the results While($Stream.DataAvailable) { $Read = $Stream.Read($Buffer, 0, 1024) $Result += ($Encoding.GetString($Buffer, 0, $Read)) } } Else { $Result = "Unable to connect to host: $($RemoteHost):$Port" } $Result }
You call it by passing in a param array of commands, a host, and a delay time between each command being sent, e.g.:
Get-Telnet -RemoteHost "192.168.10.1" -Commands "admin","password","terminal pager 0","show run" -WaitTime 1500
I’m only interested in hitting a mail server, so my commands are below.
- Start a session: “helo example.com”
- Create a new email from a dummy user: “mail from: <[email protected]>”
- Set the recipient to the user we’re trying to validate: “rcpt to: <$email>”
If the user exists then the third command returns status code “250”; if not, the status code is “550” – this is all I’ll check for.
The script below will split an email address and get the domain, find out the MX record using Resolve-DnsName, then log on via telnet to the mail server and attempt to create a mail to that user, returning the results of all commands and checking for an occurrence of “550”.
(syntax highlighter is throwing a wobbly if I use an email address inside the code block, so imagine “botATexample.com” is “[email protected]”)
try { $notexists = true $email = Read-Host 'Enter an email address to test' $columns = $email -split '@' $mx = (Resolve-DnsName -Type MX –Name $columns[1] -ea 0) if ($mx -ne $null){ $notexists = (Get-Telnet -RemoteHost $mx.NameExchange[0] -Commands "helo example.com","mail from: <botATexample.com>","rcpt to: <$email>" -WaitTime 500).Contains("550") } if ($notexists) {Write-Host "Doesn't exist"} else {Write-Host "Exists! "} } catch [system.exception] { Write-Host $_.Exception.ToString() }
The results might look something like this:
Notes
A helluva lot of mail servers will block this telnet connection! Therefore this is not a reliable method to get all existing users from a list of email addresses; it will result in a LOT of false negatives.
However, those that it returns as real users will certainly be real users.