Master Nikto's full capability set — understanding what each finding category means, why HTTP security headers matter, how dangerous file discovery translates to exploitation, what false positives look like and how to filter them, and how defenders detect and harden against web scanning.
Nikto — Web Server Scanner
Nikto is an open source web server scanner that performs comprehensive tests against web servers for thousands of potentially dangerous files and programs, checks for outdated versions of over 1,200 servers, and identifies version-specific problems. It was written by Chris Sullo and is maintained as part of the Kali Linux toolset.
Unlike application-level scanners such as Burp Suite that intercept and manipulate web traffic, Nikto operates at the web server layer — checking for dangerous default files, misconfigured headers, exposed directories, and version-specific vulnerabilities in the server software itself. It is typically the second tool run after Nmap confirms a web server is present, providing a rapid surface-level assessment that guides deeper manual testing.
Nikto checks against a database of known issues. It probes for dangerous files, checks HTTP response headers, tests HTTP methods, and attempts to identify the server software and version. The findings it produces are best understood as a prioritised list of leads — each one deserves manual verification before being included in a report.
nikto -h http://target.com # basic scan nikto -h http://target.com -p 8080 # non-standard port nikto -h https://target.com -ssl # force HTTPS nikto -h http://target.com -o report.html -Format htm # save HTML report nikto -h http://target.com -Tuning 9 # SQL injection tests only nikto -h http://target.com -evasion 1 # random URL encoding (IDS evasion)
Imagine a building inspector hired to assess a commercial property. Rather than testing the structural integrity of every single beam, they work from a checklist of the most common code violations — they check every fire exit to ensure it opens, test that emergency lights work, verify that electrical panels are properly labelled, look for illegally stored hazardous materials in storage areas, and confirm that the basement drainage is properly connected. They're not doing a complete engineering survey; they're doing a rapid compliance scan against a known list of common failures. Each finding tells them where to look closer. Nikto is exactly this: a rapid checklist scan against a known database of web server failures, identifying which specific items need deeper investigation.
Nikto in Action
A standard Nikto scan against a web server returns a wealth of information about vulnerabilities and misconfigurations. Each line beginning with + is a finding.
nikto -h http://192.168.1.100 + Server: Apache/2.4.29 (Ubuntu) + The anti-clickjacking X-Frame-Options header is not present. + OSVDB-3092: /admin/: This might be interesting. + OSVDB-3268: /backup/: Directory indexing found. + OSVDB-3233: /icons/README: Apache default file found. + /phpinfo.php: PHP info file found. ← version + config exposed
Nikto flags absent security headers — each represents a risk that a browser-based attack could exploit against the application's users.
+ The X-Content-Type-Options header is not set. Risk: MIME sniffing attacks + The X-XSS-Protection header is not defined. Risk: Reflected XSS without browser protection + Strict-Transport-Security header not present. Risk: SSL stripping attacks possible
Nikto checks thousands of known dangerous paths — files left behind by developers, default installs, or backup processes that have no business being publicly accessible.
+ /config.php.bak: Backup configuration file found + /.git/HEAD: Git repository accessible + /wp-admin/: WordPress admin interface + /server-status: Apache server-status exposed # Each of these warrants immediate manual investigation
Not all Nikto findings carry equal risk. Effective triage — grouping findings by severity and impact — is the skill that separates a useful assessment from an overwhelming list of low-value alerts.
# Critical — verify immediately: + /phpinfo.php → exposes PHP config, server paths, env vars + /.git/HEAD → full source code extraction possible # High — investigate further: + /admin/ → may or may not require auth + /backup/ → check if files are readable # Informational — note for report, easy fix: + Missing headers → lower severity, quick remediation
What You Need to Know
Nikto Tuning — Targeting Specific Test Categories
The -Tuning flag controls which categories of tests Nikto runs. This is critical for professional engagements where a full scan might be too noisy or time-consuming, and where specific vulnerability classes are in scope. Running only the tests relevant to the current assessment also reduces false positives and makes output easier to triage.
| ID | Category | What It Checks | When to Use |
|---|---|---|---|
| 0 | File Upload | Forms and endpoints that accept file uploads — potential remote code execution paths | Web app assessments where file upload is present |
| 1 | Interesting File / Seen in Logs | Files commonly found in server logs, admin panels, backup paths | Initial recon — high signal-to-noise ratio |
| 2 | Misconfiguration / Default File | Default install files, test pages, server-status, server-info endpoints | Post-install hardening verification |
| 3 | Information Disclosure | Files that leak server info, PHPinfo, error messages with stack traces | All assessments — always worth running |
| 4 | Injection (XSS/Script/HTML) | Cross-site scripting entry points, HTML injection, script injection | Web application security assessments |
| 5 | Remote File Retrieval (inside web root) | Local file inclusion, path traversal within the web root | PHP applications, legacy web frameworks |
| 6 | Denial of Service | Requests that could cause service disruption — use with caution | Avoid in production; lab/staging only |
| 7 | Remote File Retrieval (outside web root) | Directory traversal and LFI outside the web root | Older web servers, CGI scripts |
| 8 | Command Execution / Remote Shell | CGI vulnerabilities, command injection entry points | Legacy servers with CGI, command injection testing |
| 9 | SQL Injection | SQL injection indicators in parameters, error messages, response patterns | Web app DB-backed assessments — complement with sqlmap |
| a | Authentication Bypass | Default credentials, authentication logic bypasses | Admin interface assessments |
| b | Software Identification | Identify CMS, framework, and software versions | Technology fingerprinting pass |
Combining tuning flags focuses Nikto on the highest-priority areas for a given assessment type, reducing runtime and output volume while covering the most relevant risk categories.
# Information gathering only (quietest, good starting point): nikto -h http://target.com -Tuning 123b # Web application assessment (XSS, SQLi, LFI): nikto -h http://target.com -Tuning 459 # Full assessment excluding DoS tests (safe for production): nikto -h http://target.com -Tuning 1234589ab # WordPress-specific — combine with wpscan for full coverage: nikto -h http://target.com -Tuning 12345b wpscan --url http://target.com --enumerate p,u,t
Security Headers — Why Each One Matters
HTTP security headers are server-sent instructions to the client's browser that control how it handles the page's content. Missing or misconfigured headers are among the most consistently reported web application findings — easy to detect, easy to fix, and significant in their absence because they represent entire classes of browser-based attacks left unmitigated.
Nikto checks for all of the headers below. Understanding what each header prevents — and what attack becomes possible without it — is necessary to explain findings at a professional level and is directly relevant to the CEH Web Application Hacking domain.
| Header | What It Prevents | Absent Risk | Severity |
|---|---|---|---|
| Content-Security-Policy | Instructs the browser which sources of scripts, styles, images, and frames are trusted. Blocks inline script execution and unauthorised external resources. | XSS attacks can inject and execute arbitrary JavaScript. Attackers can load external malicious scripts. Data exfiltration via script. | Critical |
| Strict-Transport-Security | Tells browsers to only connect over HTTPS — never downgrade to HTTP, even if the user types http://. Enforced for the specified max-age duration. | SSL stripping attacks intercept the initial HTTP request before the redirect to HTTPS, allowing man-in-the-middle interception of the session. | Critical |
| X-Frame-Options | Controls whether the page can be embedded in an iframe. DENY blocks all framing; SAMEORIGIN allows only same-site framing. | Clickjacking attacks: attacker embeds the page in an invisible iframe over a deceptive site, tricking users into clicking legitimate buttons unknowingly. | High |
| X-Content-Type-Options | nosniff directive prevents browsers from MIME-sniffing a response away from the declared Content-Type. | MIME confusion attacks: a file uploaded as "image/jpeg" but containing JavaScript code can be interpreted as script by a browser that sniffs the content type. | High |
| Referrer-Policy | Controls how much referrer information is included in requests. Prevents sensitive URL parameters from leaking to third-party resources on the page. | Session tokens, password reset tokens, or sensitive data in URL parameters can leak to analytics, advertising, or CDN providers via the Referer header. | Medium |
| Permissions-Policy | Controls which browser APIs the page can use — camera, microphone, geolocation, payment. Restricts what injected scripts can access even if CSP is bypassed. | Compromised page scripts or injected third-party code can access device APIs (camera, microphone) without explicit user permission prompts in some browser contexts. | Medium |
Imagine a prestigious nightclub that has a strict guest list policy. The CSP header is like that guest list — the server tells the browser "only scripts from these specific domains are allowed to run on this page." Without a CSP, the policy is equivalent to "anyone can come in, no ID required." An XSS attack is like a stranger walking in unchallenged and telling the bartender to charge everyone else's tabs to them. A strict CSP means that even if an attacker manages to inject a script tag into the page, the browser refuses to execute it because it's not on the approved list. The attack is contained at the browser level before it can do anything.
Exposed Files — From Discovery to Exploitation
Nikto's dangerous file checks are based on a database of paths that have historically been found to expose sensitive information or functionality. Understanding why each category is dangerous — what an attacker can actually do with the finding — is essential for prioritising remediation and explaining impact in a report.
When a .git directory is accessible from the web root, an attacker can reconstruct the entire source code repository — including files that were never meant to be deployed and commits that contained secrets before they were removed.
# Nikto finds /.git/HEAD — verify manually: curl http://target.com/.git/HEAD ref: refs/heads/main # Confirmed accessible. Download entire repo with git-dumper: git-dumper http://target.com/.git ./extracted_repo [-] Testing http://target.com/.git/HEAD [200] [-] Fetching .git/packed-refs ... [-] Fetching objects ... [-] Running git checkout . # Now search the extracted repo for secrets in commit history: cd extracted_repo && git log --all --oneline a3f92b1 "temp: hardcoded DB password for testing" ← deleted but in history git show a3f92b1:config/database.php $db_password = "Pr0ductionDB!2024";
Even if the developer realised their mistake and removed the secret in a later commit, git history preserves every previous state of every file. The "deletion" commit only removes it from the current working tree — the secret remains accessible in the repository history forever unless the history is explicitly rewritten.
A phpinfo.php file outputs a complete PHP environment report — initially useful for developers debugging configuration, but catastrophically informative for attackers if left publicly accessible.
# What phpinfo() reveals to an attacker: PHP Version 7.4.3 → CVE research for this exact version Server API Apache/2.4.29 Document Root /var/www/html/app → server filesystem path SCRIPT_FILENAME /var/www/html/app/phpinfo.php → full path disclosed disable_functions (none) → no function restrictions, exec() available allow_url_fopen On → can fetch remote URLs in PHP scripts allow_url_include On → remote file inclusion vulnerabilities possible SMTP localhost:25 → internal mail relay visible MySQL socket /var/run/mysqld/mysqld.sock → database socket path AWS_SECRET_KEY AKIAIOSFODNN7EXAMPLE → sometimes in environment vars! # Environment variables are frequently included in phpinfo() # These may contain cloud provider credentials, API keys, or DSN strings
The Apache server-status page is a built-in diagnostic endpoint showing every active request being processed by the server in real time. When exposed publicly, it leaks active session tokens, internal URLs, and client IP addresses.
curl http://target.com/server-status Apache Server Status for target.com Srv PID Conn Slot Mode CPU SS Req Conn Child Slot Client VHost Request 0-0 1234 1 0 W 0.0 0 47 0.0 0.00 0.00 10.0.1.5 corp-internal GET /admin/dashboard?session=a3f9b2c1... HTTP/1.1 1-0 1235 1 1 W 0.0 0 12 0.0 0.00 0.00 203.0.1.1 corp.com GET /login HTTP/1.1 # The highlighted request shows: # - An internal IP address (10.0.1.5) — suggests internal network access # - A session token in the URL query string — session hijacking possible # - An admin dashboard URL and path — admin panel confirmed and located
False Positives — Distinguishing Real Findings from Noise
Nikto is known for producing a meaningful number of false positives — findings that the tool flags as potentially vulnerable but that turn out, on manual inspection, to be benign. Including unverified Nikto output in a professional report is one of the fastest ways to lose client confidence. Every finding must be manually verified before being reported as confirmed.
Understanding where false positives come from helps you identify them quickly:
- Generic path checks: Nikto checks for paths like
/admin/regardless of whether the application actually has an admin panel. If the server returns a 200 response for any request (common with custom 404 handlers that return 200 with an "error" page), Nikto will flag every checked path as present. - Custom 404 handlers: Many frameworks return HTTP 200 with a custom "not found" page rather than the standard HTTP 404. Nikto cannot always distinguish this from a real resource — leading to false positives on nearly every path check.
- WAF interference: Web Application Firewalls may return 403 Forbidden for scan-like requests. Nikto may interpret certain 403 responses as indicators of restricted resources rather than WAF blocks.
- Version-matched checks without exploitability: Nikto may flag a vulnerability based on the server version string alone, without verifying that the specific vulnerable code path is actually reachable in the deployed configuration.
A junior penetration tester runs Nikto against a web application and sees thirty-seven findings flagged, including what appears to be an exposed admin panel at /admin/. They copy the output directly into the report under "Critical Findings."
The client's developers review the report and note that the application uses a custom 404 handler that returns HTTP 200 with a "page not found" message for all non-existent paths — including /admin/. The "admin panel" does not exist; Nikto flagged it because the server returned a 200 status code, which it treats as an indication that the resource was found.
Manual verification would have taken thirty seconds: a browser visit to /admin/ would have immediately shown the application's "page not found" message, not an admin interface. The finding would have been correctly discarded before entering the report. The lesson: Nikto output is a starting point for investigation, not a finished product. Every finding requires a manual HTTP request to confirm the resource actually exists and contains what the tool claims.
A systematic manual verification process for each Nikto finding. This takes minutes per finding but produces reports that hold up to scrutiny.
# For each Nikto finding, perform these verification steps: # 1. Fetch the path manually — check actual response vs expected: curl -I http://target.com/phpinfo.php HTTP/1.1 200 OK ← confirmed real (not a fake 200) Content-Type: text/html ← PHP rendered the page # 2. Confirm the content matches the finding description: curl http://target.com/phpinfo.php | grep -i "phpinfo" PHP Version 7.4.3 ← confirmed, real phpinfo output visible # 3. For directory indexing, verify files are actually listed: curl http://target.com/backup/ <title>Index of /backup</title> backup_2024-01-15.sql.gz ← real directory listing, real files # 4. Document HTTP status, response body extract, and screenshot # Only then include in the report as a confirmed finding
What Nikto Findings Reveal About Web Security Posture
Nikto findings are not random — they cluster around specific failure modes in how organisations manage their web servers. When you see a server with multiple critical Nikto findings, they usually share a root cause. Understanding these root causes is what enables effective remediation recommendations.
The Default Configuration Problem
Many Nikto findings trace back to a single root cause: the web server was installed with default configuration and never hardened. Apache, Nginx, IIS, and most other web servers ship with demonstration files, diagnostic endpoints, directory indexing, and permissive HTTP method settings that serve developer convenience but create security risks in production.
A server that still has phpinfo.php in its web root, still returns a default Apache "It works!" page, still has directory indexing enabled, and still exposes /server-status has almost certainly never had its default configuration reviewed. The presence of multiple default-file findings is a strong signal that security hardening was skipped entirely, which means the remaining attack surface is likely much larger than what Nikto alone can identify.
Dev artifacts in production: phpinfo.php, test.php, and debug.php are created during development and forgotten when the application is deployed. Deployment pipelines should explicitly exclude development files.
Incomplete decommissioning: Backup files (.bak, ~, .old) are created during upgrades and left in place. Directory-level cleanup should be part of every upgrade procedure.
Missing security headers: Web frameworks don't add security headers by default — they must be explicitly configured. Most organisations don't discover the gap until a scanner points it out.
Disable directory indexing: Options -Indexes in Apache, autoindex off in Nginx. This single directive closes directory listing findings for the entire server.
Remove default files: Delete server-status, server-info, phpinfo.php, and all framework demo/test pages before deploying to production. Automate this in the deployment pipeline.
Add security headers: Configure all six core security headers in the web server config or application middleware. Test with securityheaders.com after deployment.
Restrict HTTP methods: Only allow GET, POST, and HEAD unless PUT, DELETE, or OPTIONS are explicitly required. Disable TRACE unconditionally — it enables cross-site tracing (XST) attacks.
Detecting Nikto Scans from the Defender's Side
Nikto's default User-Agent string is Mozilla/5.00 (Nikto/2.x) — one of the most recognisable scanner signatures in web server access logs. Any WAF or web application firewall with up-to-date signatures will detect and block Nikto within seconds of starting a scan. Nikto offers evasion options (-evasion 1 for random URL encoding, -evasion 2 for directory separator variations) but these are more effective against basic signature matching than against behavioural analysis.
The more reliable detection signal is behavioural: a Nikto scan generates thousands of HTTP requests in a very short period, the vast majority returning 404 responses. A normal user generates tens of requests per session with mostly 200 responses. Any system that monitors the ratio of 4xx responses to 2xx responses per source IP will trivially identify Nikto scan behaviour — independent of any User-Agent signature.
Core Concepts Summary
You've covered the theory. Now apply it hands-on in the simulated environment.
Start Lab — Nikto→← Return to all labs