Nikto: Web Server Security Scanner

JJ Gallego
CyberScribers
Published in
5 min readSep 25, 2024
https://github.com/sullo/nikto

1. Introduction to Nikto

Nikto 2.5 is an open-source web server scanner that performs comprehensive security tests. Key features include:

  • Checks for over 7,000 potentially dangerous files/programs
  • Detects outdated versions of 1250+ servers
  • Identifies version-specific issues on 270+ servers
  • Examines server configuration and installed software
  • Regular updates to scan items and plugins

While not designed for stealth, Nikto aims for speed and thoroughness. It may flag non-security issues for informational purposes. Nikto is a valuable tool for webmasters and security professionals to assess web server vulnerabilities.

2. Installation

sudo apt update && sudo apt upgrade -y
sudo apt install nikto -y

If Nikto is not available in the package repositories, you can install it via GitHub:

sudo apt install git
git clone https://github.com/sullo/nikto.git
cd nikto/program
sudo chmod +x nikto.pl

3. Basic Usage

   Options:
-ask+ Whether to ask about submitting updates
yes Ask about each (default)
no Don't ask, don't send
auto Don't ask, just send
-Cgidirs+ Scan these CGI dirs: "none", "all", or values like "/cgi/ /cgi-a/"
-config+ Use this config file
-Display+ Turn on/off display outputs:
1 Show redirects
2 Show cookies received
3 Show all 200/OK responses
4 Show URLs which require authentication
D Debug output
E Display all HTTP errors
P Print progress to STDOUT
S Scrub output of IPs and hostnames
V Verbose output
-dbcheck Check database and other key files for syntax errors
-followredirects Follow 3xx redirects to new location
-evasion+ Encoding technique:
1 Random URI encoding (non-UTF8)
2 Directory self-reference (/./)
3 Premature URL ending
4 Prepend long random string
5 Fake parameter
6 TAB as request spacer
7 Change the case of the URL
8 Use Windows directory separator (\)
A Use a carriage return (0x0d) as a request spacer
B Use binary value 0x0b as a request spacer
-Format+ Save file (-o) format:
csv Comma-separated-value
htm HTML Format
msf+ Log to Metasploit
nbe Nessus NBE format
txt Plain text
xml XML Format
(if not specified the format will be taken from the file extension passed to -output)
-Help Extended help information
-host+ Target host
-IgnoreCode Ignore Codes--treat as negative responses
-id+ Host authentication to use, format is id:pass or id:pass:realm
-key+ Client certificate key file
-list-plugins List all available plugins, perform no testing
-maxtime+ Maximum testing time per host
-mutate+ Guess additional file names:
1 Test all files with all root directories
2 Guess for password file names
3 Enumerate user names via Apache (/~user type requests)
4 Enumerate user names via cgiwrap (/cgi-bin/cgiwrap/~user type requests)
5 Attempt to brute force sub-domain names, assume that the host name is the parent domain
6 Attempt to guess directory names from the supplied dictionary file
-mutate-options Provide information for mutates
-nointeractive Disables interactive features
-nolookup Disables DNS lookups
-noslash Strip trailing slash from URL (e.g., '/admin/' to '/admin')
-nossl Disables the use of SSL
-no404 Disables nikto attempting to guess a 404 page
-output+ Write output to this file ('.' for auto-name)
-Pause+ Pause between tests (seconds, integer or float)
-Plugins+ List of plugins to run (default: ALL)
-port+ Port to use (default 80)
-RSAcert+ Client certificate file
-root+ Prepend root value to all requests, format is /directory
-Save Save positive responses to this directory ('.' for auto-name)
-ssl Force ssl mode on port
-Tuning+ Scan tuning:
1 Interesting File / Seen in logs
2 Misconfiguration / Default File
3 Information Disclosure
4 Injection (XSS/Script/HTML)
5 Remote File Retrieval - Inside Web Root
6 Denial of Service
7 Remote File Retrieval - Server Wide
8 Command Execution / Remote Shell
9 SQL Injection
0 File Upload
a Authentication Bypass
b Software Identification
c Remote Source Inclusion
x Reverse Tuning Options (i.e., include all except specified)
-timeout+ Timeout for requests (default 10 seconds)
-Userdbs Load only user databases, not the standard databases
all Disable standard dbs and load only user dbs
tests Disable only db_tests and load udb_tests
-until Run until the specified time or duration
-update Update databases and plugins from CIRT.net
-useproxy Use the proxy defined in nikto.conf
-usecookies Use cookies from responses in future requests
-Version Print plugin and database versions
-vhost+ Virtual host (for Host header)
+ requires a value

As I already did in previous post, I have created a docker container and a network.

sudo docker network create --subnet=172.20.0.0/16 my_test_net
sudo docker run -d --name test_container1 --net my_test_net --ip 172.20.0.2 -p 8080:80 nginx

Verify the Nginx Container is Running

After the container starts, check its status to confirm it is running:

docker ps

To scan a web server, run Nikto like this:

sudo nikto -h http://<target_ip_or_domain>

This will start a scan of the target website on port 80 by default. Nikto will check for various vulnerabilities, outdated software, misconfigurations, and much more.

You can output the scan results to a file for further analysis. For example, to save the output to a text file, or save it in different formats, like HTML or CSV:

sudo nikto -h http://localhost:3000 -output results.txt

sudo nikto -h http://localhost:3000 -o results.html -Format html

4. Scan a Specific IP Range

As in my case I have set 3 VM I will use a script to loop through the IP range and scan each IP address individually. So first I start my VN and VMs again as I shutted down my system.

sudo docker ps -a
sudo docker start test_container1
sudo docker start test_container2
sudo docker start test_container3
sudo docker network inspect my_test_net
  • test_container1: IP 172.20.0.2
  • test_container2: IP 172.20.0.3
  • test_container3: IP 172.20.0.4

There are different ways for the script, for example in our case we can do:

#!/bin/bash
# Define the Docker container IP range
# Adjust the IP addresses to match your actual container IPs
for ip in 172.20.0.2 172.20.0.3 172.20.0.4; do
echo "Scanning $ip"
# Run Nikto on each IP address and save the output to a file
sudo nikto -h http://$ip -output "nikto_scan_$ip.txt"
done

Or we can do an script to iterate through the IP range and run Nikto on each IP.

# Define the starting and ending IPs
for ip in {1..255}; do
echo "Scanning 192.168.0.$ip"
# Run Nikto on each IP address and save the output
sudo nikto -h http://192.168.0.$ip -output "nikto_scan_192.168.0.$ip.txt"
done

After that we should make the script executable, to do that save the script as nikto_scan.sh, and make it executable by running:

chmod +x nikto_scan.sh
./nikto_scan.sh

This will go through all IP addresses and scan each one using Nikto. You will get the output for each IP address in sequence.

Now that I have my report in my homeLab, I will use scp as I explained in my previous post:

first I do pwd to see the current directory, and then just use the scp command with the directory of origin and the target one.

scp /path/to/source/file username@remote_host:/path/to/destination

sudo scp /home/raven/tools/nikto_scan_172.20.0.* raven@192.168.0.1:/home/raven/Documents/

--

--

JJ Gallego
CyberScribers

Biologist specializing in Molecular Microbiology and cybersecurity.