Caller ID Spoofing with Microsoft Teams and Calling Plan

Microsoft Calling Plans for Teams are a great way for Teams users to enable the telephony features of Microsoft Teams without having to deploy any of the infrastructure required for Teams Direct Routing.  When you use the Calling Plan service, the entire PBX experience is managed by Microsoft - they provide the phone numbers (DIDs) and inbound/outbound calling.  One challenge that some people have with using Calling Plan however is that the outbound call display number to send is limited to numbers you purchased from Microsoft - if for example you had a Toll Free number from a third party pointed at one of your Microsoft DIDs for an auto-attendant there is no easy way to also use that number for your outbound display.  If you attempt to create a Teams calling line ID policy for a number that isn't in your tennent you will get an error that "The Service number +1XXXXXXXXXX is not valid.  Please ensure that the service number is configured in BVD and belongs to this Tenant".

In a standard SIP-enabled PBX, doing a number override for an arbitrary number is a pretty standard feature - most SIP carriers will accept whatever number you send.  This is known as "CLID Spoofing" and while it has lots of possible cases for abuse, it is really useful when you get services from more than one carrier and want to display a unified caller ID across both.

So as a Teams customer who subscribes to Calling Plan how can you use a arbitrary number as your calling line ID?  The solution is simple - create a dedicated resource account, assign the target number to that user as a "Direct Routing Number", and then create a calling line ID policy based off that user.  This works even if you don't have any of the other requirements for direct routing setup.

Specifcally, here are the commands you need to use in PowerShell.  This requires you have the MicrosoftTeams and MsOnline powershell modules installed and you have an authenticated session to both.  

Steps to use your own Calling Line ID in Teams

First you need to authenticate yourself to Microsoft Teams:

Connect-MicrosoftTeams

Then you need to connect to Microsoft Online Services:

Connect-MsOnlineService

With both of these connected you should now be able to run the commands below. The first step is to set some variables in your powershell session that will be used throughout. In the variables below,replace NPANXXXXXX with the number you want to use as the CLID Number display, MYDOMAIN with the domain for your Office 365 tennet, and CLID NAME with the desired CLID Name Display.

$Name = CLID-NPANXXXXXX-ONPREM@MYDOMAIN.onmicrosoft.com
$Number = "+1NPANXXXXXX"
$CLIDName = "CLID NAME"
$PolicyName = "CLID-NPANXXXXXX-ONPREM"

With the variables in place, create a resource account

New-CsOnlineApplicationInstance -UserPrincipalName $Name

Now sleep for 60 seconds to ensure the Office 365 backend is in sync

Start-Sleep -Seconds 60

Change the usage location as appropriate, in my case I use Canada but this needs to be adjusted to the correct usage location.

Set-MsolUser -UserPrincipalName $Name -UsageLocation "CA"

Next we assign the user a phone system virtual license - replace MYDOMAIN with the base domain of the Office365 account:

Set-MsolUserLicense -UserPrincipalName $Name -AddLicenses MYDOMAIN:PHONESYSTEM_VIRTUALUSER

Now sleep for another 60 seconds to ensure the license is in sync. Or just wait. It sometimes takes a bit longer than 60 seconds for everything to update on the Microsoft backend.

Start-Sleep -Seconds 60

Assign the target number to the resource account

Set-CsOnlineApplicationInstance -Identity $Name -OnPremPhoneNumber $Number

Get the ObjectId of the resource account we created

$ResourceAccountId = (Get-CsOnlineUser "$Name").ObjectId

Finally create the CallingLineIdenity policy, which we can then assign to end users as required

New-CsCallingLineIdentity -Identity $PolicyName -ResourceAccount $ResourceAccountId -Description $PolicyName -CompanyName $CLIDName -CallingIdSubstitute "Resource"  -EnableUserOverride $false

You now have a calling line ID policy created in Teams that can be assigned to any user and will display the calling line number and name you specified when creating this script.

This has a lot of potential for abuse - for example if you were to display a number that didn't actually belong to you and you used Teams for a telemarking campaign you could face fines of up to $1,500 per violation for an individual and up to $15,000 per violation for a corporation.  In a perfect world, Microsoft would implement some better way for organizations to bring their own numbers with some form of verification before allowing them to be used as a outbound CLID to limit the potential for abuse.  So remember, with great power comes great responsibility so please only use this power for good.