Introduction
Nikto is a popular open-source web server scanner that performs comprehensive tests against web servers for multiple items, including over 6700 potentially dangerous files/programs, checks for outdated versions of over 1250 servers, and version-specific problems on over 270 servers.
While Nikto can easily scan standard HTTP websites, scanning sites that use SSL/TLS (HTTPS) requires a specific option. In this lab, you will learn how to use Nikto to scan an SSL/TLS enabled website. We will use a locally hosted, secure web server for testing purposes. You will learn how to initiate an SSL scan, direct it to a specific port, and interpret the SSL-related information in the scan results.
Identify a target website using HTTPS
In this step, we will confirm that our target secure web server is running and accessible. The setup script for this lab has already started a simple Python web server that uses SSL/TLS. It is listening on localhost at port 4433.
To verify that the server is running, we can use the curl command. Since our server uses a self-signed certificate (which is not trusted by a Certificate Authority), we must use the -k or --insecure flag with curl to tell it to proceed despite the untrusted certificate.
Execute the following command in your terminal:
curl -k https://localhost:4433
You should see the HTML content of the server's main page, which confirms the server is active and serving content over HTTPS.
<html><body><h1>Welcome to the Secure Test Server!</h1></body></html>
Now that we have confirmed our target is operational, we can proceed with scanning it.
Use the -ssl flag to enable SSL mode
In this step, we'll learn why the -ssl flag is essential for scanning HTTPS sites. By default, Nikto attempts to scan targets over standard HTTP on port 80. If you point it to a port that expects an SSL/TLS connection without specifying to use SSL, the scan will fail because the initial communication handshake is incorrect.
Let's try running Nikto against our secure server on port 4433 without the -ssl flag to observe this behavior.
nikto -h localhost -p 4433
You will see an output indicating that no web server was found, or you might see an error message. This is because Nikto is trying to speak HTTP to a port that is listening for HTTPS.
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 127.0.0.1
+ Target Hostname: localhost
+ Target Port: 4433
---------------------------------------------------------------------------
+ Start Time: ...
---------------------------------------------------------------------------
+ ERROR: No web server found on localhost:4433
---------------------------------------------------------------------------
+ 0 host(s) tested
This demonstrates the need for the -ssl flag. This flag explicitly tells Nikto to wrap its web requests in an SSL/TLS layer, enabling it to communicate with secure servers. In the next step, we will use this flag to perform a proper scan.
Run the scan against the HTTPS target
In this step, you will perform a proper vulnerability scan against our secure web server using the -ssl flag. By combining the -h (host), -p (port), and -ssl flags, we can instruct Nikto to connect to the correct host and port, and to use an SSL/TLS connection.
Run the following command in your terminal to initiate the scan:
nikto -h localhost -p 4433 -ssl
Nikto will now start the scan. Because our server is using a self-signed certificate, Nikto will likely display a warning about the certificate issuer not being trusted, which is expected in this case. The scan will then proceed.
The output will look similar to this:
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 127.0.0.1
+ Target Hostname: localhost
+ Target Port: 4433
+ SSL Info: Self-signed certificate.
+ Start Time: ...
---------------------------------------------------------------------------
+ Server: SimpleHTTP/0.6 Python/3.10.12
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
...
+ 1 host(s) tested
You have now successfully scanned an SSL-enabled website with Nikto.
Observe SSL-specific checks in the output
In this step, we will analyze the output from the previous scan to identify information that is specific to SSL/TLS connections. When the -ssl flag is used, Nikto not only scans for general web vulnerabilities but also provides details about the server's SSL/TLS certificate and configuration.
If you scroll back through the output of the command from the previous step, you will find information related to the SSL certificate. To isolate this information, you can re-run the scan and use grep to filter the output. Let's search for the certificate's "Subject" line.
nikto -h localhost -p 4433 -ssl | grep "Subject"
This command will run the scan again, but only display lines containing the word "Subject".
+ Subject: C=US, ST=California, L=MountainView, O=LabEx, OU=IT, CN=localhost
This line shows the details embedded in the server's SSL certificate, such as the Country (C), State (ST), and Common Name (CN). This information can be useful for verifying the identity of a server during a security assessment. Nikto also checks for cipher information and other SSL-related vulnerabilities, providing a more complete picture of the secure server's configuration.
Force SSL mode on a non-standard port
In this step, we will explore how to "force" Nikto to use SSL on any port, even one that typically handles unencrypted traffic. This is useful for identifying misconfigured services that might be running HTTPS on an unusual port, like 8080.
First, we need to stop the existing server and start a new one on port 8080.
## Stop the previous server
pkill -f "python3 /home/labex/project/https_server/server.py"
## Create a new server configuration for port 8080
cat << EOF > /home/labex/project/https_server/server_8080.py
import http.server
import ssl
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
server_address = ('0.0.0.0', 8080)
httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket,
server_side=True,
certfile='cert.pem',
keyfile='key.pem',
ssl_version=ssl.PROTOCOL_TLS)
httpd.serve_forever()
EOF
## Start the new server in the background and wait a moment
python3 /home/labex/project/https_server/server_8080.py &> /dev/null &
sleep 3
Now, our secure server is running on port 8080. Without the -ssl flag, Nikto would assume this is a standard HTTP port. By including -ssl, we force it to initiate a TLS handshake.
Run the scan against port 8080:
nikto -h localhost -p 8080 -ssl
The output will be similar to the previous scans, confirming that Nikto successfully connected using SSL/TLS to a non-standard port and performed its tests.
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 127.0.0.1
+ Target Hostname: localhost
+ Target Port: 8080
+ SSL Info: Self-signed certificate.
...
This confirms your ability to use Nikto to scan for SSL/TLS services on any arbitrary port.
Summary
In this lab, you have learned the fundamental process of scanning SSL/TLS enabled websites using Nikto. You started by identifying and verifying a target HTTPS server. You then saw firsthand why simply pointing Nikto at an HTTPS port fails and learned that the -ssl flag is required to enable SSL/TLS communication.
You successfully executed a scan against a secure server, analyzed the output for SSL-specific information like certificate details, and finally, learned how to force SSL mode on a non-standard port. This skill is crucial for conducting thorough security assessments on modern web applications that rely on HTTPS for security.


