Team LiB
Previous Section Next Section

4.3. Nikto Under the Hood

This section traces the logic flow of the entire Nikto program, and discusses the routines available through nikto_core and LibWhisker. The Nikto program structure is modular. Most of Nikto's actual functionality lies within external plug-ins , which you can find in the plugins/ directory where the Nikto source code was uncompressed.

It is a good idea to browse the source of existing plug-ins to better understand how they work. Execute the following Linux command from the Nikto root directory to generate a tag file for the source tree:

find . -name "*.pl" -o -name "*.pm" -o -name "*.plugin" | xargs ctags 

4.3.1. Nikto's Program Flow

At 200 lines of code the file is relatively small. The following paragraphs briefly discuss what the program does on a macro level.

At the start of the program, you'll notice a series of global variables. To avoid namespace collisions, plug-in developers shouldn't use these variable names. Next, load_configs( ) parses the configuration file config.txt and initializes %CONFIG. Then the find_plugins( ) routine searches expected directories for the plug-in file, and sets appropriate values in %FILES. The nikto_core plug-in and LibWhisker are included with the require keyword, which makes all routines from and nikto_core.plugin available to the rest of as well as to its plug-ins. The general_config() routine parses the command-line options and sets %CLI appropriately. Next, LibWhisker's http_init_request( ) initializes LibWhisker's %request with default values.

The proxy_setup( ) function sets the appropriate values in %request, depending upon the proxy settings in the configuration file. The open_output() function opens a file handle for writing program output, only if an output file was specified on the command line. Next, set_targets( ) populates %TARGETS with the hostname or IP address of the target, along with specified ports. The load_scan_items( ) function loads the vulnerability checks found from servers.db, scan_database.db, and user_scan_database.db (if the file exists) into global arrays.

Finally, the main loop for the vulnerability checks is reached. For each item in %TARGETS the following actions are taken: first, dump_target_info( ) displays the target information. Next, check_responses( ) verifies that valid and invalid requests return the HTTP status codes 200 and 404. In addition, this function sets any HTTP Basic authentication credentials specified by the user. The check_cgi( ) function is called to verify the existence of common CGI directories (these can be set in the configuration file). The set_scan_items() function is called to process scan db arrays and to perform macro replacement on the checks. Next, run_plugins( ) is called to execute the plug-ins on the current target host and port. Finally, test_target( ) is called to perform the actual checks found in the scan db arrays.

4.3.2. Nikto's Plug-in Interface

Nikto's plug-in interface is relatively simple. The plug-ins are Perl programs executed by Nikto's run_plugins( ) function. For a plug-in to be executed correctly, it must meet three requirements. First, the plug-in file should use the naming convention nikto_foo.plugin, where foo is the name of the plug-in. Second, the plug-in should have an initialization routine with the same name as the plug-in. And third, the plug-in should have an entry in the file nikto_plugin_order.txt. This file controls which plug-ins run, and in what order. As an example, a line could be added to the file that simply states nikto_foo. This would call the routine nikto_foo( ) within the file nikto_foo.plugin. To keep the plug-ins portable, you should not use additional modules, but instead copy the needed code into the plug-in itself.

A side effect of the chosen plug-in execution method is that the plug-ins and Nikto share the global namespace. This is why you don't need use statements to access Nikto or LibWhisker routines. This simplifies the plug-ins. Plug-in developers should make sure their variable and routine names don't conflict with any of Nikto's global variables.

    Team LiB
    Previous Section Next Section