# 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
# --------------------------------------------------------
# STEP TO RESPECT TO BE COMPLETE
#
# OK/NOK- Present script test and completed (include explanation)
# OK- Launcher tool/exploit menu modified
# OK- Launcher editor menu modified
# OK/NOK- Documentation uadated
#
# --------------------------------------------------------


use Tk; # http://search.cpan.org/~srezic/Tk/pod/UserGuide.pod
use Tk::Radiobutton;
use Tk::PNG;
use Tk::Photo;
use Tk::JPEG;
use Tk::NoteBook;
use Tk::ProgressBar;
use LWP::UserAgent;
use HTTP::Request;
use Net::Ping; # http://search.cpan.org/~smpeters/Net-Ping-2.36/lib/Net/Ping.pm
use Net::Netmask; # http://search.cpan.org/dist/Net-Netmask/
use Net::Subnets;
use IO::Socket::INET;
use IO::Select;

# Declaring functions for network analyzing stuff. Thus no argument passing for function. Its all full available variable.
$p=Net::Ping->new("icmp");

# Variable
my $ScanType = "single";
my $IpAddress = "";
my $IpAddress_single = "";
my $IpAddress_sub = "";
my $SubnetToScan = "";
my $Results = "";
my @TypeTable = ("5212","5215","5220","5312","5320","5324","5330", "5340");
my $CallerID_g = "";
my $UserID_g = "";
my $UserPassword_g = "";
my $ProxyServer_g = "";
my $RegistrarServer_g = "";

my @colors = (  0, '#ff002a',  1, '#ff0014',  2, '#ff000a',  3, '#ff0500',  4, '#ff1000',
	     5, '#ff1b00',  6, '#ff3000',  7, '#ff3b00',  8, '#ff4600',  9, '#ff5100',
	    10, '#ff6100', 11, '#ff7600', 12, '#ff8100', 13, '#ff8c00', 14, '#ff9700',
	    15, '#ffa100', 16, '#ffbc00', 17, '#ffc700', 18, '#ffd200', 19, '#ffdd00',
	    20, '#ffe700', 21, '#fffd00', 22, '#f0ff00', 23, '#e5ff00', 24, '#dbff00',
	    25, '#d0ff00', 26, '#baff00', 27, '#afff00', 28, '#9fff00', 29, '#95ff00',
	    30, '#8aff00', 31, '#74ff00', 32, '#6aff00', 33, '#5fff00', 34, '#54ff00',
	    35, '#44ff00', 36, '#2eff00', 37, '#24ff00', 38, '#19ff00', 39, '#0eff00',
	    40, '#03ff00', 41, '#00ff17', 42, '#00ff21', 43, '#00ff2c', 44, '#00ff37',
	    45, '#00ff42', 46, '#00ff57', 47, '#00ff67', 48, '#00ff72', 49, '#00ff7d',
	    50, '#00ff87', 51, '#00ff9d', 52, '#00ffa8', 53, '#00ffb8', 54, '#00ffc3',
	    55, '#00ffcd', 56, '#00ffe3', 57, '#00ffee', 58, '#00fff8', 59, '#00faff',
	    60, '#00eaff', 61, '#00d4ff', 62, '#00c9ff', 63, '#00bfff', 64, '#00b4ff',
	    65, '#00a9ff', 66, '#008eff', 67, '#0083ff', 68, '#0079ff', 69, '#006eff',
	    70, '#0063ff', 71, '#004eff', 72, '#003eff', 73, '#0033ff', 74, '#0028ff',
	    75, '#001dff', 76, '#0008ff', 77, '#0200ff', 78, '#1200ff', 79, '#1d00ff',
	    80, '#2800ff', 81, '#3d00ff', 82, '#4800ff', 83, '#5300ff', 84, '#5d00ff',
	    85, '#6e00ff', 86, '#8300ff', 87, '#8e00ff', 88, '#9900ff', 89, '#a300ff',
	    90, '#ae00ff', 91, '#c900ff', 92, '#d400ff', 93, '#df00ff', 94, '#e900ff',
	    95, '#f400ff', 96, '#ff00f3', 97, '#ff00e3', 98, '#ff00d9', 99, '#ff00ce' );

	
my $subweb_mw = MainWindow->new(
						-title => 'VxWorks active debug mode detection');

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=>"Vulnerability details",
			-command => sub {&EXPLANATION}
			);		
$file_mb->command(
		-label=>'Launch tool',
		-command => 
			sub {&LAUNCH}
		);

$file_mb->command(
			-label=>"Save scan results",
			-command => sub {&SAVERESULTS}
			);
			
$file_mb->command(
	-label=>'Exit',
	-command => [$subweb_mw => 'destroy']
	);
		#------------- Button menu --------------
my $FrameButton = $subweb_mw -> Frame ();

my $ImageDetail = $FrameButton->Photo( 
									-format => 'jpeg',
									-file => "./Image/IMG_oeil.jpg",
									 );									 
my $ImageLaunch = $FrameButton->Photo( 
									-format => 'jpeg',
									-file => "./Image/IMG_launch.jpg",
									 );									 
my $ImageSave = $FrameButton->Photo( 
									-format => 'jpeg',
									-file => "./Image/IMG_save.jpg",
									 );		
my $ImageExit = $FrameButton->Photo( 
									-format => 'jpeg',
									-file => "./Image/IMG_exit.jpg",
									 );	
									 									 									 
my $ButtonDetail = $FrameButton->Button (
    								-image => $ImageDetail, 
								    -command => sub {&EXPLANATION}
									)->pack(-side => 'left');
my $ButtonLaunch = $FrameButton->Button (
    								-image => $ImageLaunch, 
								    -command => sub {&LAUNCH}
									)->pack(-side => 'left');
my $ButtonSave = $FrameButton->Button (
    								-image => $ImageSave, 
								    -command => sub {&SAVERESULTS}
									)->pack(-side => 'left');
my $ButtonExit = $FrameButton->Button (
    								-image => $ImageExit, 
								    -command => [$subweb_mw => 'destroy']
									)->pack(-side => 'right');									
																		
$FrameButton -> pack (-side => 'top', -anchor => 'w'); 	

#---------- LABEL FRAME CONFIGURE -------------------------------------
my $labeled_frame = $subweb_mw ->LabFrame(
										-label => "Configure",
                                   		-labelside => "acrosstop"
                                   		)->pack(-side => 'top', -anchor => 'w');

#----------
my $FrameTOP = $labeled_frame -> Frame ();
my $rdb_scan = $FrameTOP  -> Radiobutton(-text=>"IP Subnet to test",
												-value=>"scan",
												-variable=>\$ScanType);
$rdb_scan -> pack (-side => 'left');
$FrameTOP -> pack (-side => 'top', -anchor => 'w');
#----------	
my $FrameMIDDLE1 = $labeled_frame -> Frame ();

$FrameMIDDLE1->Label(
	-text => 'Subnet (192.168.1.0/24):            '
	)->pack(-side => 'left');
my $TextLabel = $FrameMIDDLE1 -> Entry(
	-textvariable => \$SubnetToScan,
	- width => 54,
	)->pack(-side => 'left');
$FrameMIDDLE1 -> pack (-side => 'top', -anchor => 'w');

#----------	
my $FrameMIDDLE2 = $labeled_frame -> Frame ();
my $rdb_single = $FrameMIDDLE2 -> Radiobutton(-text=>"Single device to test",  
												-value=>"single",  
												-variable=>\$ScanType);
$rdb_single -> pack (-side => 'left');
$FrameMIDDLE2 -> pack (-side => 'top', -anchor => 'w');
#----------	
my $FrameMIDDLE3 = $labeled_frame -> Frame ();
$FrameMIDDLE3->Label(
	-text => 'Device IP Address (192.168.1.1):'
	)->pack(-side => 'left');
my $TextLabel_single = $FrameMIDDLE3 -> Entry(
	-textvariable => \$IpAddress_single,
	- width => 54,
	)->pack(-side => 'left');
$FrameMIDDLE3 -> pack (-side => 'top', -anchor => 'w');


#-------------PROGRESS BAR ----------------------------

$bar1 = $subweb_mw->ProgressBar( -borderwidth=>2, -blocks=>100, -gap=>0,
			  -troughcolor=>'white',-colors=>\@colors,
			  -length=>106 )->pack( -padx=>5, -pady=>5, -fill=>'x' );
#$bar1->value( 100 - $val );


#------------- TAB BOOK -------------------------------

my $FrameTab= $subweb_mw -> Frame (-width => 40, -height => 20);
my $book = $FrameTab->NoteBook()->pack( -fill=>'both', -expand=>1 );

$tab1 = $book->add( "Sheet 1", -label=>"Details");
$tab2 = $book->add( "Sheet 2", -label=>"Positive results" );
$tab3 = $book->add( "Sheet 3", -label=>"All logs");
$book->raise("Sheet 1");

my $TextWidget_tab1 = $tab1->Text(); 
$TextWidget_tab1 ->configure(-height => 28);
my $scrollbar_tab1 = $tab1 ->Scrollbar(-command => ['yview', $TextWidget_tab1 ]);
$TextWidget_tab1 ->configure(-yscrollcommand => ['set', $scrollbar_tab1]);

my $TextWidget_tab2 = $tab2->Text(); 
$TextWidget_tab2 ->configure(-height => 28);
my $scrollbar_tab2 = $tab2 ->Scrollbar(-command => ['yview', $TextWidget_tab2 ]);
$TextWidget_tab2 ->configure(-yscrollcommand => ['set', $scrollbar_tab2]);

my $TextWidget_tab3 = $tab3->Text(); 
$TextWidget_tab3 ->configure(-height => 28);
my $scrollbar_tab3 = $tab3 ->Scrollbar(-command => ['yview', $TextWidget_tab3 ]);
$TextWidget_tab3 ->configure(-yscrollcommand => ['set', $scrollbar_tab3]);


$TextWidget_tab1 ->pack(-side => 'left', -fill => 'both', -expand => 1);
$TextWidget_tab2 ->pack(-side => 'left', -fill => 'both', -expand => 1);
$TextWidget_tab3 ->pack(-side => 'left', -fill => 'both', -expand => 1);

$scrollbar_tab1->pack(-side => 'right', -fill => 'y');
$scrollbar_tab2->pack(-side => 'right', -fill => 'y');
$scrollbar_tab3->pack(-side => 'right', -fill => 'y');

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

#-------------


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

sub LAUNCH
{
	# variable initialization
	$Results = "";
	$TextWidget_tab3 -> delete('0.0', 'end');
	$TextWidget_tab2 -> delete('0.0', 'end');
	$bar1->value(0);
	$book->raise("Sheet 3");

	if ($ScanType =~ /single/)
	{
		&SINGLE;	
	}
	elsif ($ScanType =~ /scan/)
	{
		&EXPLOITSUBNET;
	}
}

sub EXPLOITSUBNET
{
	# Subnet testing

	if ($SubnetToScan =~ /[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\/[0-9]{1,2}/)
	{		
		$IpAddress_sub = $SubnetToScan;	

		&TESTDEFAULT;
	}
	else
	{
		$subweb_mw->Dialog(-title => 'WARNING', 	
						-text => 'Bad IP Subnet syntax !',
					)->Show( );
   	}
}


sub SINGLE
{
	# Subnet testing
	
	if ($IpAddress_single =~ /[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/)
	{
		$IpAddress_sub=$IpAddress_single."/32";
		
		&TESTDEFAULT;
	}
	else
	{
		$subweb_mw->Dialog(-title => 'WARNING', 	
						-text => 'Bad IP Subnet syntax !',
					)->Show( );
   	}
}


sub SAVERESULTS
{
	my $FileToSave = $subweb_mw->getSaveFile(
							-defaultextension => '.txt',
                            -initialdir => "user_data"
                              );

	open (TOSAVE, ">>$FileToSave");
	print TOSAVE $Results;
	close (TOSAVE);
	
}	


sub TESTDEFAULT
{
	# Subnet calculation and detail stuff
	my $sn = Net::Subnets->new;
   	my ( $lowipref, $highipref ) = $sn->range( \$IpAddress_sub );
    my $lowIP = $$lowipref;
	my $highIP = $$highipref;
	my $listref = $sn->list( \( $lowIP, $highIP ) );# Creating a table with all the IP Address.

	# Progres bar stuff		
	my $counter_global = 0;#Used for progress bar measure
	my $counter_temp = 0;#Used for progress bar status
	my $percentage = 0;#Used for progress bar status
				
	# Calcultaion of the number of case to properly set the progress bar.
	foreach my $scan_count ( @{ $listref } ) 
	{
		$counter_global++;	
	}
		
		
	#----------------------------------------------------------------------
	# LAUNCHING OF THE EXPLOIT/TOOL. GUI HANDLING 
	#----------------------------------------------------------------------				
	$TextWidget_tab3 -> insert ("end", "-------------------------------------------------------------------------------\n");			
    $TextWidget_tab3 -> insert ("end","Launching VxWorks active debug mode detection\n");
	$TextWidget_tab3 -> insert ("end", "-------------------------------------------------------------------------------\n");		
	$TextWidget_tab3  -> update ();	
	$TextWidget_tab3  -> see ('end');

	$TextWidget_tab2 -> insert ("end", "-------------------------------------------------------------------------------\n");			
    $TextWidget_tab2 -> insert ("end","Launching VxWorks active debug mode detection\n");
	$TextWidget_tab2 -> insert ("end", "-------------------------------------------------------------------------------\n");		
	$TextWidget_tab2  -> update ();	
	$TextWidget_tab2  -> see ('end');
		
	$Results = $Results."-------------------------------------------------------------------------------\n";	
	$Results = $Results."Launching VxWorks active debug mode detection\n";	
	$Results = $Results."-------------------------------------------------------------------------------\n";	
		
	# END -----------------------------------------------------------------
		
		
						
	foreach my $scan_address ( @{ $listref } ) 
	{
		# Initialization.
		$IpAddress = $scan_address;	
			
		#$counter_temp is used for progress bar.	
		$counter_temp++;

		#----------------------------------------------------------------------
		# INCLUDE CODE TO GET DATA TO ANALYZE 
		#----------------------------------------------------------------------
			
	    $TextWidget_tab3 -> insert ("end","$IpAddress: Trying to connect\n");
	    $TextWidget_tab3  -> update ();	
		$TextWidget_tab3  -> see ('end');
			
		$Results = $Results."$IpAddress: Trying to connect\n";
		
		# Time  to wait for the "destination unreachable" package.
		my $icmp_timeout=4;
			
		# Create the icmp socket for the "destination unreachable" packages  
		$icmp_sock = new IO::Socket::INET(Proto=>"icmp");
		$read_set = new IO::Select();
		$read_set->add($icmp_sock);
			
		# Buffer to send via UDP
		my $buf="hello";

		my $sock = new IO::Socket::INET(
										PeerAddr=>$IpAddress,
										PeerPort=>"17185",
										Proto=>"udp",
										);
		# Send the buffer and close the UDP socket.
	    $sock->send("$buf");
		close($sock);

		# Wait for incoming packets.
	    ($new_readable) = IO::Select->select($read_set, undef, undef, $icmp_timeout);
		# Set the arrival flag.
		$icmp_arrived = 0;
			
		# For every socket we had received packets (In our case only one - icmp_socket)
		foreach $socket (@$new_readable)
		{
           	# If we have captured an icmp packages, Its probably "destination unreachable"
			if ($socket == $icmp_sock)
			{
               	# Set the flag and clean the socket buffers
				$icmp_arrived = 1;
				$icmp_sock->recv($buffer,50,0);
			}
		}
	    if ( $icmp_arrived == 0 )
	    {
		    $TextWidget_tab3 -> insert ("end","$IpAddress: WARNING, VxWorks debug mode may be active.\n");
			$TextWidget_tab3  -> update ();	
			$TextWidget_tab3  -> see ('end');

		    $TextWidget_tab2 -> insert ("end","$IpAddress: WARNING, VxWorks debug mode may be active.\n");
			$TextWidget_tab2  -> update ();	
			$TextWidget_tab2  -> see ('end');
				
			$Results = $Results."$IpAddress: WARNING, VxWorks debug mode may be active.\n";		
	    }
	    else
	    {
		    $TextWidget_tab3 -> insert ("end","$IpAddress: Device not vulnerable.\n");
			$TextWidget_tab3  -> update ();	
			$TextWidget_tab3  -> see ('end');
				
			$Results = $Results."$IpAddress: Device not vulnerable.\n";			    
		}
		    
		# Close the icmp sock
		close($icmp_sock);

		# PROGRESS BAR UPDATE
	   	#----------------------------------------------------------------------
	   	$percentage = int (($counter_temp/$counter_global)*100);
		$bar1->value($percentage);
	}

	#----------------------------------------------------------------------
    #END OF TEST. GUI HANDLING
    #----------------------------------------------------------------------
    $TextWidget_tab3 -> insert ("end","END\n");
	$TextWidget_tab3 -> insert ("end", "-------------------------------------------------------------------------------\n");	
	$TextWidget_tab3  -> update ();	
	$TextWidget_tab3  -> see ('end');

	$TextWidget_tab2 -> insert ("end", "END\n");			
	$TextWidget_tab2 -> insert ("end", "-------------------------------------------------------------------------------\n");		
	$TextWidget_tab2  -> update ();	
	$TextWidget_tab2  -> see ('end');
	
	$Results = $Results."END\n";
	$Results = $Results."-------------------------------------------------------------------------------\n";
}



sub EXPLANATION
{
	$TextWidget_tab1 -> delete('0.0', 'end');
	$TextWidget_tab1 -> insert ("end", "-------------------------------------------------------------------------------\n");
	$TextWidget_tab1 -> insert ("end", "WARNING:\n");
	$TextWidget_tab1 -> insert ("end", "Depending on firewall filtering or network stack configuration, ISME may not received an ICMP network unreachable packet from the tested device (which mean that the UDP port 17185 is closed). This means that the device will be considered as potentialy vulnerable by ISME even if it is the not case. UDP protocol do not permit true exchange like TCP, thus rendering identification difficult.\n\n");
	
	$TextWidget_tab1 -> insert ("end", "VULNERABILITY:\n");
	$TextWidget_tab1 -> insert ("end", "The VxWorks WDB target agent is a target-resident, run-time facility that is required for connecting host tools to a VxWorks target system during development. WDB is a selectable component in the VxWorks configuration and is enabled by default. The WDB debug agent access is not secured and does provide a security hole in a deployed system. It is advisable for production systems to reconfigure VxWorks with only those components needed for deployed operation and to build it as the appropriate type of system image. It is recommended to remove host development components such as the WDB target agent and debugging components (INCLUDE_WDB and INCLUDE_DEBUG) as well as other operating system components that are not required to support customer applications. Consult the VxWorks Kernel Programmer's guide for more information on WDB.Additional information can be found in ICS-CERT advisory ICSA-10-214-01 and on the Metasploit Blog.\n\n");
	$TextWidget_tab1 -> insert ("end", "IMPACT:\n");
	$TextWidget_tab1 -> insert ("end", "An attacker can use the debug service to fully compromise the device.\n\n");			
	$TextWidget_tab1 -> insert ("end", "WORKAROUND\n");
	$TextWidget_tab1 -> insert ("end", "Vendors should remove the WDB target debug agent in their VxWorks based products by removing the INCLUDE_WDB & INCLUDE_DEBUG components from their VxWorks Image. Appropriate firewall rules should be implemented to restrict access to the debug service (17185/udp) to only trusted sources until vendors have released patches to disable it.\n");
	
	$TextWidget_tab1 -> insert ("end", "-------------------------------------------------------------------------------\n");
	$TextWidget_tab1  -> update ();	
	$TextWidget_tab1  -> see ('end'); 
	
	$book->raise("Sheet 1");			
}
