#!/usr/bin/perl use Socket; $SIG{ALRM}=sub { $connection=0; close(CON); }; $trick_master= "\x20\x00\x01\x30\x02\xFD\xA8\xE3" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00\x00\x00" ; $get_pa= "\x2a\x00\x01\x32\x02\xfd" . "\xa8\xe3\x00\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00" . "\x00\x00\x00\x00\x21\x00" . "\x02\x00\x00\x00\x00\x00" . "\x00\x00\x00\x00\x00\x00" ; $|=1; print "\nCitrix Published Application Scanner version 2.0\ By Ian Vitek, ian.vitek\@ixsecurity.com\n"; die "\nUsage: $0 {IP | file | - | random } [timeout]\ \tIP\tIP to test\ \tfile\tRead IPs from file\ \t-\tRead IPs from standard input\ \trandom\tRead IPs from /dev/urandom\ \ttimeout\tTimeout\ \n" if(!$ARGV[0]); $input=$ARGV[0]; $timeout=$ARGV[1]; $timeout=1 if(!$timeout); if($input eq "-" || -r $input) { open(INPUTFD,"$input") or die "Cant open file $input: $!\n"; $newHost=2; } elsif ($input eq "random") { open(RANDOM,"/dev/urandom") or die "Cant open /dev/urandom: $!\n"; binmode(RANDOM); $newHost=3; } else { $newHost=1; } $loop=1; while($loop==1) { undef $target; if($newHost==2) { $target= or exit; chomp $target; $target=~s/\s*(\S+)/$1/; redo if(!$target); } elsif ($newHost==1) { $loop=0; $target=$input; } elsif ($newHost==3) { undef @ch; $i=0; while($i<4) { while($ch[$i] < 1 || $ch[$i] > 254) { $ch[$i]=ord getc(RANDOM); } $i++; } $target=sprintf("%d.%d.%d.%d",$ch[0],$ch[1],$ch[2],$ch[3]); } else { die "Nothing to do? Check input!\n\n"; } # # Get Master Browser # $server=inet_aton($target) or die "Is \"${target}\" a target?\n\n"; $retry=0; $connection=0; while($retry++<2 and $connection==0) { $connection=1; socket(CON, PF_INET, SOCK_DGRAM, getprotobyname('udp')); send(CON, $trick_master, 0, sockaddr_in(1604, $server)); alarm $timeout; $from_CON=recv(CON,$data,1500,0); alarm 0; } close(CON); if($connection==0) { print "$target not responding\n"; next; } undef $master_raw; undef $master; ($master_raw)=$data=~/.+\x02\x00\x06\x44(....)/s; if($master_raw) { $master=sprintf("%d.%d.%d.%d",ord substr($master_raw,0,1),ord substr($master_raw,1,1),ord substr($master_raw,2,1),ord substr($master_raw,3,1)); } else { $master="ERROR"; } print "$target|$master"; if($target eq $master) { print "|1|"; } else { print "|0|"; } # # Enumerate PA # $retry=0; $connection=0; while($retry++<2 and $connection==0) { $connection=1; socket(CON, PF_INET, SOCK_DGRAM, getprotobyname('udp')); send(CON, $get_pa, 0, sockaddr_in(1604, $server)); alarm $timeout; undef $data; $from_CON=recv(CON,$data,1500,0); alarm 0; } if($connection==0) { print "Connection lost\n"; next; } undef $pa; $pa=substr($data,40); chop $pa; $pa=~s/\x00/\;/sg; print "$pa"; # # More packets? # $last_packet=ord substr($data,30,1); while($last_packet==0) { $connection=1; alarm $timeout*2; undef $data; $from_CON=recv(CON,$data,1500,0); alarm 0; if($connection==0) { print ",ERROR"; last; } undef $pa; $pa=substr($data,39); chop $pa; $pa=~s/\x00/\;/sg; print "$pa"; $last_packet=ord substr($data,30,1); } close(CON); print "\n"; }