4.3. Nikto Under the HoodThis 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.
4.3.1. Nikto's Program FlowAt 200 lines of code the Nikto.pl 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 LW.pm and nikto_core.plugin available to the rest of nikto.pl 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 InterfaceNikto'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. |