Skip to content

Instantly share code, notes, and snippets.

@dweekly
Created August 16, 2020 03:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dweekly/77dc65d5d7c2917b2e0a35258183c871 to your computer and use it in GitHub Desktop.
Save dweekly/77dc65d5d7c2917b2e0a35258183c871 to your computer and use it in GitHub Desktop.
ftpcheck scans hosts and networks for FTP and anonymous FTP archives.
#!/usr/bin/perl
########################################################
# ftpcheck v0.31 [November 2, 1998]
# http://david.weekly.org/code
#
# by David Weekly <dew@cs.stanford.edu>
#
# Thanks to Shane Kerr for cleaning up the process code!
#
# This code is under the GPL. Use it freely. Enjoy.
# Debug. Enhance. Email me the patches!
########################################################
use Socket;
use Net::FTP;
# timeouts in seconds for creating a socket and connecting
my $MAX_SOCKET_TIME = 2;
my $MAX_CONNECT_TIME = 3;
my $HELP=qq{Usage: ftpcheck [-h | --help] [-p processes] [-d | --debug] host};
my @hosts;
# how many simultaneous processes are we allowed to use?
my $MAX_PROCESSES=10;
my $DEBUG=0;
while($_=shift){
if(/^--(.*)/){
$_=$1;
if(/help/){
print $HELP;
exit(0);
}
if(/debug/){
$DEBUG=1;
}
}
elsif(/^-(.*)/){
$_=$1;
if(/^h/ or /^\?/){
print $HELP;
exit(0);
}
if(/^p/){
$MAX_PROCESSES=shift;
}
if(/^d/){
$DEBUG=1;
}
}else{
push @hosts,$_;
}
}
if(!$hosts[0]){
print $HELP;
exit(-1);
}
my $host;
$|=1;
print "ftpcheck v0.31 by dave weekly <dew\@cs.stanford.edu>\n\n";
# go through all of the hosts, replacing subnets with all contained IPs.
for $host (@hosts){
$_=shift(@hosts);
# scan a class C
if(/^([^.]+)\.([^.]+)\.([^.]+)$/){
my $i;
print "Expanding class C $_\n" if($DEBUG);
for($i=1;$i<255;$i++){
my $thost="$_.$i";
push @hosts,$thost;
}
}
else{
push @hosts,$_;
}
}
my @pids;
my $npids=0;
for $host (@hosts){
my $pid;
$pid=fork();
if($pid>0){
$npids++;
if($npids>=$MAX_PROCESSES){
for(1..($MAX_PROCESSES)){
$wait_ret=wait();
if($wait_ret>0){
$npids--;
}
}
}
next;
}elsif(undef $pid){
print "fork error\n" if ($DEBUG);
exit(0);
}else{
my($proto,$port,$sin,$ip);
print "Trying $host\n" if ($DEBUG);
$0="(checking $host)";
# kill thread on timeout
local $SIG{'ALRM'} = sub { exit(0); };
alarm $MAX_SOCKET_TIME;
$proto=getprotobyname('tcp');
$port=21;
$ip=inet_aton($host);
if(!$ip){
print "couldn't find host $host\n" if($DEBUG);
exit(0);
}
$sin=sockaddr_in($port,$ip);
socket(Sock, PF_INET, SOCK_STREAM, $proto);
alarm $MAX_CONNECT_TIME;
if(!connect(Sock,$sin)){
exit(0);
}
my $iaddr=(unpack_sockaddr_in(getpeername(Sock)))[1];
close(Sock);
# SOMETHING is listening on the FTP port...really ftp server?
print "listen $host!\n" if($DEBUG);
alarm 0;
$hostname=gethostbyaddr($iaddr,AF_INET);
# create new FTP connection w/5 second timeout
$ftp = Net::FTP->new($host, Timeout => 5);
if(!$ftp){
print " <$host ($hostname) denied you>\n" if($DEBUG);
exit(0);
}
if(!$ftp->login("anonymous","just\@checking.com")){
print " FTP on $host [$hostname]\n";
exit(0);
}
print "Anon FTP on $host [$hostname]\n";
$ftp->quit;
exit(0);
}
}
print "done spawning, $npids children remain\n" if($DEBUG);
# wait for my children
for(1..$npids){
my $wt=wait();
if($wt==-1){
print "hey $!\n" if($DEBUG);
redo;
}
}
print "Done\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment