# Nikto v2.1.0 - The Manual

List of Tables

7.1. Scan Database Fields
7.2. Members of the Mark structure
7.3. Members of the Vulnerability structure
7.4. Members of the cache structure
7.5. TID Scheme

List of Examples

3.1. Valid Hosts File
7.1. Example initialisation function

## Chapter 1. Introduction

## Overview

Nikto is a web server assessment tool. It is designed to find various default and insecure files, configurations and programs on any type of web server.

## Description

Examine a web server to find potential problems and security vulnerabilities, including:

- Server and software misconfigurations

- Default files and programs

- Insecure files and programs

- Outdated servers and programs

Nikto is built on LibWhisker (by RFP) and can run on any platform which has a PERL environment. It supports SSL, proxies, host authentication, IDS evasion and more. It can be updated automatically from the command-line, and supports the optional submission of updated version data back to the maintainers.

The name "Nikto" is taken from the movie "The Day the Earth Stood Still", and of course subsequent abuse by Bruce Campbell in "Army of Darkness". More information on the pop-culture popularity of Nikto can be found at http://www.blather.net/blather/2005/10/klaatu_barada_nikto_the_day_th.html

## Advanced Error Detection Logic

Most web security tools, (including Nikto 1.32 and below), rely heavily on the HTTP response to determine if a page or script exists on the target. Because many servers do not properly adhere to RFC standards and return a 200 "OK" response for requests which are not found or forbidden, this can lead to many false-positives. In addition, error responses for various file extensions can differ--the "not found" response for a .html file is often different than a .cgi.

Some testing tools, such as Nessus, also look at the content of the response to help eliminate these false positives. While often effective, this method relies on pre-defined strings to help eliminate false positives.

As of version 2.0 Nikto no longer assumes the error pages for different file types will be the same. A list of unique file extensions is generated at run-time (from the test database), and each of those extensions is tested against the target. For every file type, the "best method" of determining errors is found: standard RFC response, content match or MD4 hash (in decreasing order of preference). This allows Nikto to use the fastest and most accurate method for each individual file type, and therefore help eliminate the false positives seen for some servers in version 1.32 and below.

For example, if a server responds with a 404 "not found" error for a non-existent .txt file, Nikto will match the HTTP response of "404" on tests. If the server responds with a 200 "OK" response, it will try to match on the content, and assuming it finds a match (for example, the words "could not be found"), it will use this method for determining missing .txt files. If the other methods fail, Nikto will attempt to remove date and time strings (which can constantly change) from the returned page's content, generate an MD5 hash of the content, and then match that hash value against future .txt tests. The latter is by far the slowest type of match, but in many cases will provide valid results for a particular file type.

## History

The Nikto 1.00 Beta was released on December 27, 2001, (followed almost immediately by the 1.01 release). Over the course of two years Nikto's code evolved into the most popular freely available web vulnerability scanner. The 2.0 release, in November, 2007 represents several years of improvements.

In 2008, due to other commitments, Sullo, the original author couldn't continue to support Nikto and the code was released under the GPL and passed to the community for support.

## Chapter 2. Installation

## Requirements

Any system which supports a basic PERL installation should allow Nikto to run. It has been extensively tested on:

- Windows (using ActiveState Perl)

- Mac OSX

- Various Linux and Unix installations (including RedHat, Solaris, Debian, Knoppix, etc.)

The only required PERL module that does not come standard is LibWhisker. Nikto comes with and is configured to use a local LW.pm file (in the plugins directory), but users may wish to change Nikto to use a version installed on the system. See Section 2 for further information.

For SSL support the Net::SSLeay PERL module must be installed (which in turn requires OpenSSL on the Unix platform). Windows support for SSL is dependent on the installation package, but is rumored to exist for ActiveState's Perl.

The nmap scanner can also be used, if desired. In some cases using nmap will slow down Nikto execution, as it must call an external program. For scanning many ports across one or more servers, using nmap will be faster than using Nikto's internal PERL scanning.

- PERL: http://www.cpan.org/

- LibWhisker: http://www.wiretrip.net/

- ActiveState Perl: http://www.activestate.com/

- OpenSSL: http://www.openssl.org/

- nmap: http://insecure.org/

## Install

These instructions do not include information on installing PERL, PERL Modules, OpenSSL, LibWhisker or any of the utilities that may be needed during installation (such as gzip, tar, etc.). Please see the distributor's documentation for information on how to install and configure those software packages.

Unpack the download file:

    tar -xvfz nikto-current.tar.gz

Assuming a standard OS/PERL installation, Nikto should now be usable. See Chapter 4 (Options) or Chapter 8 (Troubleshooting) for further configuration information.

## Chapter 3. Usage

## Basic Testing

The most basic Nikto scan requires simply a host to target, since port 80 is assumed if none is specified. The host can either be an IP or a hostname of a machine, and is specified using the -h (-host) option. This will scan the IP 192.168.0.1 on TCP port 80:

    perl nikto.pl -h 192.168.0.1

To check on a different port, specify the port number with the -p (-port) option. This will scan the IP 192.168.0.1 on TCP port 443:

    perl nikto.pl -h 192.168.0.1 -p 443

Hosts, ports and protocols may also be specified by using a full URL syntax, and it will be scanned:

    perl nikto.pl -h https://192.168.0.1:443/

There is no need to specify that port 443 may be SSL, as Nikto will first test regular HTTP and if that fails, HTTPS. If you are sure it is an SSL server, specifying -s (-ssl) will speed up the test.

    perl nikto.pl -h 192.168.0.1 -p 443 -ssl

| Note
`-mutate` 1 increases the number of tests so that all filenames are tested against all databases inc `db_tests`. This will produce over 2,000,000 extra tests, which will use up a massive amount of resource.

More complex tests can be performed using the `-mutate` parameter, as detailed later. This can produce extra tests, some of which may be provided with extra parameters through the `-mutate-options` parameter. For example, using `-mutate` 3, with or without a file attempts to brute force usernames if the web server allows ~`user` URIs:

    perl nikto.pl -h 192.168.0.1 -mutate 3 -mutate-options user-list.txt

## Multiple Port Testing

Nikto can scan multiple ports in the same scanning session. To test more than one port on the same host, specify the list of ports in the -p (-port) option. Ports can be specified as a range (i.e., 80-90), or as a comma-delimited list, (i.e., 80,88,90). This will scan the host on ports 80, 88 and 443.

    perl nikto.pl -h 192.168.0.1 -p 80,88,443

## Multiple Host Testing

Nikto support scanning multiple hosts in the same session via a text file of host names or IPs. Instead of giving a host name or IP for the -h (-host) option, a file name can be given. A file of hosts must be formatted as one host per line, with the port number(s) at the end of each line. Ports can be separated from the host and other ports via a colon or a comma. If no port is specified, port 80 is assumed.

This is an example of a valid hosts file:

Example 3.1. Valid Hosts File

    192.168.0.1:80
    http://192.168.0.1:8080/
    192.168.0.3

| Note
For win32 users: due to peculiaries in the way that cmd.exe works with pipes, the above example may not work for you. In this case a temporary file will have to be used to store the output from nmap

A host file may also be an nmap output in "greppable" format (i.e. from the output from -oG).

A file may be passed to Nikto through stdout/stdin using a "-" as the filename. For example:

    nmap -p80 192.168.0.0/24 -oG - | nikto.pl -h -

## Using a Proxy

If the machine running Nikto only has access to the target host (or update server) via an HTTP proxy, the test can still be performed. Set the `PROXY*` variables (as described in section 4), then execute Nikto with the -u (-useproxy) command. All connections will be relayed through the HTTP proxy specified in the configuration file.

    perl nikto.pl -h 192.168.0.1 -p 80 -u

## Updating

Nikto can be automatically updated, assuming you have Internet connectivity from the host Nikto is installed on. To update to the latest plugins and databases, simply run Nikto with the -update command.

| Note
The -update option cannot be abbreviated.

    perl nikto.pl -update

If updates are required, you will see a list of the files downloaded:

     perl nikto.pl -update
     + Retrieving 'nikto_core.plugin'
     + Retrieving 'CHANGES.txt'

Updates may also be manually downloaded from http://www.cirt.net/

## Integration with Nessus

Nessus (http://www.nessus.org/nessus/) can be configured to automatically launch Nikto when it finds a web server. Ensure Nikto works properly, then place the directory containing nikto.pl in root's PATH environment variable. When nessusd starts, it should see the nikto.pl program and enable usage through the GUI.

## Chapter 4. Command Line Options

## All Options

Below are all of the Nikto command line options and explanations. A brief version of this text is available by running Nikto with the -h (-help) option.

`-Cgidirs`

  Scan these CGI directories. Special words "none" or "all" may be used to scan all CGI directories or none, (respectively). A literal value for a CGI directory such as "/cgi-test/" may be specified (must include trailing slash). If this is option is not specified, all CGI directories listed in config.txt will be tested.

`-config`

  Specify an alternative config file to use instead of the config.txt located in the install directory.

`-dbcheck`

  Check the scan databases for syntax errors.

`-Display`

  Control the output that Nikto shows. See Chapter 5 for detailed information on these options. Use the reference number or letter to specify the type, multiple may be used:

  1 - Show redirects

  2 - Show cookies received

  3 - Show all 200/OK responses

  4 - Show URLs which require authentication

  D - Debug Output

  V - Verbose Output

`-evasion`

  Specify the LibWhisker IDS evasion technique to use (see the LibWhisker docs for detailed information on these). Use the reference number to specify the type, multiple may be used:

  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 (\)

`-findonly`

  Only discover the HTTP(S) ports, do not perform a security scan. This will attempt to connect with HTTP or HTTPS, and report the Server header.

`-Format`

  Save the output file specified with -o (-output) option in this format. If not specified, the default will be taken from the file extension specified in the -output option. Valid formats are:

  csv - a comma-seperated list

  htm - an HTML report

  txt - a text report

  xml - an XML report

`-host`

  Host(s) to target. Can be an IP address, hostname or text file of hosts. A single dash (-) maybe used for stdout. Can also parse nmap -oG style output

`-Help`

  Display extended help information.

`-id`

  ID and password to use for host Basic host authentication. Format is "id:password".

`-list-plugins`

  Will list all plugins that Nikto can run against targets and then will exit without performing a scan. These can be tuned for a session using the -plugins option.

  The output format is:

  Plugin `name`

  `full name` - `description`

  Written by `author`, Copyright (C) `copyright`

`-mutate`

  Specify mutation technique. A mutation will cause Nikto to combine tests or attempt to guess values. These techniques may cause a tremendous amount of tests to be launched against the target. Use the reference number to specify the type, multiple may be used:

  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 extra information for mutates, e.g. a dictionary file

`-nolookup`

  Do not perform name lookups on IP addresses.

`-nossl`

  Do not use SSL to connect to the server.

`-no404`

  Disable 404 (file not found) checking. This will reduce the total number of requests made to the webserver and may be preferable when checking a server over a slow link, or an embedded device. This will generally lead to more false positives being discovered.

`-output`

  Write output to the file specified. The format used will be taken from the file extension. This can be over-riden by using the -Format option (e.g. to write text files with a different extenstion. Existing files will have new information appended.

`-plugins`

  Select which plugins will be run on the specified targets. A comma separated list should be provided which lists the names of the plugins. The names can be found by using -list-plugins.

  There are two special entries: ALL, which specifies all plugins shall be run and NONE, which specifies no plugins shall be run. The default is ALL

`-port`

  TCP port(s) to target. To test more than one port on the same host, specify the list of ports in the -p (-port) option. Ports can be specified as a range (i.e., 80-90), or as a comma-delimited list, (i.e., 80,88,90). If not specified, port 80 is used.

`-Pause`

  Seconds to delay between each test.

`-root`

  Prepend the value specified to the beginning of every request. This is useful to test applications or web servers which have all of their files under a certain directory.

`-ssl`

  Only test SSL on the ports specified. Using this option will dramatically speed up requests to HTTPS ports, since otherwise the HTTP request will have to timeout first.

`-Single`

  Perform a single request to a target server. Nikto will prompt for all options which can be specified, and then report the detailed output. See Chapter 5 for detailed information.

`-timeout`

  Seconds to wait before timing out a request. Default timeout is 10 seconds.

`-Tuning`

  Tuning options will control the test that Nikto will use against a target. By default, if any options are specified, only those tests will be performed. If the "x" option is used, it will reverse the logic and exclude only those tests. Use the reference number or letter to specify the type, multiple may be used:

  0 - File Upload

  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

  a - Authentication Bypass

  b - Software Identification

  c - Remote Source Inclusion

  x - Reverse Tuning Options (i.e., include all except specified)

  The given string will be parsed from left to right, any x characters will apply to all characters to the right of the character.

`-useproxy`

  Use the HTTP proxy defined in the configuration file.

`-update`

  Update the plugins and databases directly from cirt.net.

`-Version`

  Display the Nikto software, plugin and database versions.

`-vhost`

  Specify the Host header to be sent to the target.

## Mutation Techniques

A mutation will cause Nikto to combine tests or attempt to guess values. These techniques may cause a tremendous amount of tests to be launched against the target. Use the reference number to specify the type, multiple may be combined.

1. Test all files with all root directories. This takes each test and splits it into a list of files and directories. A scan list is then created by combining each file with each directory.

2. Guess for password file names. Takes a list of common password file names (such as "passwd", "pass", "password") and file extensions ("txt", "pwd", "bak", etc.) and builds a list of files to check for.

3. Enumerate user names via Apache (/~user type requests). Exploit a misconfiguration with Apache UserDir setups which allows valid user names to be discovered. This will attempt to brute-force guess user names. A file of known users can also be supplied by supplying the file name in the `-mutate-options` parameter.

4. Enumerate user names via cgiwrap (/cgi-bin/cgiwrap/~user type requests). Exploit a flaw in cgiwrap which allows valid user names to be discovered. This will attempt to brute-force guess user names. A file of known users can also be supplied by supplying the file name in the `-mutate-options` parameter.

5. Attempt to brute force sub-domain names. This will attempt to brute force know domain names, it will assume the given host (without a www) is the parent domain.

6. Attempt to brute directory names. This is the only mutate option that requires a file to be passed in the `-mutate-options` parameter. It will use the given file to attempt to guess directory names. Lists of common directories may be found in the OWASP DirBuster project.

## Display

By default only some basic information about the target and vulnerabilities is shown. Using the `-Display` parameter can produce more information for debugging issues.

- 1 - Show redirects. This will display all requests which elicit a "redirect" response from the server.

- 2 - Show cookies received. This will display all cookies that were sent by the remote host.

- 3 - Show all 200/OK responses. This will show all responses which elicit an "okay" (200) response from the server. This could be useful for debugging.

- 4 - Show URLs which require authentication. This will show all responses which elicit an "authorization required" header.

- D - Debug Output. Show debug output, which shows the verbose output and extra information such as variable content.

- V - Verbose Output. Show verbose output, which typically shows where Nikto is during program execution.

## Scan Tuning

Scan tuning can be used to decrease the number of tests performed against a target. By specifying the type of test to include or exclude, faster, focused testing can be completed. This is useful in situations where the presence of certain file types are undesired -- such as XSS or simply "interesting" files.

Test types can be controlled at an individual level by specifying their identifier to the `-T` (`-Tuning`) option. In the default mode, if `-T` is invoked only the test type(s) specified will be executed. For example, only the tests for "Remote file retrieval" and "Command execution" can performed against the target:

    perl nikto.pl -h 192.168.0.1 -T 58

If an "x" is passed to `-T` then this will negate all tests of types following the x. This is useful where a test may check several different types of exploit. For example:

    perl nikto.pl -h 192.168.0.1 -T 58xb

The valid tuning options are:

- 0 - File Upload. Exploits which allow a file to be uploaded to the target server.

- 1 - Interesting File / Seen in logs. An unknown but suspicious file or attack that has been seen in web server logs (note: if you have information regarding any of these attacks, please contact CIRT, Inc.).

- 2 - Misconfiguration / Default File. Default files or files which have been misconfigured in some manner. This could be documentation, or a resource which should be password protected.

- 3 - Information Disclosure. A resource which reveals information about the target. This could be a file system path or account name.

- 4 - Injection (XSS/Script/HTML). Any manner of injection, including cross site scripting (XSS) or content (HTML). This does not include command injection.

- 5 - Remote File Retrieval - Inside Web Root. Resource allows remote users to retrieve unauthorized files from within the web server's root directory.

- 6 - Denial of Service. Resource allows a denial of service against the target application, web server or host (note: no intentional DoS attacks are attempted).

- 7 - Remote File Retrieval - Server Wide. Resource allows remote users to retrieve unauthorized files from anywhere on the target.

- 8 - Command Execution / Remote Shell. Resource allows the user to execute a system command or spawn a remote shell.

- 9 - SQL Injection. Any type of attack which allows SQL to be executed against a database.

- a - Authentication Bypass. Allows client to access a resource it should not be allowed to access.

- b - Software Identification. Installed software or program could be positively identified.

- c - Remote source inclusion. Software allows remote inclusion of source code.

- x - Reverse Tuning Options. Perform exclusion of the specified tuning type instead of inclusion of the specified tuning type.

## Single Request Mode

Single request mode is designed to preform a solitary request against the target. This is useful to confirm a test result using the same resources Nikto used during a scan. The single option allows manual setting of most variables used by Nikto and LibWhisker, and upon completion will display both the request and the result of the operation.

Most options have a default value or can be left blank. The most common and required values are at the beginning of the "questions" section for slightly easier use. True and false are specified by numeric equivalents, 1 and 0 respectively. Please note that Single mode is not very user-friendly. Here is an example Nikto run with the `-Single` option.

    [dave@yggdrasil nikto-2.03]$ ./nikto.pl -Single
    --------------------------------------------  Nikto 2.1.0
    --------------------------------------------  Single Request Mode
                                  Hostname or IP: localhost
                                       Port (80):
                                         URI (/): /test.html
                                         SSL (0):
                                      Proxy host:
                                      Proxy port:
                          Show HTML Response (1):
                              HTTP Version (1.1):
                               HTTP Method (GET):
          User-Agent (Mozilla/4.75 (Nikto/2.1.0):
                         Connection (Keep-Alive):
                                            Data:
                            force_bodysnatch (0):
                                 force_close (1):
                                 http_space1 ( ):
                                 http_space2 ( ):
                         include_host_in_uri (0):
               invalid_protocol_return_value (1):
                                    max_size (0):
                                 protocol (HTTP):
               require_newline_after_headers (0):
                                       retry (0):
                               ssl_save_info (0):
                                    timeout (10):
                                 uri_password ():
                                  uri_postfix ():
                                   uri_prefix ():
                                     uri_user ():
                             Enable Anti-IDS (0):
    --------------------------------------------  Done with questions
            Host Name: localhost
            Host IP: 127.0.0.1
            HTTP Response Code: 404
    --------------------------------------------  Connection Details
            Connection: Keep-Alive
            Host: localhost
            User-Agent: Mozilla/4.75 (Nikto/2.1.0
            data:
            force_bodysnatch: 0
            force_close: 1
            force_open: 0
            host: localhost
            http_space1:
            http_space2:
            ignore_duplicate_headers: 1
            include_host_in_uri: 0
            invalid_protocol_return_value: 1
            max_size: 0
            method: GET
            port: 80
            protocol: HTTP
            require_newline_after_headers: 0
            retry: 0
            ssl: 0
            ssl_save_info: 0
            timeout: 10
            trailing_slurp: 0
            uri: /test.html
            uri_param_sep: ?
            uri_postfix:
            uri_prefix:
            version: 1.1
    --------------------------------------------  Response Headers
            Connection: close
            Content-Length: 268
            Content-Type: text/html; charset=iso-8859-1
            Date: Tue, 18 Aug 2009 10:13:57 GMT
            Server: Apache/2
            code: 404
            http_data_sent: 1
            http_eol:

            http_space1:
            http_space2:
            message: Not Found
            protocol: HTTP
            uri: /test.html
            version: 1.1
    --------------------------------------------  Response Content
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>404 Not Found</title>
    </head><body>
    <h1>Not Found</h1>
    <p>The requested URL /test.html was not found on this server.</p>
    <hr>
    <address>Apache/2 Server at localhost Port 80</address>
    </body></html>

## Chapter 5. Configuration Files

## Location

Nikto, like any non-trivial program needs to know a few things about how to work with the current environment. For most situations the default configuration file will work. Sometimes, tuning may be required, or some things may need to be changes.

Nikto will look for a configuration file in three places and if it finds one, will apply it in the strict order, listed below. A later found configuration file will overwrite any variables set in an earlier configuration file. The locations are:

1. /etc/nikto.conf (this may be altered depending on platform)

2. $HOME/nikto.conf

3. nikto.conf

## Format

The configuration files are formated like a standard Unix configuration file: blank lines are ignored, any line starting with a # is ignored, variables are set with VariableName=Value line.

## Variables

The following variables may be set within the configuration file:

`CLIOPTS`

  Default options that should always be passed to the command line. For example:

      CLIOPTS=-output results.txt -Format text

  Default Setting

      CLIOPTS=

`NIKTODTD`

  Path to the location of the DTD used for XML output. If the path is not absolute then it will be relative to the directory where Nikto is executed.

  Default Setting

      NIKTODTD=docs/nikto.dtd

`NMAP`, `NMAPOPTS`

  Deprecated

  Location of nmap and the default nmap options. Nikto used to use nmap to aid in checking for valid HTTP ports on any targets. From Nikto 2.10, nmap is no longer used from within Nikto and this variable will do nothing. This variable may be removed in a later version.

  Default Setting

      NMAP=/usr/local/bin/nmap
      NMPOPTS=-P0

`SKIPPORTS`

  Deprecated

  This configuration item originally defined ports that would never be scanned by Nikto. This is currently unused and deprecated.

  Default Setting

      SKIPPORTS=21 111

`SKIPIDS`

  | Note
  Note, this filter only applies to tests in the `db_tests` database

  Contains a space separated list of Test IDs (tids) that Nikto will not run on the system, for example:

      SKIPIDS=000045 000345

  Default Setting

      SKIPIDS=

`DEFAULTHTTPVER`

  Defines the default version of HTTP that Nikto will use, unless superceded by a specific test. Usually keeping this to the default will suffice, though some web servers may only work with later versions of the HTTP protocol.

  Default Setting

      DEFAULTHTTPVER=1.0

`UPDATES`

  If the outdated Nikto plugin sees a web server it doesn't know of, or a version that is later than that defined in `db_outdated`, then it will send this information back to cirt.net for inclusion in future versions of Nikto. Server specific information (e.g. IP addresses or hostnames) are not sent.

  This item can be set to one of the below values:

  > `UPDATES=yes`

  >   Display each submission and ask for permission before it is sent

  > `UPDATES=no`

  >   Do not send any data back to cirt.net

  > `UPDATES=auto`

  >   Send data back to cirt.net with no prompting

  Default Setting

      UPDATES=yes

`MAX_WARN`

  Unused

  Produces a warning of a number of MOVED responses are retrieved. This is currently unused.

  Default Setting

      MAX_WARN=20

`PROMPTS`

  Deprecated

  Disables Nikto prompts if set to "no". This is currently unused and has been deprecated by the UPDATES item.

  Default Setting

      PROMPTS=

`CIRT`

  The IP address that Nikto will use to update the databases and plugins, or will send version information back to (as described in the `UPDATES` item).

  Default Setting

      CIRT=209.172.49.178

`PROXYHOST`, `PROXYPORT`, `PROXYUSER`, `PROXYPASS`

  Address, port and username password of a proxy to relay all requests through. Note, to use a proxy, you must set the configuration items in the configuration file and supply the `-useproxy` switch to the command line.

  Default Setting

      PROXYHOST=
      PROXYPORT=
      PROXYUSER=
      PROXYPASS=

`STATIC-COOKIE`

  Adds the supplied cookie to all requests made via Nikto, this is generally useful is an authentication cookie is required for a website. For example:

      STATIC-COOKIE=userid=0

  Default Setting

      STATIC-COOKIE=

`CHECKMETHODS`

  Nikto will attempt to identify targets as webservers by sending a request to fetch the / URI via certain HTTP methods. Some web servers do not implement all HTTP methods and may cause Nikto to fail to identify the web server correctly if it doesn't support the method being used.

  If this setting is missing from the configuration file, then Nikto will default back to the Nikto 2.02 default of HEAD.

  Default Setting

      CHECKMETHODS=HEAD GET

`EXECDIR`, `PLUGINDIR`, `TEMPLATEDIR`, `DOCDIR`

  Defines where to find the location of Nikto, its plugins, XML/HTML templates and documents. This should only normally be changed if repackaging Nikto to work with different file system standards. Nikto will use the EXECDIR item to guess the other directories.

  Default Setting

      EXECDIR=.
      PLUGINDIR=EXECDIR/plugins
      TEMPLATEDIR=EXECDIR/templates
      DOCDIR=EXECDIR/docs

## Chapter 6. Output and Reports

## Export Formats

Nikto saved output comes in four flavours: text, CSV, XML or HTML. When using `-output`, an output format may be specified with `-Format`. Text format is assumed if nothing is specified with `-Format`. The DTD for the Nikto XML format can be found in the 'docs' directory (nikto.dtd).

## HTML and XML Customisation

HTML reports are generated from template files located in the `templates` directory. Variables are defined as `#variable-name`, and are replaced when the report is generated. The files `htm_start.tmpl` and `htm_end.tmpl` are included at the beginning and end of the report (respectively). The `htm_summary.tmpl` also appears at the beginning of the report. The `htm_host_head` appears once for every host, and the `htm_host_item.tmpl` and `htm_host_im.tmpl` appear once for each item found on a host and each "informational message" per host (respectively).

All valid variables are used in these templates. Future versions of this documentation will include a list of variables and their meaning.

The copyright statements must not be removed from the `htm_end.tmpl` without placing them in another of the templates. It is a violation of the Nikto licence to remove these notices.

## Chapter 7. Test and Code Writing

## Scan Database Field Values

Though some checks can be found in other plugins, the `scan_database.db` contains the bulk of the web test information. Here is a description of the field values:

Table 7.1. Scan Database Fields

Test ID | Nikto test ID
OSVDB-ID | Corresponding vulnerability entry number for osvdb.org
Server Type | Generic server matching type
URI | URI to retrieve
HTTP Method | HTTP method to use for URI
Match 1 | String or code to match for successful test
Match 1 (Or) | String or code to alternatively match for successful test
Match1 (And) | String or code to also match for successful test
Fail 1 | String or code to match for test failure
Fail 2 | String or code to match for test failure (alternative)
Summary | Summary message to report for successful test
HTTP Data | HTTP data to be sent during POST tests
Headers | Additional headers to send during test

## User-Defined Tests

Users can create their own, private tests for any of the databases. By placing a syntactically correct database file in the `plugins` directory, with a file name prefaced with a "u", the data will be loaded along with the built-in checks.

For example, create the file `plugins/udb_tests` and it will be loaded at the same time `plugins/db_tests` is loaded. These files will also be checked for syntax when `-dbcheck` is used.

For tests which require a "private" OSVDB ID, use the OSVDB ID 0 (zero). This should be used for all vulnerabilities that do not (or should not) exist in OSVDB, as ID 0 is for testing only. You are encouraged to send missing information to OSVDB at moderators@osvdb.org.

For the "Test ID", it is recommended you use unique numbers between 400000 and 499999 to allow for growth of the Nikto database without interfering with your own tests (note: numbers above 500000 are reserved for other tests).

Please help Nikto's continued success by sending test updates to `<sullo@cirt.net>`.

## Scan Database Syntax

The scan database is a CSV delimited file which contains most of the tests. Fields are enclosed by quotes and separated by commas. The field order is:

Test-ID, OSVDB-ID, Tuning Type, URI, HTTP Method, Match 1, Match 1 Or, Match1 And, Fail 1, Fail 2, Summary, HTTP Data, Headers

Here is an example test:

    "120","3092","2","/manual/","GET","200","","","","","Web server manual","",""

## Plugins

To allow a bit more flexibility, Nikto allows plugins so that there is easy expansion of existing capabilities and some future proofing.

Plugins are run in four different phases, these are:

> Initialisation (mandatory)

>   Plugin initialisation is performed before targets are assigned. During this phase, the plugin should tell Nikto about its existence and capabilities. It may optionally set up any later required variables.

> Reconnaisance (optional)

>   During the reconnaisance phase, the plugin should look for interesting information that may be of use during the scan phase. It may report vulnerablities, though this is discouraged.

> Scan (optional)

>   The scan phase should perform the meat of the plugin - this is where it should look at the web server and return any potential vulnerabilities.

> Reporting (optional)

>   The reporting phase is used to export any found vulnerabilities into a format that they can be used later, for example written as a file report, or imported into a database. No testing of the web server, or reporting of new vulnerbilies should be performed in this phase.

>   This phase is slightly more complex than the others and may be called at several points during Nikto's execution, as detailed later

Plugins are written in standard perl in the current context. They should be placed within the `PLUGINDIR` defined in the Nikto configuration file and must have a filename ending in `.plugin`.

An important concept to grasp about plugins and the order that are executed in is plugin weight: each phase will execute all defined plugins in the order defined by the weight. A plugin's weight is defined as a number between 1 and 100, where 1 is high priority and 100 is low priority. Plugins of equal weight will be executed in an undefined order.

### Initialisation Phase

As described above, all plugins must be able to execute in the initialisation phase or they will be ignored.

A perl sub must exist called ``filename`_init`. The sub is passed no parameters and should return a hash reference to a hash that should contain the following entries:

`name` (mandatory)

  The short name of the plugin. This is used to identify the plugin during verbose logging and will, in future versions, be used to select plugin execution. The name should be one word and, ideally, lower case.

`full_name` (mandatory)

  The full name of the plugin. This is used to identify the plugin during verbose logging and may be used in reporting modules to identify tests run against the web server.

`author` (mandatory)

  The name or handle of the author of the plugin. This may be used during reporting to identify ownerships of copyright of tests run against the web server.

`description` (mandatory)

  A short sentence to describe the purpose of the plugin. This may be used during reporting, or by a front end to describe the purpose of the plugin.

`copyright` (mandatory)

  The copyright string (or lack of it) of the plugin. This may be used during reporting to ensure that appropriate copyright is assigned to reports.

`recon_method` (optional)

  This should be a reference to a function used during the reconnaisance phase of the plugin's execution. If this is left undefined then the plugin will not execute during the reconnaisance phase.

`recon_cond` (optional)

  This is an expression to be evaluated before the plugin is executed; if true, the plugins is executed, if false, the plugin is skipped. This can be used to minimise plugin execution.

`recon_weight` (optional)

  This is the weight used to schedule the running of the plugin during the reconnaisance phase. If this is left undefined it will default to 50.

`scan_method` (optional)

  This should be a reference to a function used during the scan phase of the plugin's execution. If this is left undefined then the plugin will not execute during the scan phase.

`scan_cond` (optional)

  This is an expression to be evaluated before the plugin is executed; if true, the plugins is executed, if false, the plugin is skipped. This can be used to minimise plugin execution.

`scan_weight` (optional)

  This is the weight used to schedule the running of the plugin during the scan phase. If this is left undefined it will default to 50.

`report_head` (optional)

  This should be a reference to a function executed before any testing commences. If this is left undefined then the plugin will not be called to produce a report header.

`report_host_start` (optional)

  This should be a reference to a function executed before the reconnaisance phase of each host. If this is left undefined then the plugin will not be called to produce a host header.

`report_host_end` (optional)

  This should be a reference to a function executed after the scan phase of each host. If this is left undefined then the plugin will not be called to produce a host footer.

`report_item` (optional)

  This should be a reference to a function executed after each found vulnerability. If this is left undefined then the plugin will not be called to produce an item record.

`report_close` (optional)

  This should be a reference to a function executed after testing of all hosts has been finished. If this is left undefined then the plugin will not be called to close the report.

`report_format` (optional)

  This should describe the file format that the plugin handles. This is internally matched with the contents of the `-output` switch to reduce excessive calls to plugins.

`report_weight` (optional)

  This is the weight used to schedule the running of the plugin during the reporting phase. If this is left undefined it will default to 50.

Example 7.1. Example initialisation function

     sub nikto_dictionary_attack_init
    {
       my $id =
       {
          name         => "dictionary",
          full_name    => "Dictionary attack",
          author       => "Deity",
          description  => "Attempts to dictionary attack commonly known directories/files",
          recon_method => \&nikto_dictionary_attack,
          recon_cond   => '$CLI{mutate} =~ /6/',
          recon_weight => 20,
          copyright    => "2009 CIRT Inc"
       };

       return $id;
    }

### Reconnaisance Phase

The reconnaisance phase is executed for each target at the start of each scan.

Each reconnaisance method such expect to take a `mark` hash ref. It should return nothing.

`void recon_method(` | mark`)`; |

`hashref` | `mark;`

The reconnaisance phase is intended to be used to pull information about the web server for later use by the plugin, or by other plugins. Reporting vulnerabilities in this phase is discouraged.

Example uses of the reconnaisance phase are to spider a site, check for known applications etc.

### Scan Phase

The scan phase is the meat of the plugin's life, this is run, for each target, immediately after the reconnaisance phase.

Each scan should check for vulnerabilities it knows about and report on them as it finds one.

`void scan_method(` | mark`)`; |

`hashref` | `mark;`

### Reporting Phase

This is potentially the most convoluted phase as it has several hooks that may be used for each section in the scan's lifetime.

The hooks are:

#### Report Head

This hook is called immediately after target acquisition and before the reconnaisance phase. It is designed to allow the reporting plugin to open the report and ensure that any headers are appropiately written.

`handle report_head(` | filename`)`; |

`string` | `filename;`

The `filename` parameter is a bit of a misnomer; it will be a copy of the string passed to the `-output` switch and may indicate, for example, a database name.

The `handle` is a handle that will be passed to other reporting functions for this plugin so should be internally consistent.

#### Report Host Start

This hook is called immediately before the reconnaisance phase for each target. It is designed to allow the reporting plugin to write any host specfic information.

`void report_host_start(` | rhandle, |
| mark`)`; |

`handle` | `rhandle;`
`hashref` | `mark;`

The `rhandle` parameter is the output of the plugin's Report Head function.

The `mark` parameter is a hashref for the target information (described below).

#### Report Host End

This hook is called immediately after the scan phase for each target. It is designed to allow the reporting plugin to close any host specfic information.

`void report_host_end(` | rhandle, |
| mark`)`; |

`handle` | `rhandle;`
`hashref` | `mark;`

The `rhandle` parameter is the output of the plugin's Report Head function.

The `mark` parameter is a hashref for the target information (described below).

#### Report Item

This hook is called once for each vulnerability found on the target This should report details about the vulnerability.

`void report_item(` | rhandle, |
| mark, |
| vulnerbility`)`; |

`handle` | `rhandle;`
`hashref` | `mark;`
`hashref` | `vulnerbility;`

The `rhandle` parameter is the output of the plugin's Report Head function.

The `mark` parameter is a hashref for the target information (described below).

The `vulnerability` parameter is a hashref for the vulnerability information (described below).

#### Report Close

This hook is called immediately after all targets have been scanned. It is designed to allow the reporting plugin to elegantly close the report.

`void report_close(` | rhandle`)`; |

`handle` | `rhandle;`

The `rhandle` parameter is the output of the plugin's Report Head function.

### Data Structures

The below data structures are used to communicate between the various plugin methods. Unless otherwise mentioned, they are all standard perl hash references with the detailed members.

#### Mark

The mark hash contains all information about a target. It contains the below members. It should be read-only.

> Table 7.2. Members of the Mark structure

> `ident` | Host identifier, usually equivalent to what was passed on the command line.
> `hostname` | Host name of the target.
> `ip` | IP address of the target.
> `port` | TCP port of the target.
> `display_name` | Either the hostname, or the IP address of the target, dependant on whether a hostname has been discovered.
> `ssl` | Flag to indicate whether the target runs over SSL. If it is set to 0, then the plugin should not use SSL. Any other value indicates SSL should be used.
> `vhost` | Virtual hostname to use for the target.
> `root` | Root URI to use for the target.
> `banner` | Banner of the target's web server.

#### Vulnerability

The vulnerability hash contains all information about a vulnerability. It contains the below members. It should be read-only and should only be written using the `add_vulnerability` method.

> Table 7.3. Members of the Vulnerability structure

> mark | Hash ref to a mark data structure.
> message | Message for the vulnerability.
> nikto_id | Test ID (tid) of the vulnerability, this should be a unique number which'll identify the vulnerability.
> osvdb | OSVDB reference to the vulnerability in the Open Source Vulnerability Database. This may be 0 if an OSVDB reference is not relevant or doesn't exist.
> method | HTTP method used to find the vulnerability.
> uri | URI for the result.
> result | Any HTTP data, excluding headers.

### Standard Methods

Several standard methods are defined in `nikto_core.plugin` that can be used for all plugins. It is strongly advised that these should be used where possible instead of writing new methods.

For some methods, such as `add_vulnerability` which write to global variables, these must be the only interface to those global variables.

`array change_variables(` | line`)`; |

`string` | `line;`

Expands any variables in the line parameter. The expansions are variables defined in the global array `@VARIABLES`, which may be read from `db_variables`, or added by reconnaisance plugin methods.

`int is_404(` | uri, |
| content, |
| HTTPcode`)`; |

`string` | `uri;`
`string` | `content;`
`string` | `HTTPcode;`

Makes a guess whether the result is a real web page or an error page. As several web servers are badly configured and don't return HTTP 404 codes when a page isn't found, Nikto attempts to look for common error pages. Returns 1 if the page looks like an error.

`string get_ext(` | uri`)`; |

`string` | `uri;`

Attempts to work out the extension of the uri. Will return the extension or the special cases: DIRECTORY, DOTFILE, NONE.

`string date_disp(` | `)`; |

`` | `;`

Returns the current time in a human readable format (YYYY-mm-dd hh:mm:ss)

`string rm_active(` | content`)`; |

`string` | `content;`

Attempts to remove active content (e.g. dates, adverts etc.) from a page. Returns a filtered version of the content.

`string get_banner(` | mark`)`; |

`hashref` | `mark;`

Pulls the web servers banner. This is automatically performed for all targets before a mark is passed to the plugin.

`boolean content_present(` | HTTPcode`)`; |

`string` | `HTTPcode;`

Checks the HTTPresponse against known "found" responses. TRUE indicates that the request was probably successful.

`string HTTPCode, string content fetch(` | uri, |
| method, |
| content, |
| headers, |
| noclean`)`; |

`string` | `uri;`
`string` | `method;`
`string` | `content;`
`hashref` | `headers;`
`boolean` | `noclean;`

Deprecated

Performs a simple HTTP request to URI using the HTTP method, `method`. `content` supplies any data to pass in the HTTP body. `headers` allows any custom headers to be placed in the request. `noclean` is a flag specifying that the request shouldn't be cleaned up before being sent (e.g. if the Host: header is blank).

`string HTTPCode, string content nfetch(` | uri, |
| method, |
| content, |
| headers, |
| noclean`)`; |

`string` | `uri;`
`string` | `method;`
`string` | `content;`
`hashref` | `headers;`
`boolean` | `noclean;`

An updated version of fetch that uses a local, rather than a global request/result structure. This should be used in preference to fetch.

`hashref setup_hash(` | requesthash, |
| mark`)`; |

`hashref` | `requesthash;`
`hashref` | `mark;`

Sets up up a libwhisker hash with the normal Nikto variables. This should be used if any custom calls to libwhisker are used.

`string char_escape(` | line`)`; |

`string` | `line;`

Escapes any characters within line.

`array parse_csv(` | text`)`; |

`string` | `text;`

Breaks a line of CSV text into an array of items.

`arrayref init_db(` | dbname`)`; |

`string` | `dbname;`

Initialises a database that is in `PLUGINDIR` and returns an arrayref. The arrayref is to an array of hashrefs, each hash member is configured by the first line in the database file, for example:

    "nikto_id","md5hash","description"

This will result in an array of hashrefs with parameters:

    array[0]->{nikto_id}
    array[0]->{md5hash}
    array[0]->{description}

`void add_vulnerability(` | mark, |
| message, |
| nikto_id, |
| osvdb, |
| method, |
| uri, |
| data`)`; |

`hashref` | `mark;`
`string` | `message;`
`string` | `nikto_id;`
`string` | `osvdb;`
`string` | `method;`
`string` | `uri;`
`string` | `data;`

Adds a vulnerability for the mark, displays it to standard out and sends it to any reporting plugins.

`void nprint(` | message, |
| display`)`; |

`string` | `message;`
`string` | `display;`

Prints `message` to standard out. `Display` specifies a filter for the message, currently this can be "v" for verbose and "d" for debug output.

### Global Variables

The following global variables exist within Nikto, most of them are defined for internal use and their use by plugins is not advised. Several have been deprecated, these should not be used by plugins.

`%TEMPLATES` (read/write)

  Hash to store the HTML and XML report templates.

`%ERRSTRINGS` (read)

  Hash to contain all the entries in db_404 - a list of strings that may indicate a 404.

`%CLI` (read)

  Hash of passed CLI parameters

`%VARIABLES` (read) (write)

  Hash of contents of the entries in db_variables. Plugins should only write to this hash in the reconnaisance phase.

`%TESTS` (read) (write)

  Hash of the db_tests database. This is only intended to be used by the tests plugin, though it could be used by a reconnaisance plugin to add tests on the fly.

`$CONTENT` (read) (write) (deprecated)

  Global variable to store data from a fetch or nfetch. A local variable should be used instead

`%NIKTO` (read)

  Hash which contains internal Nikto data, such as help for the command line parameters.

`%REALMS` (read)

  Hash of data from db_realms.

`%NIKTOCONFIG` (read)

  Hash containing the data read from the configuration files.

`%request` (read) (write) (deprecated), `%result` (read) (write) (deprecated)

  Global libwhisker hash. This should not be used; nfetch or a local hash should be used.

`%COUNTERS` (read) (write)

  Hash containing various global counters (e.g. number of requests)

`%db_extensions` (read) (deprecated)

  Hash containing a list of common extensions

`%FoF` (read) (write)

  Hash containing data for each extension and what the server produces if a request for a non-existent file is requested.

`%UPDATES` (read) (write)

  Hash containing any updates that need to be sent back to cirt.net

`$DIV` (read)

  Divider mark for the items sent to standard out.

`@DBFILE` (read)

  Placeholder used to hold the contents of `db_tests`.

`@BUILDITEMS` (read) (write) (deprecated)

  Array to hold information for tests to act on later. Use should be avoided, a local variable should be used instead.

`$PROXYCHECKED` (read)

  Flag to see whether connection through the proxy has been checked.

`$http_eol` (read) (deprecated)

  Contains the http end of line pattern.

`@RESULTS` (read)

  Array of reported vulnerabilities, should only be written to through `add_vulnerability.`

`@PLUGINS` (read)

  Array of hashrefs for each plugin. Used internally to run plugins.

`@MARKS` (read)

  Array of marks to indicate each target.

`@REPORTS` (read)

  Ordered array that reporting plugins should be run in. Used for efficency on calling reporting plugins.

`%CACHE` (read) (write)

  Containing the URI cache, should only be read/written through `nfetch`. Members:

  > Table 7.4. Members of the cache structure

  > `{uri}` | URI for the cache
  > `{uri}{method}` | HTTP method used
  > `{uri}{res}` | HTTP result for URI
  > `{uri}{content}` | data for URI
  > `{uri}{mark}` | mark hashref for URI

## Test Identifiers

Each test, whether it comes from one of the databases or in code, must have a unique identifier. The numbering scheme for writing tests is as follows:

> Table 7.5. TID Scheme

> 000000 | db_tests
> 400000 | user defined tests (`udb*` files)
> 500000 | db_favicon
> 600000 | db_outdated
> 700000 | db_realms
> 800000 | db_server_msgs
> 900000 | tests defined in code

As much data as possible in the `%TESTS` hash should be populated for each new test that is defined in code (plugins). These fields include URI for the test, message to print on success, HTTP method and OSVDB ID. Without a 'message' value in `%TESTS` output will not be saved in HTML or XML reports. Not all tests are expected to have a uri, method or OSVDB ID. Here is an example of setting those fields:

    $TESTS{999999}{uri}="/~root";
    $TESTS{999999}{message}="Enumeration of users is possible by requesting ~username";
    $TESTS{999999}{method}="GET";
    $TESTS{999999}{osvdb}=637;

## Code Copyrights

Any new or updated code, tests or information sent to the author is assumed to free of copyrights. By sending new or updated code, tests or information to the author you relinquish all claims of copyright on the material, and agree that this code can be claimed under the same copyright as Nikto.

## Chapter 8. Troubleshooting

## SOCKS Proxies

Nikto does not currently support SOCKS proxies.

## Debugging

The major route to debugging Nikto requests is to use the `-Display` with v (verbose) or d (debug). This will output a vast amount of extra information to the screen, so it is advised to redirect output to a file when using them.

## Chapter 9. Licences

## Nikto

Nikto is licensed under the GNU General Public License (GPL), and copyrighted by CIRT, Inc.

## LibWhisker

LibWhisker is licensed under the GNU General Public License (GPL), and copyrighted by Rain Forrest Puppy.

## Tests

The web tests are licensed for use with Nikto only, and may not be reused without written consent from CIRT, Inc.

## Chapter 10. Credits

## Nikto

Nikto was originally written and maintained by Sullo, CIRT, Inc. It is currently maintained by David Lodge. LibWhisker was written by Rain Forrest Puppy

## Thanks

Many people have provided feedback, fixes, and suggestions. This list attempts to make note of those people, though not all contributors are listed. In no particular order:

- Nikto 2 Testing: Paul Woroshow, Mark G. Spencer, Michel Arboi, Jericho, rfp

- Jericho (attrition.org/OSVDB/OSF). Support/ideas/tests/corrections/spam and help matching OSVDB IDs to tests.

- rfp (wiretrip.net). LibWhisker and continuing support.

- Erik Cabetas for many updates and fixes.

- Jake Kouns (OSVDB/OSF).

- Jabra (spl0it.org) for XML DTD, XML templates and supporting code.

- Stephen Valdez. Extensive testing. We all miss you.

- S Saady. Extensive testing.

- Zeno (cgisecurity.com). Nikto mirroring.

- P Eronen (nixu.com). Provided many code fixes.

- M Arboi. Great support by writing the code to make Nikto work within Nessus, as well as bug reports.

- T Seyrat. Maintains Nikto for the Debian releases.

- J DePriest. Ideas/fixes.

- P Woroshow. Ideas/fixes.

- fr0stman. Tests.

- H Heimann. Tests.

- Xiola (xiola.net). Web design and more.

- Ryan Dewhurst. Domain guessing code.

This document is © 2009 CIRT, Inc. and may not be reused without permission.