#VERSION,1.00
#LASTMOD,12.17.2002
# Enumeration of users and directories in system 
# (in Apache using ~username)

# This software is distributed under the terms of the GPL, which should have been received
# with a copy of this software in the "LICENSE.txt" file.

# This plugin tries to enumerate all the users and directories
# in the system (of course the bruteforce attack is limited to a given range).
# In some Apache/UNIX systems this might give out many local users
# (which could later on be used for a ssh brute-force attack)

# this plugin was written by Javier Fernandez-Sanguino Pe–a

sub nikto_userenum {
 if ($NIKTO{mutate} !~ /3/) { return; }

dprint("- Enumerating users and directories bruteforcing the WWW server.\n");
my $user="";

my $min_text_length = 1;
my $max_text_length = 5;
dprint("- Searching from $min_text_length to $max_text_length.\n");

# Note1: This script only generates names with letters A-Z
# (no numbers)
#
# Note2: this script will generate SUM(26^n)(n=$min to $max) 
# it's probably faster to write this to a file than to generate it
# on the fly BTW.
# 
# Of course, it could be optimized to skip some "strange"
# combinations of usernames, but hey, then it wouldn't
# be 'brute force' would it? (jfs)
my $ctr=0;
for ( $min_text_length..$max_text_length ) {
     my $length = $_;
     my $text = "a" x $length;
     my $finish = "z" x $length;
     while ( $text ne $finish ) {
        $text = increment_s($text);
        $ctr++;
        if (($ctr % 500) eq 0) { dprint("\tUser enumeration guess $ctr ($text)\n"); }
        (my $RES , $CONTENT) = fetch("/~".$text,"HEAD");

        if ( $RES eq 301 || $RES eq 200 ) # this is a valid user
         { 
          $VULS++;
          fprint("+ /~".$text." - Is a valid user on the system.");
         }

# This brute forces directories... could be another plugin, lots of requests
#                        (my $RES , $CONTENT) = fetch("/".$text,"HEAD");
#                        if ( $RES eq 301 || $RES eq 200 ) # this is a valid directory
#                        {
#                         $VULS++;
#                         fprint("+ /".$text." - Is a valid directory on the system.");
#                        }
                }
        }
}


sub increment_s {
        my ($string) = @_;
        if ( length ($string) == 1 ) {
                $string = increment_c($string);
        } else {
                my $rest = substr $string, 1;
                my $begin = substr $string,0, 1;
                if ( $rest eq "z" x length($rest) ) {
                        $string = increment_c($begin)."a" x length($rest);
                } else {
                        $string = $begin.increment_s($rest);
                }

        }
        return $string;
}

sub increment_c {
        my ($char) = @_ ;
        if ( length($char) == 1 && $char ne "z" ) {
                $char = chr ( ord($char) + 1 );
        }
        return $char;
}

1;