SIP INVITE attack with Metasploit

Some days ago my friend @pepeluxx wrote another post about INVITE attacks. He spoke about a @sinologic project which allows to everybody passing some security tests to SIP servers. Furthermore he also published a perl script to do the same task. So I implemented it on Metasploit because I think It could be really useful during a pentesting. It’s interesting because these attacks are really dangerous, normally, attackers try to call to expensive locations. This target numbers often have special charges and they make money with this. Here there are two well known examples:

I’m not going to deep in this vector because of being a well known (and old!!) one. Basically the attacker tries to make a call using a misconfigured PBX. This is allowed because SIP RFC says that an extension has not to be registered to be able to make a call, only to receive it. Really most SIP servers implement authentication both in registering and calling process (and even to hang up a call), this is useful in eavesdropping scenarios in order to avoid SIP Teardown (BYE) attacks. But only a few systems have this configuration enabled by default, most of them use authentication only to register. In example, for Asterisk we should change “allowguest=no” in "sip.conf" file to ask for authentication in each call (INVITE). Apart from this, sysadmins should be also very carefully defining the dialplan to be secure. A common example of what not to do is the next one, in where outbound (to PSTN) calls context is included in default one:

(sip.conf file)

(extensions.conf file)
include  => outbound

I committed the module to my Github project, it only implements a SIP INVITE request where the user can provide next parameters:

Module parameters

You should try to call to a common phone number (you can see it in last picture) and with an extension because servers normally work in a different way. The code simply sends an INVITE request with provided options and then it parses the response. If it is a “Trying” you could be in a problem man. ;)

Possible insecure system

Possible insecure system

Secure system to this vector

These are the links to both UDP and TCP version of the tool. I would like to remember that Metasploit modules which support TCP also support TLS. You can change the version of the protocol and another optional parameters with command “show advanced”.
Advanced options

Finally I want to say that last days I was reviewing my SIP Metasploit modules trying to add some more features (like SIP proxy support) and I found that they are a mess. There is a lot of repeated code and they are complex to maintain. So, after speaking with some Metasploit guys on irc channel, I’m going to write a new SIP Proto ("lib/rex/proto/sip.rb") class and a Mixin ("lib/msf/core/auxiliary/sip.rb") which uses it. Once solved this I’m going to add all SIP modules I have developed to official Metasploit distribution.

Ref: http://www.sinologic.net/blog/2009-02/la-voip-mal-configurada-llama-a-cuba/


Playing with QoffeeSIP: SIP over websocket scanner

Some weeks ago we published QoffeeSIP, the Javascript SIP over websockets stack which we use to develop our WebRTC products in Quobis. An example is IdentityCall, a system designed to provide call authentication in traditional VoIP and IMS environments. Now it achieves the same goal in WebRTC ones, interconnecting them at the same time with PSTN network.

Today I’m showing a different case of use that those proposed in examples (the "simplest-example" and a "webphone"). I’m going to write a simple (but for sure the first one in the world ;) SIP over websockets server scanner. It should send a valid SIP (over websockets) petition, parse the interesting info from the response ( i.e. "User-Agent") and print it. I’m using the simplest example as basis, here there are the description of the changes I made on the code:
- In this case no HTML video tags are provided to the constructor. The reason is that we are only using websocket features of the stack, not WebRTC ones.
- Some stuff deleted from the interface in order to ask only for needed parameters (ip address, port and optionally the extension used to made the registration).
- Media parts were also deleted from script.coffee file, which defines the logic of the app.
- Obviously we need to change this logic so I added some code at the end. In this case we are saying that when states 2 (Registering after challenge) or 3 (Registered) are reached, received message is going to be parsed.
- Then strings "User-Agent", "Server" and "Organization" are parsed from this response and printed. Really we are getting it from an object with the property "frame".
- Finally, makefile is modified in order to generate the output with the correct name.

# Copyright (C) Quobis
# Project site: https://github.com/Quobis/QoffeeSIP
# Licensed under GNU-LGPL-3.0-or-later (http://www.gnu.org/licenses/lgpl-3.0.html)

# On document ready...
$ ->
    # Avoid page "reloading" on submit.
    $("form").submit (e) ->

    # Declaration of api.
    api = null

    $("#init").submit =>
        options =
            server: {ip: $("#server-ip").val(), port: $("#server-port").val()}
            onopen: =>
                api.register "qoffeesip", "anonymous"
        api = new API options
        api.on "new-state", (state, message) ->
            switch state
                when 2,3
                    userAgentRE =  /User-Agent:(.*)/i
                    serverRE =  /Server:(.*)/i
                    organizationRE =  /Organization:(.*)/i

                    matchUa = userAgentRE.exec message.frame
                    matchServer = serverRE.exec message.frame
                    matchOrganization = organizationRE.exec message.frame

                    output = matchUa or matchServer or matchOrganization

//- @source: https://github.com/Quobis/QoffeeSIP
//- Copyright (C) Quobis
//- Licensed under GNU-LGPL-3.0-or-later (http://www.gnu.org/licenses/lgpl-3.0.html)

    title SIP over websockets scanner

        input(id="server-ip", type="text", placeholder="Server IP", required)
        input(id="server-port", type="number", placeholder="Port", required)
        input(type="submit", value="Scan")


I have committed this example to QoffeeSIP examples of use, so you can download and use it as explained is QuickStart guide of the project. The command "make build" (or simply "make") is going to put the output files in "dist" folder. Then you only have to move them to an HTTP server, like Apache. You could follow next steps:

- Confirm you have installed coffeeScript and Jade in your system, if not you can use npm to install them ("coffee-script" and "jade").

- Download the examples using git.
git clone https://github.com/Quobis/QoffeeSIP.git
cd qoffeesip/examples/sipwebsockets-scanner

- Generate the files to distribute it.


- Copy them to your Apache server:

sudo cp -R dist/* /var/www

Here there are a few shoots:
Scanner setup
Scanning IdentityCall server

Scanning Kamailio
In a real tool, for best results, we should make some improvements like these:
- Use OPTIONS packets because of being more accurate for this target.

- Add support to ranges of ip addresses.
- Avoid asking for approval to use webcam and/or micro. Really it is not used but it’s a limitation of the stack. We decided to do this request during registering instead of during a call because of usability issues.
- Use Bootstrap to get a more friendly interface.

But this is only a proof of concept so I think it is good enough for now. The target of this post is to show a different way of playing with the stack. Anyway I’m going to add support for websockets to my SIP Metasploit modules in any moment if you are interested in more professional tools.
In the same way, if you were interested in a more complex application you can visit the online demo which implements "webphone" example of use. So you can play with it too, if you need help you can always open an issue on Github repository.

QoffeeSIP demo