24 Jun 2013

OVHACK - VoIP Challenges Write-up

During "La Nuit du Hack" last week end in Paris, OVH released a set of challenges . Three of them were VoIP-related. I thought it was interesting to give it a try. The first challenge comes with a cap file and the following information:
A quick look at the cap file shows that it only contains signalisation protocol (in this case, SIP):
$ capinfos VOIP1_ndh_easy.cap 
File name:           VOIP1_ndh_easy.cap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Ethernet
Packet size limit:   file hdr: 65535 bytes
Number of packets:   35
File size:           24896 bytes
Data size:           24312 bytes
Capture duration:    5 seconds
Start time:          Fri Jun 21 14:38:30 2013
End time:            Fri Jun 21 14:38:35 2013
Data byte rate:      4617.01 bytes/sec
Data bit rate:       36936.10 bits/sec
Average packet size: 694.63 bytes
Average packet rate: 6.65 packets/sec
SHA1:                8b5622e767e008fa6b648bc071aa19d0b7c40b48
RIPEMD160:           42630586727b8d01d57584d338623c60ac382aea
MD5:                 13c54fb7e70546c53632d4a9ef96deab
Strict time order:   True

$ tshark -qnr VOIP1_ndh_easy.cap -z io,phs 

===================================================================
Protocol Hierarchy Statistics
Filter: 

eth                                      frames:35 bytes:24312
  ip                                     frames:35 bytes:24312
    udp                                  frames:35 bytes:24312
      sip                                frames:35 bytes:24312
===================================================================

A closer look at the cap shows some failed authentication attempts:
$ tshark -nr VOIP1_ndh_easy.cap sip.auth
  1   0.000000 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
  2   0.000021 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
  4   0.000312 178.33.242.242 -> 37.160.7.151 SIP 645 Status: 401 Unauthorized    (0 bindings)
  6   0.110184 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
 11   0.280350 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 12   0.356216 37.160.7.151 -> 178.33.242.242 SIP 904 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
 17   5.073604 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
 19   5.073858 178.33.242.242 -> 37.160.7.151 SIP 645 Status: 401 Unauthorized    (0 bindings)
 22   5.089776 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 23   5.155821 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
 27   5.165829 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 28   5.187878 37.160.7.151 -> 178.33.242.242 SIP 901 Request: REGISTER sip:178.33.242.242:5060;transport=UDP
 31   5.199716 37.160.7.151 -> 178.33.242.242 SIP 904 Request: REGISTER sip:178.33.242.242:5060;transport=UDP

Last attempt seems to contain the correct password, as there is no 401 Unauthorized message.
By googling around, you can find this nice post on VoIP hacking, that mentions sipcrack usage (sipcrack is packaged in Debian).

We create a dump file from the cap file with the following command:
$ sipdump -p VOIP1_ndh_easy.cap VOIP1_ndh_easy.dmp

First, we use the excellent rockyou.txt dictionnary, with sipcrack. We try to crack the 8th password, as it seems to be correct. Unfortunately, no password is found:
$ sipcrack -w rockyou.txt VOIP1_ndh_easy.dmp 

SIPcrack 0.2  ( MaJoMu | www.codito.de ) 
----------------------------------------

* Found Accounts:

Num     Server          Client          User    Hash|Password

1       37.160.7.151    178.33.242.242  jerome  5d0b5b10ba93bb4df788ee995fd16361
2       37.160.7.151    178.33.242.242  jerome  5d0b5b10ba93bb4df788ee995fd16361
3       37.160.7.151    178.33.242.242  jerome  8c8b9699a1ceac60e2341727af25ba49
4       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
5       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
6       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
7       37.160.7.151    178.33.242.242  jerome  70c61b8ebe6e146281e7f9efa66668e1
8       37.160.7.151    178.33.242.242  jerome  4919f5bce37c6565296979a6750af219

* Select which entry to crack (1 - 8): 8

* Generating static MD5 hash... 808e24f456745cb56d8f7f4b67579c61
* Loaded wordlist: 'rockyou.txt'
* Starting bruteforce against user 'jerome' (MD5: '4919f5bce37c6565296979a6750af219')
* Tried 14352510 passwords in 11 seconds

* Tried all passwords, no match

The text above mentionned that the password length is 6 characters and that it only contains lower-case letters.
John the ripper can generate this, but it'll take ages, and use a lot of disk space. Thanks to Sn0rkY advise, we can use a fifo! to dynamically pass passwords generated by John to sipcrack. In one terminal, sipcrack is reading from the fifo:
$ mkfifo fifo && sipcrack -w fifo VOIP1_ndh_easy.dmp

SIPcrack 0.2  ( MaJoMu | www.codito.de ) 
----------------------------------------

* Found Accounts:

Num     Server          Client          User    Hash|Password

1       37.160.7.151    178.33.242.242  jerome  5d0b5b10ba93bb4df788ee995fd16361
2       37.160.7.151    178.33.242.242  jerome  5d0b5b10ba93bb4df788ee995fd16361
3       37.160.7.151    178.33.242.242  jerome  8c8b9699a1ceac60e2341727af25ba49
4       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
5       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
6       37.160.7.151    178.33.242.242  jerome  415c2bc5d47e8d9689e6ec78792920f6
7       37.160.7.151    178.33.242.242  jerome  70c61b8ebe6e146281e7f9efa66668e1
8       37.160.7.151    178.33.242.242  jerome  4919f5bce37c6565296979a6750af219

* Select which entry to crack (1 - 8): 8

* Generating static MD5 hash... 808e24f456745cb56d8f7f4b67579c61

... whilst in another terminal, John is generating the dictionary and outputs to the fifo:
$ john -i:alpha -stdout=6 > fifo

After few seconds:
* Loaded wordlist: 'fifo'
* Starting bruteforce against user 'jerome' (MD5: '4919f5bce37c6565296979a6750af219')
* Tried 37540823 passwords in 29 seconds

* Found password: 'sipcrk'
* Updating dump file 'VOIP1_ndh_easy.dmp'... done
Bazinga!



The second challenge is similar to the first one:

$ capinfos VOIP2_ndh_auth.cap 
File name:           VOIP2_ndh_auth.cap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Ethernet
Packet size limit:   file hdr: 847 bytes
Packet size limit:   inferred: 847 bytes
Number of packets:   52
File size:           36078 bytes
Data size:           35825 bytes
Capture duration:    6 seconds
Start time:          Fri Jun 21 14:45:56 2013
End time:            Fri Jun 21 14:46:02 2013
Data byte rate:      6406.65 bytes/sec
Data bit rate:       51253.21 bits/sec
Average packet size: 688.94 bytes
Average packet rate: 9.30 packets/sec
SHA1:                b3b5851632ad9cbeba308fb9607ca0c65bd145db
RIPEMD160:           a4a28e4b9ffbff93c4f4cb8fe97e62e16c23eeb3
MD5:                 9ab6584a82464dc309871616550bae7e
Strict time order:   True
$ tshark -qnr VOIP2_ndh_auth.cap -z io,phs

===================================================================
Protocol Hierarchy Statistics
Filter: 

eth                                      frames:52 bytes:35825
  ip                                     frames:52 bytes:35825
    udp                                  frames:52 bytes:35825
      sip                                frames:52 bytes:35825
        short                            frames:11 bytes:9920
===================================================================

$ tshark -nr VOIP2_ndh_auth.cap sip.auth
  4   0.000330 178.33.242.242 -> 37.160.7.151 SIP 645 Status: 401 Unauthorized    (0 bindings)
  6   0.000514 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 17   0.532170 178.33.242.242 -> 37.160.7.151 SIP 645 Status: 401 Unauthorized    (0 bindings)
 20   0.550135 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 31   3.784278 178.33.242.242 -> 37.160.7.151 SIP 645 Status: 401 Unauthorized    (0 bindings)
 34   3.804119 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 39   5.451961 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)
 44   5.496272 178.33.242.242 -> 37.160.7.151 SIP 633 Status: 401 Unauthorized    (0 bindings)

We use the same technique we used for the first challenge:
$ sipdump -p VOIP2_ndh_auth.cap VOIP2_ndh_auth.dmp

SIPdump 0.2  ( MaJoMu | www.codito.de ) 
---------------------------------------

* Using pcap file 'VOIP2_ndh_auth.cap' for sniffing
* Starting to sniff with packet filter 'tcp or udp'

* Dumped login from 178.33.242.242 -> 37.160.7.151 (User: 'jerome')

* Exiting, sniffed 1 logins

For some reason, we may have to run this command several times, as it does not always find any login:
$ sipdump -p VOIP2_ndh_auth.cap VOIP2_ndh_auth.dmp

SIPdump 0.2  ( MaJoMu | www.codito.de ) 
---------------------------------------

* Using pcap file 'VOIP2_ndh_auth.cap' for sniffing
* Starting to sniff with packet filter 'tcp or udp'


* Exiting, sniffed 0 logins

When trying to break it:
$ mkfifo fifo && sipcrack -w fifo VOIP2_ndh_auth.dmp 

SIPcrack 0.2  ( MaJoMu | www.codito.de ) 
----------------------------------------

* Found Accounts:

Num     Server          Client          User    Hash|Password

1       37.160.7.151    178.33.242.242  jerome  cd5a6d788761e167b5fee5ad9c0ea328

* Select which entry to crack (1 - 1): 1

* Cannot crack 'MDREGIS' hash, only MD5 supported so far...

There is this weird MDREGIS in VOIP2_ndh_auth.dmp:
37.160.7.151"178.33.242.242"jerome"asterisk"REGISTER"sip:178.33.242.242:5060;transport=UDP"4fd59b13""""MDREGIS"cd5a6d788761e167b5fee5ad9c0ea328

Let's replace with MD5, and run sipcrack again:
$ sed -i.orig 's/MDREGIS/MD5/g' VOIP2_ndh_auth.dmp
$ sipcrack -w fifo VOIP2_ndh_auth.dmp 

SIPcrack 0.2  ( MaJoMu | www.codito.de ) 
----------------------------------------

* Found Accounts:

Num     Server          Client          User    Hash|Password

1       37.160.7.151    178.33.242.242  jerome  cd5a6d788761e167b5fee5ad9c0ea328

* Select which entry to crack (1 - 1): 1

* Generating static MD5 hash... 808e24f456745cb56d8f7f4b67579c61
* Loaded wordlist: 'fifo'
* Starting bruteforce against user 'jerome' (MD5: 'cd5a6d788761e167b5fee5ad9c0ea328')
* Tried 38480203 passwords in 28 seconds

* Found password: 'goodjb'
* Updating dump file 'VOIP2_ndh_auth.dmp'... done
BOOOM!



The third challenge is pure fun! We have to find out the account number and pin code that a guy typed on his phone :)

Capture lasts longer than the previous ones (108 seconds):
$ capinfos VOIP3_voip_call.cap 
File name:           VOIP3_voip_call.cap
File type:           Wireshark/tcpdump/... - libpcap
File encapsulation:  Ethernet
Packet size limit:   file hdr: 65535 bytes
Number of packets:   5910
File size:           1356338 bytes
Data size:           1261754 bytes
Capture duration:    108 seconds
Start time:          Thu Jun 20 17:16:31 2013
End time:            Thu Jun 20 17:18:18 2013
Data byte rate:      11688.83 bytes/sec
Data bit rate:       93510.66 bits/sec
Average packet size: 213.49 bytes
Average packet rate: 54.75 packets/sec
SHA1:                28bd8ddbf816f4a163208446749c0e31bfe12408
RIPEMD160:           5a0239f9851bebfa380851901740231d11f7f7e7
MD5:                 457789940df97729c7ad553d7cc59142
Strict time order:   True

This time, there is media traffic (rtp):
$ tshark -qnr VOIP3_voip_call.cap -z io,phs

===================================================================
Protocol Hierarchy Statistics
Filter: 

eth                                      frames:5910 bytes:1261754
  ip                                     frames:5910 bytes:1261754
    udp                                  frames:5910 bytes:1261754
      sip                                frames:20 bytes:13614
      rtp                                frames:5890 bytes:1248140
        rtpevent                         frames:80 bytes:4800
===================================================================

Wireshark allows us to decode captured RTP data into audio format. By clicking on Telephony->RTP->Show all streams, we can find 4 streams:

By clicking "Find reverse", we can find the full conversation, and listen to it:

In this first conversation, it does not seem that user type his password:

We select the second conversation, and listen to it:

This time, we can ear the user dialing his code:

Let's extract this conversation in .au format.

$ file voip3.au
voip3.au: Sun/NeXT audio data: 16-bit linear PCM, mono, 8000 Hz

We can use Audacity to explore this file:

On analog phones, pressing a single key will send a tone containing two frequencies. On a touch pad, every column and every row emits its own frequency, as described in this Wikipedia entry:

By selecting every dial and performing a spectrum analysis, we can find out the keys that the user pressed :) On Audacity, highlight one dial and select Analyse->Plot Spectrum. You may need to reduce the sample size to 512 to get a display, and select Spectrum Algorithm and Rectangular window function:

By repeating this process for each key, we collect the user account number and pin code :)
6842276257:1952