Dialplan Vulnerabilities

The Asterisk dialplan is another area where taking security into consideration is critical. The dialplan can be broken down into multiple contexts to provide access control to extensions. For example, you may want to allow your office phones to make calls out through your service provider. However, you do not want to allow anonymous callers that come into your main company menu to be able to then dial out through your service provider. Use contexts to ensure that only the callers you intend have access to services that cost you money.

Tip #7: Build dialplan contexts with great care. Also, avoid putting any extensions that could cost you money in the [default] context.

One of the more recent Asterisk dialplan vulnerabilities to have been discovered and published is the idea of dialplan injection. A dialplan injection vulnerability begins with an extension that has a pattern that ends with the match-all character, a period. Take this extension as an example:

exten => _X.,1,Dial(IAX2/otherserver/${EXTEN},30)

The pattern for this extension matches all extensions (of any length) that begin with a digit. Patterns like this are pretty common and convenient. The extension then sends this call over to another server using the IAX2 protocol, with a dial timeout of 30 seconds. Note the usage of the ${EXTEN} variable here. That’s where the vulnerability exists.

In the world of Voice over IP, there is no reason that a dialed extension must be numeric. In fact, it is quite common using SIP to be able to dial someone by name. Since it is possible for non-numeric characters to be a part of a dialed extension, what would happen if someone sent a call to this extension?

1234&DAHDI/g1/12565551212

A call like this is an attempt at exploiting a dialplan injection vulnerability. In the previous extension definition, once ${EXTEN} has been evaluated, the actual Dial() statement that will be executed is:

exten => _X.,1,Dial(IAX2/otherserver/1234&DAHDI/g1/12565551212,30)

If the system has a PRI configured, this call will cause a call to go out on the PRI to a number chosen by the attacker, even though you did not explicitly grant access to the PRI to that caller. This problem can quickly cost you a whole lot of money.

There are (at least) two approaches for avoiding this problem. The first and easiest approach is to always use strict pattern matching. If you know the length of extensions you are expecting and only expect only numeric extensions, use a strict numeric pattern match. For example, this would work if you are expecting four-digit numeric extensions only:

exten => _XXXX,1,Dial(IAX2/otherserver/${EXTEN},30)

The other approach to mitigating dialplan injection vulnerabilities is by using the FILTER() dialplan function. Perhaps you would like to allow numeric extensions of any length. FILTER() makes that easy to achieve safely.

exten => _X.,1,Set(SAFE_EXTEN=${FILTER(0-9,${EXTEN})})
    same => n,Dial(IAX2/otherserver/${SAFE_EXTEN},30)

For more information about the syntax for the FILTER() dialplan function, see the output of the core show function FILTER command at the Asterisk CLI.

Tip #8: Be wary of dialplan injection vulnerabilities. Use strict pattern matching or use the FILTER() dialplan function to avoid these problems.