<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY description SYSTEM "sections/description.xml">
<!ENTITY options SYSTEM "sections/options.xml">
]>
<book>
  <title>Nikto v2.1.5 - The Manual</title>

  <chapter id="introduction">
    <title>Introduction</title>

    <section>
      <title>Overview</title>

      <para>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.</para>
    </section>

    <section>
      <title>Description</title>

      &description;

      <para>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 <ulink
      url="http://www.blather.net/blather/2005/10/klaatu_barada_nikto_the_day_th.html">http://www.blather.net/blather/2005/10/klaatu_barada_nikto_the_day_th.html</ulink></para>
    </section>

    <section>
      <title>Advanced Error Detection Logic</title>

      <para>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.</para>

      <para>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.</para>

      <para>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.</para>

      <para>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.</para>

      <para>This feature is performed by making several requests for
      non-existent pages of various filetypes. This may add up to a thousand
      requests to the remote server during the lifetime of the scan. This may
      not be desireable over slow connection and can be disabled with the
      <parameter>-no404</parameter> option.</para>
    </section>

    <section>
      <title>History</title>

      <para>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.</para>

      <para>In 2008, David Lodge officially joined the development team and
      assumed leadership of Nikto while Chris Sullo pursued another
      committment. In 2009, Sullo rejoined the project.</para>
    </section>
  </chapter>

  <chapter id="installation">
    <title>Installation</title>

    <section>
      <title>Requirements</title>

      <para>Any system which supports a basic Perl installation should allow
      Nikto to run. It has been extensively tested on:</para>

      <itemizedlist>
        <listitem>
          <para>Windows (using ActiveState Perl and Strawberry Perl). Some
          POSIX features, such as interactive commands may not work under
          Windows.</para>
        </listitem>

        <listitem>
          <para>Mac OSX</para>
        </listitem>

        <listitem>
          <para>Various Linux and Unix installations (including RedHat,
          Solaris, Debian, Ubuntu, BackTrack, etc.)</para>
        </listitem>
      </itemizedlist>

      <para>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). As of Nikto version 2.1.5, the included
      LibWhisker differs (slightly) from the standard LibWhisker 2.5
      distribution.</para>

      <para>For SSL support the Net::SSLeay Perl module must be installed.
      Windows support for SSL is dependent on the installation package, but is
      rumored to exist for ActiveState's Perl.</para>

      <para>For support for logging to Metasploit, the RPC::XML and
      RPC::XML::Client modules must be installed. Nikto will operate without
      these modules, but the functionality will not be available.</para>

      <itemizedlist>
        <listitem>
          <para>Perl: <ulink
          url="http://www.cpan.org/">http://www.cpan.org/</ulink></para>
        </listitem>

        <listitem>
          <para>LibWhisker: <ulink
          url="http://www.wiretrip.net/">http://www.wiretrip.net/</ulink></para>
        </listitem>

        <listitem>
          <para>ActiveState Perl: <ulink
          url="http://www.activestate.com/">http://www.activestate.com/</ulink></para>
        </listitem>

        <listitem>
          <para>OpenSSL: <ulink
          url="http://www.openssl.org/">http://www.openssl.org/</ulink></para>
        </listitem>

        <listitem>
          <para>Perl modules RPC::XML::Client and RPC::XML for Metasploit
          logging integration</para>
        </listitem>

        <listitem>
          <para>For convenience, the JSON::PP module is included in the
          distribution. This is used for saving requests and responses in a
          parseable format.</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Install</title>

      <para>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.</para>

      <para>Unpack the download file:</para>

      <screen>tar -xvfz nikto-current.tar.gz</screen>

      <para>Assuming a standard OS/Perl installation, Nikto should now be
      usable. See Chapter 4 (Options) or Chapter 8 (Troubleshooting) for
      further configuration information.</para>
    </section>
  </chapter>

  <chapter id="usage">
    <title>Usage</title>

    <section>
      <title>Basic Testing</title>

      <para>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
      <parameter>-h</parameter> (<parameter>-host</parameter>) option. This
      will scan the IP 192.168.0.1 on TCP port 80:</para>

      <screen>perl nikto.pl -h 192.168.0.1</screen>

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

      <screen>perl nikto.pl -h 192.168.0.1 -p 443</screen>

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

      <screen>perl nikto.pl -h https://192.168.0.1:443/</screen>

      <para>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 <parameter>-s</parameter>
      (<parameter>-ssl</parameter>) will speed up the test.</para>

      <screen>perl nikto.pl -h 192.168.0.1 -p 443 -ssl</screen>

      <note>
        <para>The <parameter>-mutate</parameter> and
        <parameter>-mutate-options</parameter> parameters have been deprecated
        in nikto 2.1.2. Plugin selections, using the
        <parameter>-Plugin</parameter> parameter, should be used instead.
        Nikto will automagically turn a mutate option into the appropriate
        selection string.</para>
      </note>

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

      <screen>perl nikto.pl -h 192.168.0.1 -mutate 3 -mutate-options user-list.txt</screen>
    </section>

    <section>
      <title>Multiple Port Testing</title>

      <para>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 <parameter>-p</parameter> (<parameter>-port</parameter>) 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.</para>

      <screen>perl nikto.pl -h 192.168.0.1 -p 80,88,443</screen>
    </section>

    <section>
      <title>Multiple Host Testing</title>

      <para>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 <parameter>-h</parameter> (<parameter>-host</parameter>) 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.</para>

      <para>This is an example of a valid hosts file:</para>

      <example>
        <title>Valid Hosts File</title>

        <programlisting>192.168.0.1:80
http://192.168.0.1:8080/
192.168.0.3</programlisting>
      </example>

      <note>
        <para>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</para>
      </note>

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

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

      <screen>nmap -p80 192.168.0.0/24 -oG - | nikto.pl -h -</screen>
    </section>

    <section>
      <title>Using a Proxy</title>

      <para>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.
      There are two ways to use a proxy with Nikto, via the nikto.conf file or
      directly on the command line.</para>

      <para>To use the nikto.conf file, set the <varname>PROXY*</varname>
      variables (as described in section 4), and then execute Nikto with the
      -useproxy option. All connections will be relayed through the HTTP proxy
      specified in the configuration file.</para>

      <screen>perl nikto.pl -h localhost -p 80 -useproxy</screen>

      <para>To set the proxy on the command line, use the -useproxy option
      with the proxy set as the argument, for example:</para>

      <screen>./nikto.pl -h localhost -useproxy http://localhost:8080/</screen>
    </section>

    <section>
      <title>Updating</title>

      <para>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.</para>

      <note>
        <para>The -update option cannot be abbreviated.</para>
      </note>

      <screen>perl nikto.pl -update</screen>

      <para>If updates are required, you will see a list of the files
      downloaded:</para>

      <screen>
 perl nikto.pl -update
 + Retrieving 'nikto_core.plugin'
 + Retrieving 'CHANGES.txt'
      </screen>

      <para>Updates may also be manually downloaded from the appropriate
      version's directory at <ulink
      url="http://cirt.net/nikto/UPDATES/">http://cirt.net/nikto/UPDATES/</ulink>.
      Plugin and database files from the server should replace those in the
      'plugins' or 'databases' directories.</para>
    </section>

    <section>
      <title>Integration with Nessus</title>

      <para>Nessus (<ulink
      url="http://www.nessus.org/">http://www.nessus.org/nessus/</ulink>) can
      be configured to automatically launch Nikto when it finds a web server.
      Ensure Nikto works properly, that nikto.pl is in the PATH, and that
      nikto.nasl is present in the Nessus install. Run 'nessusd -R' and then
      restart nessusd.</para>

      <para>See <ulink
      url="http://blog.tenablesecurity.com/2008/09/using-nessus-to.html">http://blog.tenablesecurity.com/2008/09/using-nessus-to.html</ulink>
      for detailed instructions.</para>
    </section>

    <section>
      <title>Interactive Features</title>

      <para>Nikto contains several options which can be changed during an
      active scan, provided it is running on a system which provides POSIX
      support, which includes *nix and some other operating systems. On
      systems without POSIX support, these features will be silently
      disabled.</para>

      <para>During an active scan, pressing any of the keys below will turn on
      or off the listed feature or perform the listed action. Note that these
      are case sensitive.</para>

      <itemizedlist>
        <listitem>
          <para>SPACE - Report current scan status</para>
        </listitem>

        <listitem>
          <para>v - Turn verbose mode on/off</para>
        </listitem>

        <listitem>
          <para>d - Turn debug mode on/off</para>
        </listitem>

        <listitem>
          <para>e - Turn error reporting on/off</para>
        </listitem>

        <listitem>
          <para>p - Turn progress reporting on/off</para>
        </listitem>

        <listitem>
          <para>r - Turn redirect display on/off</para>
        </listitem>

        <listitem>
          <para>c - Turn cookie display on/off</para>
        </listitem>

        <listitem>
          <para>o - Turn OK display on/off</para>
        </listitem>

        <listitem>
          <para>a - Turn auth display on/off</para>
        </listitem>

        <listitem>
          <para>q - Quit</para>
        </listitem>

        <listitem>
          <para>N - Next host</para>
        </listitem>

        <listitem>
          <para>P - Pause</para>
        </listitem>
      </itemizedlist>
    </section>
  </chapter>

  <chapter id="options">
    <title>Command Line Options</title>

    <section>
      <title>All Options</title>

      &options;
    </section>

    <section>
      <title>Mutation Techniques</title>

      <note>
        <para>The <parameter>-mutate</parameter> and
        <parameter>-mutate-options</parameter> parameters have been deprecated
        in nikto 2.1.2. Plugin selections, using the
        <parameter>-Plugin</parameter> parameter, should be used instead.
        Nikto will automagically turn a mutate option into the appropriate
        selection string.</para>
      </note>

      <para>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.</para>

      <orderedlist>
        <listitem>
          <para>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.</para>
        </listitem>

        <listitem>
          <para>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.</para>
        </listitem>

        <listitem>
          <para>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
          <parameter>-mutate-options</parameter> parameter.</para>
        </listitem>

        <listitem>
          <para>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 <parameter>-mutate-options</parameter> parameter.</para>
        </listitem>

        <listitem>
          <para>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.</para>
        </listitem>

        <listitem>
          <para>Attempt to brute directory names. This is the only mutate
          option that requires a file to be passed in the
          <parameter>-mutate-options</parameter> 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.</para>
        </listitem>
      </orderedlist>
    </section>

    <section>
      <title>Display</title>

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

      <itemizedlist>
        <listitem>
          <para>1 - Show redirects. This will display all requests which
          elicit a "redirect" response from the server.</para>
        </listitem>

        <listitem>
          <para>2 - Show cookies received. This will display all cookies that
          were sent by the remote host.</para>
        </listitem>

        <listitem>
          <para>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.</para>
        </listitem>

        <listitem>
          <para>4 - Show URLs which require authentication. This will show all
          responses which elicit an "authorization required" header.</para>
        </listitem>

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

        <listitem>
          <para>E - Display all HTTP errors. Show details for any HTTP error
          encountered.</para>
        </listitem>

        <listitem>
          <para>P - Print progress to STDOUT. Show status report to STDOUT
          during testing (interval set in nikto.conf).</para>
        </listitem>

        <listitem>
          <para>V - Verbose Output. Show verbose output, which typically shows
          where Nikto is during program execution.</para>
        </listitem>

        <listitem>
          <para>E - Error Output. Display all HTTP and communications errors,
          which show a lot of output on some servers.</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Scan Tuning</title>

      <para>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.</para>

      <para>Test types can be controlled at an individual level by specifying
      their identifier to the <parameter>-T</parameter>
      (<parameter>-Tuning</parameter>) option. In the default mode, if
      <parameter>-T</parameter> 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:</para>

      <screen>perl nikto.pl -h 192.168.0.1 -T 58</screen>

      <para>If an "x" is passed to <parameter>-T</parameter> 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:</para>

      <screen>perl nikto.pl -h 192.168.0.1 -T 58xb</screen>

      <para>The valid tuning options are:</para>

      <itemizedlist>
        <listitem>
          <para>0 - File Upload. Exploits which allow a file to be uploaded to
          the target server.</para>
        </listitem>

        <listitem>
          <para>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.).</para>
        </listitem>

        <listitem>
          <para>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.</para>
        </listitem>

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

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

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

        <listitem>
          <para>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).</para>
        </listitem>

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

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

        <listitem>
          <para>9 - SQL Injection. Any type of attack which allows SQL to be
          executed against a database.</para>
        </listitem>

        <listitem>
          <para>a - Authentication Bypass. Allows client to access a resource
          it should not be allowed to access.</para>
        </listitem>

        <listitem>
          <para>b - Software Identification. Installed software or program
          could be positively identified.</para>
        </listitem>

        <listitem>
          <para>c - Remote source inclusion. Software allows remote inclusion
          of source code.</para>
        </listitem>

        <listitem>
          <para>d - WebServices. HTTP WebService/API locations.</para>
        </listitem>

        <listitem>
          <para>x - Reverse Tuning Options. Perform exclusion of the specified
          tuning type instead of inclusion of the specified tuning
          type.</para>
        </listitem>
      </itemizedlist>
    </section>

    <section>
      <title>Replay Saved Requests</title>

      <para>When using the Save functionality (-Save), findings requests are
      saved in text files. While these files contain human readable text, they
      also contain JSON representations of the request and response. This JSON
      request can be replayed by using the "replay.pl" script.</para>

      <para>The replay.pl reads and parses a saved file via the -file option,
      and can optionally run the request through a proxy, such as Burp. This
      will allow further exploration of vulnerabilities in a program better
      suited to replay and resend attacks.</para>

      <screen>

$ ./replay -file savedir_host_80_2012-09-11-00-07-42/host_80_2012-09-11_002114.txt -proxy localhost:8080
--------------------------------------------  Info
Request to:     http://host:80/manual/
Test ID:        002114
OSVDB ID:       3092
Message:        OSVDB-3092: /manual/: Web server manual found.
--------------------------------------------  Response
date: Tue, 11 Sep 2012 04:14:20 GMT
server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.10 with Suhosin-Patch
content-location: index.html.en
vary: negotiate,accept-language,accept-charset
tcn: choice
last-modified: Tue, 06 Sep 2011 02:41:54 GMT
etag: "15eb9df-1f07-4ac3cc53d8080;15eb9dd-32b-4ac3cc53d8080"
accept-ranges: bytes
content-length: 7943
keep-alive: timeout=5, max=100
connection: Keep-Alive
content-type: text/html
content-language: en

&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"&gt;&lt;head&gt;&lt;!--
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
              This file is generated from xml source: DO NOT EDIT
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      --&gt;
&lt;title&gt;Apache HTTP Server Version 2.2
Documentation - Apache HTTP Server&lt;/title&gt;
...

</screen>
    </section>

    <section>
      <title>Plugin selection</title>

      <para>From Nikto 2.1.2 plugins can be selected on an individual basis
      and may have parameters passed to them.</para>

      <para>A plugin selection string may be passed on the command line
      through the <parameter>-Plugin</parameter> parameter. It consists of a
      semi-colon separated list of plugin names with option parameters placed
      in brackets. In simple form a plugin statement is like:</para>

      <blockquote>
        <para><parameter>plugin-name</parameter><optional>(<parameter>parameter
        name</parameter><optional>:<parameter>parameter value</parameter>
        </optional><optional>,<parameter>other
        parameters</parameter></optional> )</optional></para>
      </blockquote>

      <para>For example we can do:</para>

      <screen>tests(report:500,verbose)</screen>

      <para>Which will set the parameters report to a value of 500 and verbose
      to a value of 1. The parameters and plugin names can be found be
      running:</para>

      <screen>./nikto.pl -list-plugins</screen>

      <para>This also means that we deprecate the mutate options and replace
      them with parameters passed to plugins, so the mutate options now
      internally translate to:</para>

      <orderedlist>
        <listitem>
          <para>tests(all)</para>
        </listitem>

        <listitem>
          <para>tests(passfiles)</para>
        </listitem>

        <listitem>
          <para>apacheusers(enumerate,home[,dictionary:dict.txt])</para>
        </listitem>

        <listitem>
          <para>apacheusers(enumerate,cgiwrap[,dictionary:dict.txt])</para>
        </listitem>

        <listitem>
          <para>subdomain</para>
        </listitem>

        <listitem>
          <para>dictionary(dictionary:dict.txt)</para>
        </listitem>
      </orderedlist>

      <para>Macros for commonly run plugin sets can also be defined in
      nikto.conf, the default ones are:</para>

      <screen>@@MUTATE=dictionary;subdomain
@@DEFAULT=@@ALL;-@@MUTATE;tests(report:500)</screen>

      <para>These are expanded by using -list-plugins and can be overridden
      through -Plugins.</para>

      <para>Altogether this can allow a customised set of plugins that may
      need to be run for a specific circumstance. For example if a normal test
      bought up that the server was vulnerable to the apache Expect header XSS
      attack and we want to run a test just to see that it is vulnerable by
      adding debugging, we can run:</para>

      <screen>nikto.pl -host target.txt -Plugins "apache_expect_xss(verbose,debug)"</screen>

      <para>And then manually check the output to see whether it was truly
      vulnerable.</para>

      <para>It should be noted that reports are also plugins, so if you need
      to customize the plugin string and want an output, include the report
      plugin:</para>

      <screen>nikto.pl -host targets.txt -Plugins "apacheusers(enumerate,dictionary:users.txt);report_xml" -output apacheusers.xml</screen>
    </section>
  </chapter>

  <chapter id="configuration">
    <title>Configuration Files</title>

    <section>
      <title>Location</title>

      <para>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.</para>

      <para>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:</para>

      <orderedlist>
        <listitem>
          <para>/etc/nikto.conf (this may be altered depending on
          platform)</para>
        </listitem>

        <listitem>
          <para>$HOME/nikto.conf</para>
        </listitem>

        <listitem>
          <para>nikto.conf</para>
        </listitem>
      </orderedlist>
    </section>

    <section>
      <title>Format</title>

      <para>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.</para>
    </section>

    <section>
      <title>Variables</title>

      <para>The following variables may be set within the configuration
      file:</para>

      <variablelist>
        <varlistentry>
          <term><varname>CLIOPTS</varname></term>

          <listitem>
            <para>Default options that should always be passed to the command
            line. For example:</para>

            <screen>CLIOPTS=-output results.txt -Format text</screen>

            <para>Default Setting</para>

            <screen>CLIOPTS=</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>NIKTODTD</varname></term>

          <listitem>
            <para>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.</para>

            <para>Default Setting</para>

            <screen>NIKTODTD=docs/nikto.dtd</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>RFIURL</varname></term>

          <listitem>
            <para>Full URL to an file for remote file inclusion. This file
            should contain a call to phpinfo(), as Nikto will look for the
            output of that command to determine that the RFI succeeded. You
            may use the default cirt.net file, but please keep in mind there
            must be connectivity from the target server to cirt.net, it's
            subject to cirt.net's availability, and successful requests will
            be logged (by Apache). We recommend you use your own.</para>

            <para>Default Setting</para>

            <screen>RFIURL=http://cirt.net/rfiinc.txt?</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>SKIPPORTS</varname></term>

          <listitem>
            <para>This configuration item defines ports that would never be
            scanned by Nikto.</para>

            <para>Default Setting</para>

            <screen>SKIPPORTS=21 111</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>SKIPIDS</varname></term>

          <listitem>
            <note>
              <para>Note, this filter only applies to tests in the
              <filename>db_tests</filename> database</para>
            </note>

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

            <screen>SKIPIDS=000045 000345</screen>

            <para>Default Setting</para>

            <screen>SKIPIDS=</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>DEFAULTHTTPVER</varname></term>

          <listitem>
            <para>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.</para>

            <para>Default Setting</para>

            <screen>DEFAULTHTTPVER=1.0</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>UPDATES</varname></term>

          <listitem>
            <para>If the outdated Nikto plugin sees a web server it doesn't
            know of, or a version that is later than that defined in
            <filename>db_outdated</filename>, 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.</para>

            <para>This item can be set to one of the below values:</para>

            <blockquote>
              <variablelist>
                <varlistentry>
                  <term><varname>UPDATES=yes</varname></term>

                  <listitem>
                    <para>Display each submission and ask for permission
                    before it is sent</para>
                  </listitem>
                </varlistentry>

                <varlistentry>
                  <term><varname>UPDATES=no</varname></term>

                  <listitem>
                    <para>Do not send any data back to cirt.net</para>
                  </listitem>
                </varlistentry>

                <varlistentry>
                  <term><varname>UPDATES=auto</varname></term>

                  <listitem>
                    <para>Send data back to cirt.net with no prompting</para>
                  </listitem>
                </varlistentry>
              </variablelist>
            </blockquote>

            <para>Default Setting</para>

            <screen>UPDATES=yes</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>LW_SSL_ENGINE</varname></term>

          <listitem>
            <para>Force LibWhisker to use the specified SSL library instead of
            the default select (Net::SSLeay, if available).</para>

            <para>This item can be set to one of the below values:</para>

            <blockquote>
              <variablelist>
                <varlistentry>
                  <term><varname>LW_SSL_ENGINE=auto</varname></term>

                  <listitem>
                    <para>use auto-selection</para>
                  </listitem>
                </varlistentry>

                <varlistentry>
                  <term><varname>LW_SSL_ENGINE=SSL</varname></term>

                  <listitem>
                    <para>use Net::SSL</para>
                  </listitem>
                </varlistentry>

                <varlistentry>
                  <term><varname>LW_SSL_ENGINE=SSLeay</varname></term>

                  <listitem>
                    <para>use Net::SSLeay</para>
                  </listitem>
                </varlistentry>
              </variablelist>
            </blockquote>

            <para>Default Setting</para>

            <screen>LW_SSL_ENGINE=auto</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>MAX_WARN</varname></term>

          <listitem>
            <para><emphasis>Unused</emphasis></para>

            <para>Produces a warning of a number of MOVED responses are
            retrieved. This is currently unused.</para>

            <para>Default Setting</para>

            <screen>MAX_WARN=20</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>PROMPTS</varname></term>

          <listitem>
            <para>Disables Nikto prompts if set to "no". This is currently
            only used to prompt for proxy authentication and sending
            updates.</para>

            <para>Default Setting</para>

            <screen>PROMPTS=</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>CIRT</varname></term>

          <listitem>
            <para>The IP address that Nikto will use to update the databases
            and plugins, or will send version information back to (as
            described in the <varname>UPDATES</varname> item).</para>

            <para>Default Setting</para>

            <screen>CIRT=174.142.17.165</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>PROXYHOST</varname></term>

          <term><varname>PROXYPORT</varname></term>

          <term><varname>PROXYUSER</varname></term>

          <term><varname>PROXYPASS</varname></term>

          <listitem>
            <para>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
            <parameter>-useproxy</parameter> switch to the command
            line.</para>

            <para>Default Setting</para>

            <screen>PROXYHOST=
PROXYPORT=
PROXYUSER=
PROXYPASS=</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>STATIC-COOKIE</varname></term>

          <listitem>
            <para>Adds the supplied cookie(s) to all requests made via Nikto.
            This is generally useful is an authentication cookie is required
            for a website. Separate cookies with a semi-colon, for
            example:</para>

            <screen>STATIC-COOKIE="cookie1"="cookie value";"cookie2"="cookie val"</screen>

            <para>Default Setting</para>

            <screen>STATIC-COOKIE=</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>CHECKMETHODS</varname></term>

          <listitem>
            <para>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.</para>

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

            <para>Default Setting</para>

            <screen>CHECKMETHODS=HEAD GET</screen>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><varname>EXECDIR</varname></term>

          <term><varname>PLUGINDIR</varname></term>

          <term><varname>TEMPLATEDIR</varname></term>

          <term><varname>DBDIR</varname></term>

          <term><varname>DOCDIR</varname></term>

          <listitem>
            <para>Defines where to find the location of Nikto, its plugins,
            databases, 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.</para>

            <para>Default Setting</para>

            <screen>EXECDIR=.
PLUGINDIR=EXECDIR/plugins
TEMPLATEDIR=EXECDIR/templates
DBDIR=EXECDIR/databases
DOCDIR=EXECDIR/docs</screen>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>
  </chapter>

  <chapter id="reports">
    <title>Output and Reports</title>

    <section>
      <title>Export Formats</title>

      <para>Nikto allows output to be saved in a variety of formats, including
      text, CSV, HTML, XML, NBE and exporting to metasploit. When using
      <parameter>-output</parameter>, an output format may be specified with
      <parameter>-Format</parameter>.</para>

      <para>If no <parameter>-Format</parameter> is specified, Nikto will try
      to guess the format from the file extension. If Nikto cannot guess the
      file format then output will only be sent to stdout.</para>

      <para>The DTD for the Nikto XML format can be found in the 'docs'
      directory (nikto.dtd).</para>
    </section>

    <section>
      <title>HTML and XML Customisation</title>

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

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

      <para>The copyright statements must not be removed from the
      <filename>htm_end.tmpl</filename> without placing them in another of the
      templates. It is a violation of the Nikto licence to remove these
      notices.</para>
    </section>
  </chapter>

  <chapter id="developing">
    <title>OSS Development</title>

    <section>
      <title>Open Source Contributions</title>

      <para>Nikto is an open source project licensed under the GNU GPL
      license. As such, code updates are welcomed and very much
      appreciated.</para>
    </section>

    <section>
      <title>Development Source</title>

      <para>The Nikto development source code is located in a GitHub
      repository which is publicly accessible at https://github.com/sullo/nikto. 
      To download the source code, install git and issue the following command:</para>

      <itemizedlist>
        <listitem>
          <para>git clone https://github.com/sullo/nikto</para>
        </listitem>
      </itemizedlist>

    </section>
  </chapter>

  <chapter id="expanding">
    <title>Test and Code Writing</title>

    <section>
      <title>Scan Database Field Values</title>

      <para>Though some checks can be found in other plugins, the
      <filename>db_tests</filename> contains the bulk of the web test
      information. Here is a description of the field values:</para>

      <table>
        <title>Scan Database Fields</title>

        <tgroup cols="2">
          <tbody>
            <row>
              <entry>Test ID</entry>

              <entry>Nikto test ID</entry>
            </row>

            <row>
              <entry>OSVDB-ID</entry>

              <entry>Corresponding vulnerability entry number for
              osvdb.org</entry>
            </row>

            <row>
              <entry>Server Type</entry>

              <entry>Generic server matching type</entry>
            </row>

            <row>
              <entry>URI</entry>

              <entry>URI to retrieve</entry>
            </row>

            <row>
              <entry>HTTP Method</entry>

              <entry>HTTP method to use for URI</entry>
            </row>

            <row>
              <entry>Match 1</entry>

              <entry>String or code to match for successful test</entry>
            </row>

            <row>
              <entry>Match 1 (Or)</entry>

              <entry>String or code to alternatively match for successful
              test</entry>
            </row>

            <row>
              <entry>Match1 (And)</entry>

              <entry>String or code to also match for successful test</entry>
            </row>

            <row>
              <entry>Fail 1</entry>

              <entry>String or code to match for test failure</entry>
            </row>

            <row>
              <entry>Fail 2</entry>

              <entry>String or code to match for test failure
              (alternative)</entry>
            </row>

            <row>
              <entry>Summary</entry>

              <entry>Summary message to report for successful test</entry>
            </row>

            <row>
              <entry>HTTP Data</entry>

              <entry>HTTP data to be sent during POST tests</entry>
            </row>

            <row>
              <entry>Headers</entry>

              <entry>Additional headers to send during test</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>

    <section>
      <title>User-Defined Tests</title>

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

      <para>For example, create the file
      <filename>databases/udb_tests</filename> and it will be loaded at the
      same time <filename>databases/db_tests</filename> is loaded. These files
      will also be checked for syntax when <parameter>-dbcheck</parameter> is
      used.</para>

      <para>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.</para>

      <para>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).</para>

      <para>Please help Nikto's continued success by sending test updates to
      <email>sullo@cirt.net</email>.</para>
    </section>

    <section>
      <title>Scan Database Syntax</title>

      <para>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:</para>

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

      <para>Here is an example test:</para>

      <screen>"120","3092","2","/manual/","GET","200","","","","","Web server manual","",""</screen>
    </section>

    <section>
      <title>Plugins</title>

      <para>Plugins allow other bits of code to hook into Nikto's processing
      and perform extra checks that cannot be achieved through the standard
      plugins.</para>

      <para>Plugins can use several hooks, these are:</para>

      <blockquote>
        <variablelist>
          <varlistentry>
            <term>Initialization (mandatory)</term>

            <listitem>
              <para>Plugin initialization 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.</para>

              <para>This is always called for every plugin, even if the plugin
              will not be used in the scan. Any database loading or variable
              setup should be deferred to the start hook.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>Start (optional)</term>

            <listitem>
              <para>The start hook is called after target enumeration, but
              before target scanning occcurs, and will only be called on
              plugins that are scheduled to be run. It will only execute
              once.</para>

              <para>This hook is normally used to load databases or to
              initialize memory for the plugin.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>Reconnaisance (optional)</term>

            <listitem>
              <para>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.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>Scan (optional)</term>

            <listitem>
              <para>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.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>Reporting (optional)</term>

            <listitem>
              <para>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.</para>

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

          <varlistentry>
            <term>Prefetch (optional)</term>

            <listitem>
              <para>The prefetch phase is called before every request to the
              server. It is passed a copy of the request hash and can amend it
              before it is sent to the server.</para>

              <para>This is normally used where standard data is needed for
              every request, for example, if authentication is needed.</para>

              <para>As this hook will be executed for every request made, for
              efficiency, the hook sub should be kept optimal. It is strongly
              advised that conditional execution (see below) is used to ensure
              that it is only run when needed.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>Postfetch (optional)</term>

            <listitem>
              <para>The postfetch phase is called after every request to the
              server. It is passed a copy of the response hash, so that it can
              check for content or header specific risks.</para>

              <para>As this hook will be executed for every request made, for
              efficiency, the hook sub should be kept optimal. It is strongly
              advised that conditional execution (see below) is used to ensure
              that it is only run when needed.</para>
            </listitem>
          </varlistentry>
        </variablelist>
      </blockquote>

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

      <para>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.</para>
    </section>

    <section>
      <title>Initialization Phase</title>

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

      <para>A perl sub must exist called
      <function><replaceable>filename</replaceable>_init</function>. The sub
      is passed no parameters and should return a hash reference to a hash
      that should contain the following entries:</para>

      <variablelist>
        <varlistentry>
          <term><structfield>name</structfield> (mandatory)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>full_name</structfield> (mandatory)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>author</structfield> (mandatory)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>description</structfield> (mandatory)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>copyright</structfield> (mandatory)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>hooks</structfield> (optional)</term>

          <listitem>
            <para>This should be a hash of hashes that contains information
            about the hooks that the plugin can respond to.</para>

            <para>Each key of the hooks element should be the name of the
            required hook with a hash value that details the information. The
            components of the hash should be:</para>

            <variablelist>
              <varlistentry>
                <term><structfield>method</structfield> (mandatory)</term>

                <listitem>
                  <para>This should be a reference to a function called for
                  the hook.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term><structfield>cond</structfield> (optional)</term>

                <listitem>
                  <para>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.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term><structfield>weight</structfield> (optional)</term>

                <listitem>
                  <para>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.</para>
                </listitem>
              </varlistentry>
            </variablelist>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>options</structfield> (optional)</term>

          <listitem>
            <para>This is a hash that contains help information about any
            parameters that can be passed to the plugin. The information will
            be shown if the <parameter>-list-plugins</parameter> parameter is
            used.</para>

            <para>Each key of the options element should be the name of the
            parameter, with a value of a string providing a brief description
            of the parameter.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_head</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_host_start</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_host_end</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_item</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_close</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_format</structfield> (optional)</term>

          <listitem>
            <para>This should describe the file format that the plugin
            handles. This is internally matched with the contents of the
            <parameter>-output</parameter> switch to reduce excessive calls to
            plugins.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term><structfield>report_weight</structfield> (optional)</term>

          <listitem>
            <para>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.</para>
          </listitem>
        </varlistentry>
      </variablelist>

      <example>
        <title>Example initialisation function</title>

        <programlisting>sub nikto_auth_init {
    my $id = { name             =&gt; 'auth',
               full_name        =&gt; 'Guess authentication',
               author           =&gt; 'Sullo/Deity',
               description      =&gt; 'Attempt to guess authentication realms',
               hooks            =&gt; {
                                    start =&gt; {
                                       method =&gt; \&amp;nikto_auth_load,
                                       weight =&gt; 1,
                                    },
                                    postfetch =&gt; {
                                       method =&gt; \&amp;nikto_auth,
                                       weight =&gt; 19,
                                       cond   =&gt; '$result-&gt;{whisker}-&gt;{code} eq 401',
                                    },
                                    prefetch =&gt; {
                                       method =&gt; \&amp;nikto_auth_pre,
                                       weight =&gt; 19,
                                    },
                                   },                   
               copyright        =&gt; "2010 CIRT Inc"
               };

    return $id;
}</programlisting>
      </example>
    </section>

    <section>
      <title>Start hook</title>

      <para>The Start hook is called between target and enumeration and the
      start of scanning. It will only ever be called once, no matter how many
      targets Nikto is being run against. It will only be run against plugins
      that will be executed later.</para>

      <para>This makes it the ideal place to set up any required variables,
      assign variables or load databases for the plugin to be used in response
      to later hooks.</para>

      <para>The start method is passed no parameters and should return
      nothing.</para>

      <funcsynopsis>
        <funcprototype>
          <funcdef>void
          <function><replaceable>start_method</replaceable></function></funcdef>

          <paramdef><parameter>void</parameter></paramdef>
        </funcprototype>
      </funcsynopsis>

      <section>
        <title>Reconnaisance Phase</title>

        <para>The reconnaisance phase is executed for each target at the start
        of each scan.</para>

        <para>Each reconnaisance method such expect to take a
        <varname>mark</varname> hash ref. It should return nothing.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
            <function><replaceable>recon_method</replaceable></function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>hashref <parameter>parameters</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>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.</para>

        <para>Example uses of the reconnaisance phase are to spider a site,
        check for known applications etc.</para>
      </section>

      <section>
        <title>Scan Phase</title>

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

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>void
            <function><replaceable>scan_method</replaceable></function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>hashref <parameter>parameters</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </section>

      <section>
        <title>Prefetch hook</title>

        <para>The prefetch hook is executed before any request is made to the
        target. It is designed to allow the plugin to alter the libwhisker
        hash before the request.</para>

        <para>In normal execution, the prefetch hook should not report
        vulnerabilities.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>hashref request, hashref response
            <function><replaceable>prefetch_method</replaceable></function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>hashref <parameter>parameters</parameter></paramdef>

            <paramdef>hashref <parameter>request</parameter></paramdef>

            <paramdef>hashref <parameter>result</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </section>

      <section>
        <title>Postfetch hook</title>

        <para>The postfetch hook is the executed after any request is made to
        the target. It is designed to allow the plugin to check for issues
        with the response, such as vulnerable headers or content.</para>

        <para>In normal execution, the postfetch hook should report any
        vulnerabilities that it finds.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>hashref request, hashref response
            <function><replaceable>postfetch_method</replaceable></function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>hashref <parameter>parameters</parameter></paramdef>

            <paramdef>hashref <parameter>request</parameter></paramdef>

            <paramdef>hashref <parameter>result</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>
      </section>

      <section>
        <title>Reporting Phase</title>

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

        <para>The hooks are:</para>

        <section>
          <title>Report Head</title>

          <para>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.</para>

          <funcsynopsis>
            <funcprototype>
              <funcdef>handle
              <function><replaceable>report_head</replaceable></function></funcdef>

              <paramdef>string <parameter>filename</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

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

          <para>The <parameter>handle</parameter> is a handle that will be
          passed to other reporting functions for this plugin so should be
          internally consistent.</para>
        </section>

        <section>
          <title>Report Host Start</title>

          <para>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.</para>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
              <function><replaceable>report_host_start</replaceable></function></funcdef>

              <paramdef>handle <parameter>rhandle</parameter></paramdef>

              <paramdef>hashref <parameter>mark</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <para>The <parameter>rhandle</parameter> parameter is the output of
          the plugin's Report Head function.</para>

          <para>The <parameter>mark</parameter> parameter is a hashref for the
          target information (described below).</para>
        </section>

        <section>
          <title>Report Host End</title>

          <para>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.</para>

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
              <function><replaceable>report_host_end</replaceable></function></funcdef>

              <paramdef>handle <parameter>rhandle</parameter></paramdef>

              <paramdef>hashref <parameter>mark</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <para>The <parameter>rhandle</parameter> parameter is the output of
          the plugin's Report Head function.</para>

          <para>The <parameter>mark</parameter> parameter is a hashref for the
          target information (described below).</para>
        </section>

        <section>
          <title>Report Item</title>

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

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
              <function><replaceable>report_item</replaceable></function></funcdef>

              <paramdef>handle <parameter>rhandle</parameter></paramdef>

              <paramdef>hashref <parameter>mark</parameter></paramdef>

              <paramdef>hashref <parameter>vulnerbility</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <para>The <parameter>rhandle</parameter> parameter is the output of
          the plugin's Report Head function.</para>

          <para>The <parameter>mark</parameter> parameter is a hashref for the
          target information (described below).</para>

          <para>The <parameter>vulnerability</parameter> parameter is a
          hashref for the vulnerability information (described below).</para>
        </section>

        <section>
          <title>Report Close</title>

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

          <funcsynopsis>
            <funcprototype>
              <funcdef>void
              <function><replaceable>report_close</replaceable></function></funcdef>

              <paramdef>handle <parameter>rhandle</parameter></paramdef>
            </funcprototype>
          </funcsynopsis>

          <para>The <parameter>rhandle</parameter> parameter is the output of
          the plugin's Report Head function.</para>
        </section>
      </section>

      <section>
        <title>Data Structures</title>

        <para>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.</para>

        <section>
          <title><structname>Mark</structname></title>

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

          <blockquote>
            <table>
              <title>Members of the <structname>Mark</structname>
              structure</title>

              <tgroup cols="2">
                <tbody>
                  <row>
                    <entry><structfield>ident</structfield></entry>

                    <entry>Host identifier, usually equivalent to what was
                    passed on the command line.</entry>
                  </row>

                  <row>
                    <entry><structfield>hostname</structfield></entry>

                    <entry>Host name of the target.</entry>
                  </row>

                  <row>
                    <entry><structfield>ip</structfield></entry>

                    <entry>IP address of the target.</entry>
                  </row>

                  <row>
                    <entry><structfield>port</structfield></entry>

                    <entry>TCP port of the target.</entry>
                  </row>

                  <row>
                    <entry><structfield>display_name</structfield></entry>

                    <entry>Either the hostname, or the IP address of the
                    target, dependant on whether a hostname has been
                    discovered.</entry>
                  </row>

                  <row>
                    <entry><structfield>ssl</structfield></entry>

                    <entry>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.</entry>
                  </row>

                  <row>
                    <entry><structfield>vhost</structfield></entry>

                    <entry>Virtual hostname to use for the target.</entry>
                  </row>

                  <row>
                    <entry><structfield>root</structfield></entry>

                    <entry>Root URI to use for the target.</entry>
                  </row>

                  <row>
                    <entry><structfield>banner</structfield></entry>

                    <entry>Banner of the target's web server.</entry>
                  </row>
                </tbody>
              </tgroup>
            </table>
          </blockquote>
        </section>

        <section>
          <title>Parameters</title>

          <para>The parameters hash contains all parameters that are passed
          directly to a plugin through one of the hooks.</para>

          <para>The hash has a key of the parameter name and a value of the
          passed parameter. Implementation and sanity checking of the values
          is left up to the plugin.</para>

          <para>If a parameter has not been set, it will not be in the hash.
          If it has been set to an undefined value, it will be set to the
          number 1 in the hash.</para>

          <para>Some parameters, such as <parameter>verbose</parameter> and
          <parameter>debug</parameter> will be automatically handled by the
          Nikto, though the parameters will still be included in the
          hash.</para>
        </section>

        <section>
          <title>Vulnerability</title>

          <para>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
          <function>add_vulnerability</function> method.</para>

          <blockquote>
            <table>
              <title>Members of the <structname>Vulnerability</structname>
              structure</title>

              <tgroup cols="2">
                <tbody>
                  <row>
                    <entry>mark</entry>

                    <entry>Hash ref to a mark data structure.</entry>
                  </row>

                  <row>
                    <entry>message</entry>

                    <entry>Message for the vulnerability.</entry>
                  </row>

                  <row>
                    <entry>nikto_id</entry>

                    <entry>Test ID (tid) of the vulnerability, this should be
                    a unique number which'll identify the
                    vulnerability.</entry>
                  </row>

                  <row>
                    <entry>osvdb</entry>

                    <entry>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.</entry>
                  </row>

                  <row>
                    <entry>method</entry>

                    <entry>HTTP method used to find the vulnerability.</entry>
                  </row>

                  <row>
                    <entry>uri</entry>

                    <entry>URI for the result.</entry>
                  </row>

                  <row>
                    <entry>result</entry>

                    <entry>Any HTTP data, excluding headers.</entry>
                  </row>
                </tbody>
              </tgroup>
            </table>
          </blockquote>
        </section>
      </section>

      <section>
        <title>Standard Methods</title>

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

        <para>For some methods, such as <function>add_vulnerability</function>
        which write to global variables, these <emphasis>must</emphasis> be
        the only interface to those global variables.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>array <function>change_variables</function></funcdef>

            <paramdef>string <parameter>line</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>int <function>is_404</function></funcdef>

            <paramdef>string <parameter>uri</parameter></paramdef>

            <paramdef>string <parameter>content</parameter></paramdef>

            <paramdef>string <parameter>HTTPcode</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>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.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>string <function>get_ext</function></funcdef>

            <paramdef>string <parameter>uri</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>string <function>date_disp</function></funcdef>

            <paramdef>void</paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>string <function>rm_active</function></funcdef>

            <paramdef>string <parameter>content</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>string <function>get_banner</function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>boolean <function>content_present</function></funcdef>

            <paramdef>string <parameter>HTTPcode</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>string HTTPCode, string content
            <function>nfetch</function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>string <parameter>uri</parameter></paramdef>

            <paramdef>string <parameter>method</parameter></paramdef>

            <paramdef>string <parameter>content</parameter></paramdef>

            <paramdef>hashref <parameter>headers</parameter></paramdef>

            <paramdef>hashref <parameter>flags</parameter></paramdef>

            <paramdef>string <parameter>testid</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>Makes a simple request through libwhisker with the passed
        parameters. nfetch is hook aware and will cause all requests to be
        passed through the prefetch and postfetch hooks.</para>

        <para>The <parameter>flags</parameter> hash is a selection of flags
        that may modify the behaviour of the request. The current flags are
        defined:</para>

        <blockquote>
          <table>
            <title>Members of the <structname>flags</structname>
            structure</title>

            <tgroup cols="2">
              <tbody>
                <row>
                  <entry><structfield>noclean</structfield></entry>

                  <entry>Tells nfetch not to perform sanity checks on the
                  structure. Normally requests will be checked to ensure that
                  a valid Host header is included and that the Content-Length
                  header matches the size of any content, setting this flag
                  prevents the checks</entry>
                </row>

                <row>
                  <entry><structfield>noprefetch</structfield></entry>

                  <entry>Tells nfetch not to run the prefetch hook.</entry>
                </row>

                <row>
                  <entry><structfield>nopostfetch</structfield></entry>

                  <entry>Tells nfetch not to run the postfetch hook.</entry>
                </row>

                <row>
                  <entry><structfield>noerror</structfield></entry>

                  <entry>Tells nfetch not to report error responses from the
                  request.</entry>
                </row>
              </tbody>
            </tgroup>
          </table>
        </blockquote>

        <funcsynopsis>
          <funcprototype>
            <funcdef>hashref <function>setup_hash</function></funcdef>

            <paramdef>hashref <parameter>requesthash</parameter></paramdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>string <function>char_escape</function></funcdef>

            <paramdef>string <parameter>line</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>Escapes any characters within line.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>array <function>parse_csv</function></funcdef>

            <paramdef>string <parameter>text</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>Breaks a line of CSV text into an array of items.</para>

        <funcsynopsis>
          <funcprototype>
            <funcdef>arrayref <function>init_db</function></funcdef>

            <paramdef>string <parameter>dbname</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>Initializes a database that is in <varname>PLUGINDIR</varname>
        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:</para>

        <screen>"nikto_id","md5hash","description"</screen>

        <para>This will result in an array of hashrefs with parameters:</para>

        <screen>array[0]-&gt;{nikto_id}
array[0]-&gt;{md5hash}
array[0]-&gt;{description}</screen>

        <funcsynopsis>
          <funcprototype>
            <funcdef>void <function>add_vulnerability</function></funcdef>

            <paramdef>hashref <parameter>mark</parameter></paramdef>

            <paramdef>string <parameter>message</parameter></paramdef>

            <paramdef>string <parameter>nikto_id</parameter></paramdef>

            <paramdef>string <parameter>osvdb</parameter></paramdef>

            <paramdef>string <parameter>method</parameter></paramdef>

            <paramdef>string <parameter>uri</parameter></paramdef>

            <paramdef>string <parameter>data</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

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

        <funcsynopsis>
          <funcprototype>
            <funcdef>void <function>nprint</function></funcdef>

            <paramdef>string <parameter>message</parameter></paramdef>

            <paramdef>string <parameter>display</parameter></paramdef>
          </funcprototype>
        </funcsynopsis>

        <para>Prints <parameter>message</parameter> to standard out.
        <parameter>Display</parameter> specifies a filter for the message,
        currently this can be "v" for verbose and "d" for debug output.</para>
      </section>

      <section>
        <title>Global Variables</title>

        <para>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.</para>

        <variablelist>
          <varlistentry>
            <term><varname>%TEMPLATES</varname> (read/write)</term>

            <listitem>
              <para>Hash to store the HTML and XML report templates.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%CONTENTSEARCH</varname> (read)</term>

            <listitem>
              <para>Hash to contain all the entries in db_content_search - a
              list of strings and related info to alert on from any request
              (regardless of test result).</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%CLI</varname> (read)</term>

            <listitem>
              <para>Hash of passed CLI parameters</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%VARIABLES</varname> (read) (write)</term>

            <listitem>
              <para>Hash of contents of the entries in db_variables. Plugins
              should only write to this hash in the reconnaisance
              phase.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%TESTS</varname> (read) (write)</term>

            <listitem>
              <para>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.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%NIKTO</varname> (read)</term>

            <listitem>
              <para>Hash which contains internal Nikto data, such as help for
              the command line parameters.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%CONFIGFILE</varname> (read)</term>

            <listitem>
              <para>Hash containing the data read from the configuration
              files.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%request</varname> (read) (write)
            (deprecated)</term>

            <term><varname>%result</varname> (read) (write)
            (deprecated)</term>

            <listitem>
              <para>Global libwhisker hash. This should not be used; nfetch or
              a local hash should be used.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%COUNTERS</varname> (read) (write)</term>

            <listitem>
              <para>Hash containing various global counters (e.g. number of
              requests)</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%db_extensions</varname> (read) (deprecated)</term>

            <listitem>
              <para>Hash containing a list of common extensions</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%FoF</varname> (read) (write)</term>

            <listitem>
              <para>Hash containing data for each extension and what the
              server produces if a request for a non-existent file is
              requested.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>%UPDATES</varname> (read) (write)</term>

            <listitem>
              <para>Hash containing any updates that need to be sent back to
              cirt.net</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>$DIV</varname> (read)</term>

            <listitem>
              <para>Divider mark for the items sent to standard out.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>@DBFILE</varname> (read)</term>

            <listitem>
              <para>Placeholder used to hold the contents of
              <filename>db_tests</filename>.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>$PROXYCHECKED</varname> (read) (deprecated)</term>

            <listitem>
              <para>Flag to see whether connection through the proxy has been
              checked.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>@RESULTS</varname> (read)</term>

            <listitem>
              <para>Array of reported vulnerabilities, should only be written
              to through <function>add_vulnerability.</function></para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>@PLUGINS</varname> (read)</term>

            <listitem>
              <para>Array of hashrefs for each plugin. Used internally to run
              plugins.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>@MARKS</varname> (read)</term>

            <listitem>
              <para>Array of marks to indicate each target.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term><varname>@REPORTS</varname> (read)</term>

            <listitem>
              <para>Ordered array that reporting plugins should be run in.
              Used for efficency on calling reporting plugins.</para>
            </listitem>
          </varlistentry>
        </variablelist>
      </section>
    </section>

    <section>
      <title>Test Identifiers</title>

      <para>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:</para>

      <blockquote>
        <table>
          <title>TID Scheme</title>

          <tgroup cols="2">
            <tbody>
              <row>
                <entry>000000</entry>

                <entry>db_tests</entry>
              </row>

              <row>
                <entry>400000</entry>

                <entry>user defined tests (<filename>udb*</filename>
                files)</entry>
              </row>

              <row>
                <entry>500000</entry>

                <entry>db_favicon</entry>
              </row>

              <row>
                <entry>600000</entry>

                <entry>db_outdated</entry>
              </row>

              <row>
                <entry>700000</entry>

                <entry>db_realms</entry>
              </row>

              <row>
                <entry>750000</entry>

                <entry>db_content_search</entry>
              </row>

              <row>
                <entry>800000</entry>

                <entry>db_server_msgs</entry>
              </row>

              <row>
                <entry>900000</entry>

                <entry>tests defined in code</entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </blockquote>

      <para>As much data as possible in the <varname>%TESTS</varname> 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
      <varname>%TESTS</varname> 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:</para>

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

    <section>
      <title>Code Copyrights</title>

      <para>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.</para>
    </section>
  </chapter>

  <chapter id="troubleshooting">
    <title>Troubleshooting</title>

    <section>
      <title>SOCKS Proxies</title>

      <para>Nikto does not currently support SOCKS proxies.</para>
    </section>

    <section>
      <title>Debugging</title>

      <para>The major route to debugging Nikto requests is to use the
      <parameter>-Display</parameter> 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.</para>
    </section>

    <section>
      <title>Assistance</title>

      <para>If you need assistance with development or running Nikto, the
      Nikto-discuss mailing list can be an excellent resource and is an easy
      way to contact the developers and other knowledgeable users. For more
      information on the maling list, including archives and subscription
      options, please see http://cirt.net/nikto-discuss.</para>
    </section>
  </chapter>

  <chapter id="licences">
    <title>Licenses</title>

    <section>
      <title>Nikto</title>

      <para>Nikto is licensed under the GNU General Public License (GPL), and
      copyrighted by CIRT, Inc.</para>
    </section>

    <section>
      <title>LibWhisker</title>

      <para>LibWhisker is licensed under the GNU General Public License (GPL),
      and Copyright (c) 2009, Jeff Forristal (wiretrip.net)</para>
    </section>

    <section>
      <title>Tests</title>

      <para>The web tests are licensed for use with Nikto only, and may not be
      reused without written consent from CIRT, Inc.</para>
    </section>
  </chapter>

  <chapter id="credits">
    <title>Credits</title>

    <section>
      <title>Nikto</title>

      <para>Nikto is written and maintained by Chris Sullo and David Lodge.
      LibWhisker is written and maintained by Jeff Forristal (Rain Forrest
      Puppy).</para>
    </section>

    <section>
      <title>Thanks</title>

      <para>Many people have provided feedback, fixes, and suggestions. This
      list is a feeble attempt to thank a few people, in no particular
      order:</para>

      <itemizedlist>
        <listitem>
          <para>Nikto 2 Testing: Paul Woroshow, Mark G. Spencer, Michel Arboi,
          Jericho, rfp.</para>
        </listitem>

        <listitem>
          <para>Jericho (attrition.org/OSVDB/OSF).
          Support/ideas/tests/corrections/spam and help matching OSVDB IDs to
          tests.</para>
        </listitem>

        <listitem>
          <para>rfp (wiretrip.net). LibWhisker and continuing support.</para>
        </listitem>

        <listitem>
          <para>Erik Cabetas for many updates and fixes.</para>
        </listitem>

        <listitem>
          <para>Jake Kouns (OSVDB/OSF).</para>
        </listitem>

        <listitem>
          <para>Jabra (spl0it.org) for XML DTD, XML templates and supporting
          code.</para>
        </listitem>

        <listitem>
          <para>Stephen Valdez for extensive testing and being a great
          guy.</para>
        </listitem>

        <listitem>
          <para>S Saady. Extensive testing.</para>
        </listitem>

        <listitem>
          <para>P Eronen (nixu.com). Provided many code fixes.</para>
        </listitem>

        <listitem>
          <para>M Arboi. Great support by writing the code to make Nikto work
          within Nessus, as well as bug reports.</para>
        </listitem>

        <listitem>
          <para>J DePriest. Ideas/fixes.</para>
        </listitem>

        <listitem>
          <para>P Woroshow. Ideas/fixes.</para>
        </listitem>

        <listitem>
          <para>fr0stman. Tests.</para>
        </listitem>

        <listitem>
          <para>H Heimann. Tests.</para>
        </listitem>

        <listitem>
          <para>Xiola (xiola.net). Web design and more.</para>
        </listitem>

        <listitem>
          <para>Ryan Dewhurst. Domain guessing code.</para>
        </listitem>

        <listitem>
          <para>Frank Breedijk. NBE exporter code.</para>
        </listitem>

        <listitem>
          <para>Sussurro. MSF exporter code.</para>
        </listitem>

        <listitem>
          <para>Joe Hart, Gavin Jones, Ed Williams (Dyn_llandeilo). Lots of
          suggestions and bug finding.</para>
        </listitem>
      </itemizedlist>

      <para>This document is © 2010 CIRT, Inc. and may not be reused without
      permission.</para>
    </section>
  </chapter>
</book>
