More and more companies uses VoIP to communicate on the phone with their customers,
also because the calls are cheaper than over the traditional lines, but that’s not always the primary reason.
A company has the demand to let its colleagues communicate on the phone, on-site or remotely.
Has the need to manage many inbound trunks, routing the calls toward a defined group of extensions.
May have the need to record the calls, to transfer them to a mobile phone, to have an answering machine …
in short: it needs a telephone exchange.
The computational power of the modern CPUs allows to use a normal personal computer as a PBX.
As the PC capacity to playback audio is leading to a revolution in the fruition of the musical artworks,
the video playback to the vanishing of the videotapes recorders and to the birth of new standards, storage formats and high definition screens;
the ability to unify telephony with IT suggests new solutions to improve the quality of our work and the customer satisfaction.
Asterisk is an open-source software capable of converting audio and video streams into different formats, in real time.
By using dedicated hardware, it’s possible to integrate it with traditional telephone technologies: analog, ISDN, GSM, etc.
It’s programmable through its configuration files or through graphical user interfaces.
Each of its components can be customized and integrated with other software and hardware, as in the best GNU/Linux philosophy.
In short: it’s the telephone exchange software more used by both businesses and telephone companies (carriers) in the world.
So Asterisk allows to move all the telephony infrastructure from the physical world to that of the servers and of the Internet:
the telephone exchange becomes one of the many services in execution on the server,
while the VoIP traffic, as said, on the IP network.
But if this migration allows to enclose the maintenance of a new generation telephone network to one of the many duties of the system
administrator, the same care devoted to the other services must be addressed to put it into security and to the monitoring of possible attacks and abuses.
In this article we are going to analyze some intrinsic flaws of the most used protocol to carry voice over IP networks: the SIP protocol.
The SIP protocol (Session Initiation Protocol, RFC 3261) became almost the standard when using VoIP services.
Asterisk manges the SIP protocol out of the box, both in client and server mode.
As an example, let’s take a typical company configuration, where Asterisk provides the typical services of a telephone exchange:
- allows the extensions to call each other
- allows the extensions to dial outbound, through one or more carriers
- allows the inbound calls to reach an extension
Basically Asterisk acts as a router, with the necessary differences given by the different network protocols:
in particular the ‘registration’ mechanism.
The registration allows the various components (extensions, Asterisk and the carrier) to enable each other
and to know their respective IP addresses, with an authentication, optional, using an username / password pair.
In this configuration, the extensions will register with Asterisk
while Asterisk, in turn, is going to register with the carrier.
In this article we are going to see how to perform a ‘brute force‘ attack toward the username / password pair of an Asterisk extension,
how to perform a ‘users enumeration’ attack
and above all how to monitor the Asterisk’s logs to detect, in real time:
- repeated failed registration attempts toward an existing extension
- repeated failed registration attempts toward not existing extensions
- a successful registration after one or more failed registrations
by using an instrument to simulate a SIP client (SIPp) and another one to correlate the events (SEC),
both open-source and licensed under the GNU GPL.
It’s possible to perform those attacks only if the SIP port of Asterisk (which defaults to 5060 UDP) is reachable to the attacker,
this condition is met when, for example:
- in a configuration where it’s necessary to allow the extension to register remotely,
thus granting a direct access to the SIP port.
In this case is advisable, if possible, to incapsulate the traffic to the Asterisk’s resources through a VPN. - if the attacker has already penetrated into the LAN
and can run the attacks from the same subnet of the one of the extensions. - In this case is advisable, where possible, to authenticate the customers by using their IP address instead of the username / password pair.
Let’s now configure Asterisk as a testing platform:
it will simply allow the registration of an extension,
so that it will be enough to edit the sip.conf file (which by default is in the /etc/asterisk folder) to have this result:
[general]
bindport=5060
bindaddr=0.0.0.0
allow=all
canreinvite=no
autocreatepeer=no
[101]
type=friend
host=dynamic
username=101
secret=101
qualify=yes
allow=all
and be sure that the file logger.conf (which by default is in the /etc/asterisk folder) has enabled at least the debugging levels ‘notice‘ and ‘verbose‘
in one of the ‘filename’, like that:
[general]
[logfiles]
console => notice,warning,error,dtmf,debug,verbose
messages => notice,verbose
so that the registration messages will be wrote in the ‘messages’ file (which by default is in the /var/log/asterisk folder).
Restart Asterisk to make it aware about the new changes,
or run the commands ‘logger reload‘ and ‘sip reload‘ in its command line interface to restart only the related services.
Good, now we are going to install and configure SIPp.
Download SIPp from the project’s hope page, http://sipp.sf.net
for example from here: http://dfn.dl.sourceforge.net/sourceforge/sipp/sipp.3.1.src.tar.gz
from a different PC of the Asterisk server, or on a virtual machine.
Explode the archive and execute the command ‘make ossl’ to compile it with the ssl facilities, which are necessary to execute the registration
attempts (ensure to satisfy it’s dependencies, particularly the ‘openssl‘ library).
The official SIPp installation document is available here: http://sipp.sf.net/doc/reference.html#Installing+SIPp
or even more detailed here: http://sipp.sourceforge.net/wiki/index.php/Compilation
Is now necessary to create a scenario which allows to set:
- the IP address and the SIP port of the Asterisk server
- the IP address of the client
- a ‘csv‘ format file from where obtain the username / password pairs to use during the registration attempts
Like this one:
<![CDATA[
REGISTER sip:[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: ;tag=[call_number]
To:
Call-ID: [call_id]
CSeq: 1 REGISTER
Contact:
Max-Forwards: 5
Expires: 5
User-Agent: SIPp/Linux
Content-Length: 0
]]>
<![CDATA[
REGISTER sip:[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: ;tag=[call_number]
To:
Call-ID: [call_id]
CSeq: 2 REGISTER
Contact:
[field2]
Max-Forwards: 5
Expires: 5
User-Agent: SIPp/Linux
Content-Length: 0
]]>
Save it as ‘register_client.xml’.
(Here the original file)
With this scenario, also, is possible to save on a file the successful registration attempts and the users enumeration attempts:
with the option -trace_logs, as we will see next.
Unfortunately this article will not meticulously describe SIPp’s and this scenario potentiality,
but, in short:
remote_ip, remote_port, transport, local_ip and local_port are variables set at SIPp’s execution time on the command line interface,
while field0, field1 and field2 are the fields populated from the ‘csv’ file at each attempt.
The file ‘csv’, for example, can have this format:
SEQUENTIAL
201;201;[authentication username=201 password=201];
101;102;[authentication username=101 password=102];
101;101;[authentication username=101 password=101];
Save it as ‘register_client.csv’.
Please refer to this documentation:
http://sipp.sf.net/doc/reference.html#Injecting+values+from+an+external+CSV+during+calls
for the other supported format types.
Good, it’s almost time to run SIPp,
but before is necessary, on the PC on where Asterisk is installed, to:
* run Asterisk: the default command is ‘asterisk -vvvc’
* monitor its ‘messages’ log file: the default command is ‘tail -f /var/log/asterisk/messages’
Now, presuming that:
- run Asterisk: the default command is ‘asterisk -vvvc’
- monitor its ‘messages’ log file: the default command is ‘tail -f /var/log/asterisk/messages’
Now, presuming that:
- the IP address on the PC on where is running Asterisk is 172.16.160.1
- the SIP port of Asterisk is the default one: 5060 (set in the sip.conf file)
- the IP address of the PC on where SIPp in going to run is 172.16.160.128
is possible to run SIPp with the command:
./sipp -sf register_client.xml -inf register_client.csv -l 1 -m 3 -r 1 -t un -trace_err -trace_logs -i 172.16.160.128 172.16.160.1
where:
-sf
selects the scenario
-inf
the ‘csv’ file
-l
the max number of concurrent attempts
-m
the overall number of attempts to perform, then the test will finish
-r
the number of concurrent attempts in one second
-t
the type of socket to use
-trace_err
save the unexpected messages in the file
<scenario file name>_<pid>_errors.log
-trace_logs
save the log messages in the file
<scenario file name>_<pid>_logs.log
(in this case the registration and users enumeration successful attempts)
-i
the source IP address of the attempts (SIPp)
while the last argument is the destination IP address of the attempts (Asterisk).
Around the end of the log file ‘messages’ you should see the following messages:
[Nov 26 16:41:33] NOTICE[9914] chan_sip.c: Registration from ” failed for ‘172.16.160.128′ – No matching peer found
[Nov 26 16:41:34] NOTICE[9914] chan_sip.c: Registration from ” failed for ‘172.16.160.128′ – Wrong password
[Nov 26 16:41:35] VERBOSE[9914] logger.c: — Registered SIP ‘101′ at 172.16.160.128 port 1095 expires 60
where:
- the first row shows that a registration attempt with a wrong username has been made
- the second row shows that a registration attempt with a correct username but a wrong password has been made
- the third row shows a successful registration
Let’s now study a solution which can point out, in real time, those situations.
Let’s take, for example, those events:
[Nov 26 16:41:34] NOTICE[9914] chan_sip.c: Registration from ” failed for ‘172.16.160.128′ – Wrong password
[Nov 26 16:41:35] NOTICE[9914] chan_sip.c: Registration from ” failed for ‘172.16.160.128′ – Wrong password
[Nov 26 16:41:36] VERBOSE[9914] logger.c: — Registered SIP ‘101′ at 172.16.160.128 port 1095 expires 60
which shows that, after two failed registration attempts, the extension 101 has successfully registered.
In this case, the events appeared at one second of gap from each other,
but they could have been more rare
and mixed with other events.
Those events, taken individually, do not represent a serious threat,
nor do they highlight a possible SIP account violation.
An IDS is not able to detect this risk
as opposed to an event correlation engine.
The event correlation is a technique which can spotlight with accuracy a connection between two or more occurrences,
even if they are hidden by a multitude.
It is used in the most disparate fields: for example in the industrial process control, in business activity monitoring,
in network management and in the telecommunications field.
The event correlators are very expensive. SEC is the exception which proves the rule: it’s the only open-source event correlator.
SEC (Simple Event Correlator) is a mature, fast software, written in PERL, its home page is http://kodu.neti.ee/~risto/sec/
SEC supports various correlation rules; but here, for simplicity, we will use only three of them:
Single
which triggers its action at the first match of the pattern
SingleWithThreshold
which triggers its action at the N match of the same pattern, inside a time window
Pair
which triggers its action when two different patterns match
Let’s develop a first simple rule,
the objective will be to identify the registration attempts with both username and password wrong
and to show them on the screen, counting them increasingly:
# matches each wrong SIP username registration, from the same host and to the same host, with counter (1)
type=Single (2)
ptype=RegExp (3)
rem=Registration from '' failed for '172.16.160.128' - No matching peer found (4)
pattern=Registration from '' failed for '(\S+)' - No matching peer found (5)
desc=Asterisk SIP - no matching peer found - $1@$2 for $3 (6)
action=eval %x ++$c{"c_$2_$3"} ; write - Asterisk SIP - %t - No matching peer found, counter: %x - $1@$2 for $3 (7)
(Here the original file)
save it with the name ‘test.sec’ (omitting, while copying it, the number of the row)
and run SEC with this rule, making it follow the ‘messages’ file of Asterisk, with this command:
./sec.pl -conf=test.sec -input=/var/log/asterisk/messages
ensure that Asterisk is running
and from another PC run SIPp, populating the ‘csv’ file, for example, with those values:
SEQUENTIAL
201;201;[authentication username=201 password=201];
trying thus to register an non-existent extension.
In the SEC screen we should get this result:
Evaluating code ‘++$c{“c_172.16.160.1_172.16.160.128″}’ and setting variable ‘%x’
Variable ‘%x’ set to ‘1′
Writing event ‘Asterisk SIP – Thu Nov 27 19:15:01 2008 – No matching peer found, counter: 1 – 201@172.16.160.1 for 172.16.160.128′ to file -
Asterisk SIP – Thu Nov 27 19:15:01 2008 – No matching peer found, counter: 1 – 201@172.16.160.1 for 172.16.160.128
where the most meaningful row (among the other debug ones) is the last one.
This is the explanation of each row of the rule:
1 it’s a comment line, gets ignored
2 the type of rule, discussed above
3 the pattern type: a regular expression (see http://kodu.neti.ee/~risto/sec/sec.pl.html#lbAG)
4 it’s a comment line, in the SEC format, gets ignored.
It’s allowed to use as much of them as you like,
as opposed to those comments which starts with the ‘#’ char, which instead spawns syntax errors.
In this case it has been used to remind an example of a string which gets matched by this rule.
5 the pattern which allows to match a string like, for example, the one on the row 4.
The round brackets allows to store what has been matched
into special variables identified by a consecutive number ($1, $2, …)
6 the textual description of the rule, it gets printed on the screen if action=logonly. So not in this case.
7 the action to execute when the event gets detected.
In this case the actions are two, separated by the ‘;’ char
eval %x ++$c{“c_$2_$3″} – increases by 1 the counter of the events which comes from the same host and aimed toward the same host
and assign it to the SEC variable %x
$2 stores the second round bracket content of the row 5: the destination host
$3 stores the third round bracket content of the row 5: the source host
In this way, each event having unique source and destination host will have its own counter.
write – Asterisk SIP – %t – No matching peer found, counter: %x – $1@$2 for $3
outputs to the screen the string status, replacing the variables with their content.
%t is a SEC variable which stores the current date and time
It’s not very useful, but it’s a good starting point.
Let’s now try to complete it, making it identify repeated attacks, is this way:
# matches each wrong SIP username registration, from the same host and to the same host, with counter
type=Single
continue=TakeNext (1)
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - No matching peer found
pattern=Registration from '' failed for '(\S+)' - No matching peer found
desc=Asterisk SIP - no matching peer found - $1@$2 for $3
action=eval %x ++$c{"c_$2_$3"} ; write - Asterisk SIP - %t - No matching peer found, counter: %x - $1@$2 for $3
# matches 2 wrong SIP username registrations in less than 1 minute, from the same host and to the same host
type=SingleWithThreshold (2)
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - No matching peer found
pattern=Registration from '' failed for '(\S+)' - No matching peer found
desc=Asterisk SIP - 2 wrong peers in less than 1 minute - $1@$2 for $3
action=write - Asterisk SIP - %t - 2 wrong peers in less than 1 minute - $1@$2 for $3
window=59 (3)
thresh=2 (4)
(Here the original file)
Populate SIPp with the following data:
SEQUENTIAL
201;201;[authentication username=201 password=201];
301;301;[authentication username=301 password=301];
thus making it try to register two non-existent extensions, sequentially.
Let’s execute SEC with the command:
./sec.pl -debug=1 -conf=test.sec -input=/var/log/asterisk/messages
obtaining this result on the screen:
Asterisk SIP – Thu Nov 27 19:38:09 2008 – No matching peer found, counter: 1 – 201@172.16.160.1 for 172.16.160.128
Asterisk SIP – Thu Nov 27 19:38:10 2008 – No matching peer found, counter: 2 – 301@172.16.160.1 for 172.16.160.128
Asterisk SIP – Thu Nov 27 19:38:10 2008 – 2 wrong peers in less than 1 minute – 172.16.160.1@172.16.160.128 for $3
where the last row confirms the ongoing potential threat.
This is the explanation of the new rows of the rules:
1 instructs SEC to continue the matching also in the next rule, passing it the input string.
2 the rule type, discussed above:
SingleWithThreshold – which triggers its action at the N match of the same pattern, inside a time window
3 the time window: 59 seconds
4 the threshold: 2 events
Now let’s populate the SIPp’s ‘csv’ file with those data:
SEQUENTIAL
101;aaa;[authentication username=101 password=aaa];
101;aab;[authentication username=101 password=aab];
This rule, by using the same tools as the previous,
allows to identify a brute force attack toward an existing extension:
# matches each wrong SIP password registration, from/to the same host and for the same user, with counter
type=single
continue=TakeNext
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - Wrong password
pattern=Registration from '' failed for '(\S+)' - Wrong password
desc=Asterisk SIP - wrong password - $1@$2 for $3
action=eval %x ++$c{"c_$1_$2_$3"} ; write - Asterisk SIP - %t - wrong password, counter: %x - $1@$2 for $3
# matches 2 wrong SIP password registrations in less than 1 minute, from/to the same host and for the same user
type=SingleWithThreshold
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - Wrong password
pattern=Registration from '' failed for '(\S+)' - Wrong password
desc=Asterisk SIP - 2 wrong passwords in less than 1 minute - $1@$2 for $3
action=write - Asterisk SIP - %t - 2 wrong passwords in less than 1 minute - $1@$2 for $3
window=59
thresh=2
(Here the original file)
Good, now it’s time to develop a rule which puts in practice the correlation of different events.
Let’s populate the SIPp’s ‘csv’ file with those data:
SEQUENTIAL
101;aaa;[authentication username=101 password=aaa];
101;aab;[authentication username=101 password=aab];
101;101;[authentication username=101 password=101];
in this configuration, SIPp will try two wrong password and then the right one.
From the attacker point of view, it will have executed a brute force attack toward an existing extension,
guessing the authentication credential at the third attempt.
From the attacked system point of view, to identify this potential access violation will be necessary to correlate the failed registration events
followed by the successful registration one.
To develop the rule it’s possible to use the type ‘Pair’, in this way:
# matches N failed SIP registration followed by a successfull registration, from/to the same host and for the same user
type=Pair (1)
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - Wrong password
pattern=Registration from '' failed for '(\S+)' - Wrong password
desc=Asterisk SIP - wrong password - $1@$2 for $3
action=write - Asterisk SIP - %t - wrong password - $1@$2 for $3
ptype2=RegExp (2)
rem=Registered SIP '101' at 172.16.160.128 port 1095 expires 60
pattern2=Registered SIP '$1' at $3 port (\S+) expires (\S+) (3)
desc2=Asterisk SIP - registered after failures - %1 at %3 port $1 expires $2 (4)
action2=write - Asterisk SIP - %t - registered after failures - %1 at %3 port $1 expires $2 (5)
(Here the original file)
having on the screen this result:
Asterisk SIP – Thu Nov 27 19:53:54 2008 – wrong password – 101@172.16.160.1 for 172.16.160.128
Asterisk SIP – Thu Nov 27 19:53:57 2008 – registered after failures – 101 at 172.16.160.128 port 1095 expires 60
the explanation of the new rows of the rule are:
1 the rule type, discussed above:
Pair – which triggers its action when two different patterns match
2, 3, 4 e 5 the parameters of the second match
Now let’s try to add a counter for the registration failures attempts
by using again the feature to link together more rules, in that way:
# matches each wrong SIP password registration, from/to the same host and for the same user, with counter
type=single
continue=TakeNext
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - Wrong password
pattern=Registration from '' failed for '(\S+)' - Wrong password
desc=Asterisk SIP - wrong password - $1@$2 for $3
action=eval %x ++$c{"c_$1_$2_$3"} ; write - Asterisk SIP - %t - wrong password, counter: %x - $1@$2 for $3
# matches N failed SIP registration followed by a successfull registration, from the same host and for the same user
type=Pair
ptype=RegExp
rem=Registration from '' failed for '172.16.160.128' - Wrong password
pattern=Registration from '' failed for '(\S+)' - Wrong password
desc=Asterisk SIP - wrong password - $1@$2 for $3
action=none
ptype2=RegExp
rem=Registered SIP '101' at 172.16.160.128 port 1095 expires 60
pattern2=Registered SIP '$1' at $3 port (\S+) expires (\S+)
desc2=Asterisk SIP - registered after failures - %1 at %3 port $1 expires $2
action2=eval %y $c{"c_%1_%2_%3"} ; write - Asterisk SIP - %t - registered after %y failures - %1 at %3 port $1 expires $2
(Here the original file)
obtaining on the screen this result:
Asterisk SIP – Mon Dec 1 21:45:12 2008 – wrong password, counter: 1 – 101@172.16.160.1 for 172.16.160.128
Asterisk SIP – Mon Dec 1 21:45:13 2008 – wrong password, counter: 2 – 101@172.16.160.1 for 172.16.160.128
Asterisk SIP – Mon Dec 1 21:45:14 2008 – registered after 2 failures – 101 at 172.16.160.128 port 1095 expires 60
Note on the last row the warn “registered after 2 failures” which, by using the counter,
resumes more events in only one, showing it in a fast and understandable manner.
Note also that no time window has been used:
this solution is immune to the so-called “under the radar” attack mode
which slows down the attack attempts rate (for example one every 30 seconds)
in the hope that it will not be detected by an IDS with ‘insufficient short-term memory’.
If you are a VoIP carrier, for example,
a successful registration happened after two failures would suggest for sure a customer of your service which was configuring
his device to interconnect with you;
but if a successful registration happened after, let’s suppose, 1000 failed attempts,
then we are facing for sure a succeeded intrusion into your system
which would probably lead to the total drain of the phone credit of the victim.
And if this unaware customer maybe has the fault to have chosen a weak password for his SIP account
you have the professional duty to protect your system and your customers with the best defenses available.
If you are a firm and an extension of your gets compromised, you may be vulnerable to a social engineering attack attempt:
if your extensions can call each other, the attacker may pretend to be a colleague of yours,
making appear the call as if it comes from inside the company.
This article wanted to explain the implementation of some simple event correlation rules,
by using the open-source software SEC.
Staying in the VoIP scope, with this instrument is possible to achieve much more:
for example it’s possible to monitor the resources, the usage and the abuses; identify distributed attacks, flood (DDOS), INVITE [1] …
While in the scope of the event analysis in general,
it’s possible to monitor hardware, Operating System events, network services or to serve statistical reports, or even to merge many heterogeneous
sources toward a single central processor.
Notes
[1] http://sipvicious.org/blog/2008/04/storming-sip-security-now-available.html
Additional material
Asterisk home page: http://www.asterisk.org
SIPp home page: http://sipp.sourceforge.net
SEC home page: http://kodu.neti.ee/~risto/sec
SEC tutorial: http://en.hakin9.org/attachments/pdf/hakin9_05_2006_10_EN_str28-39.pdf
SEC tutorial: http://sixshooter.v6.thrupoint.net/SEC-examples/article.html
LogSurfer home page: http://www.crypt.gen.nz/logsurfer
Links
http://voipsa.org
http://sipvicious.org
http://www.milw0rm.com/search.php?dong=sip
http://www.hakin9.org/prt/view/voice-over-ip.html
http://voipsecurityblog.typepad.com
http://www.unprotectedhex.com/index.php?option=com_content&task=section&id=4&Itemid=31
SEC integration solutions suggestions
http://code.google.com/p/php-syslog-ng
http://webfwlog.sourceforge.net
http://www.splunk.com
http://www.zenoss.com
http://munin.projects.linpro.no
http://cacti.net
How to prevent users enumeration on Asterisk
Asterisk Project Security Advisory – AST-2009-003
|
|
This guide is also available in Italian |
![]() |
|


