PJSIP trunk auth and malicious external contacts

Hi all,

I reconfigured a few of my trunks for testing purposes. I know that this setup isn’t ideal in terms of security, but I wan’t to figure out what’s happening.

I have two Asterisk nodes let’s call them pbxint (internal network) and pbxdmz (public network, UDP allowed. Yes I know, bad practice). I’ve found out that when a malicious user sends OPTIONS to PBXDMZ, this allows the creation of a additional (malicious) contact for the trunk on PBXINT.

Flow:
external user that sends OPTIONS ==> pbxdmz ==> PJSIP trunk with auth ==> pbxint

pbxint*CLI> pjsip show aor pbxdmz

  Aor:  pbxdmz                                                1
Contact:  pbxdmz/sip:pbxdmz@<MALICIOUSIP>              f8266a8760 Avail         1.223
Contact:  pbxdmz/sip:<PBXDMZIP>                     d007245f0e Avail         1.657

I’ve configured authenticated trunks and these seem to be working fine.

Trunk config on pbxint. “Auth” requires incoming authentication from pbxdmz:

[pbxdmz]
type=registration
transport=transport-udp
server_uri=sip:pbxint@PBXDMZIP:5060
client_uri=sip:pbxint@PBXDMZIP:5060
contact_user=pbxint
outbound_auth=pbxdmz-auth

[pbxdmz]
type=endpoint
transport=transport-udp
context=TRUNKCONTEXT
direct_media=no
disallow=all
allow=alaw,ulaw,h264,h261,h263,h263p,vp8
aors=pbxdmz
auth=pbxdmz-auth
from_user=pbxint

[pbxdmz]
type=aor
max_contacts=1
remove_existing=yes
contact=sip:PBXDMZIP
authenticate_qualify=yes
qualify_frequency=60
qualify_timeout=5.0

[pbxdmz-auth]
type=auth
auth_type=userpass
username=SOME USER
password=SOME PASS

[pbxdmz]
type=identify
endpoint=pbxdmz
match=PBXDMZ IP

Trunk config on pbxdmz doing outbound auth to dmzint (but not requiring it since the client endpoints have their own auth required).

[dmzint]
type=registration
transport=transport-udp
server_uri=sip:pbxdmz@PBXINTIP:5060
client_uri=sip:pbxdmz@PBXINTIP:5060
contact_user=pbxdmz
outbound_auth=pbxint-auth

[pbxint]
type=endpoint
transport=transport-udp
context=TRUNKCONTEXT
direct_media=no
disallow=all
allow=alaw,ulaw,h264,h261,h263,h263p,vp8
aors=pbxint
from_user=pbxdmz
outbound_auth=pbxint-auth

[pbxint]
type=aor
max_contacts=1
remove_existing=yes
contact=sip:PBXINTIP
authenticate_qualify=yes
qualify_frequency=60
qualify_timeout=5.0

[pbxint-auth]
type=auth
auth_type=userpass
username=SOME USER
password=SOME PASS

[pbxint]
type=identify
endpoint=pbxint
match=PBXINTIP

Can someone tell me why this malicious contact is created after sending (unauthenticated) OPTIONS? Is this something that can be prevented within Asterisk or should I just block OPTIONS coming from outside in iptables?

I’m a bit confused by your use of outbound authorization on these endpoints. That said, I think the problem is that you’re sending the malicious request through the pbxdmz, which this Asterisk node is then matching to TRUNKCONTEXT (as expected) based on it coming from the IP of pbxdmz and you having it set up as an identify type endpoint matched by IP. Setting up a trunk this way only is a good idea if the sending node has sufficient security hardening to prevent malicious messaging from getting through. I’d say that your problem here is not that pbxint recognized the contact, but that you seem to be looking to use Asterisk like an SBC for pbxdmz, but are not configuring it to block malicious requests.

Use the option

authenticate_qualify

If true and a qualify request receives a challenge or authenticate response authentication is attempted before declaring the contact available

Thanks, this explains the behavior. Could I just remove the identify to make sure the contact creation doesn’t happen? I’ll make sure to tighten the security a bit.

The option is already present in the config above?

I don’t see how you’re intending to allow only certain messages to come through with this setup. How is Asterisk supposed to know which things to allow from the DMZ PBX and which ones to forbid in this setup?

Yes you’re right. I’ve closed incoming external UDP since configuring iptables to only allow OPTIONS coming from the internal network was still not sufficient. Didn’t want to take any risk so I’ll just allow external TCP and TLS.

Anyway, I can figure why OPTIONS sent to the DMZ PBX were trusted on the INT PBX (because of identify match) but I still wonder why they were forwarded to INT PBX in the first place?