Red Team · Medium
Nikto Web Scanner

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.

Medium Red Team Path ⏱ 22 min read CEH Aligned
Learning Progress
0%

Nikto — Web Server Scanner

CEH DomainModule 14 — Hacking Web Applications: Web server vulnerability scanning, misconfiguration detection

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.

Core Nikto Usage
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)
🚨Active and Noisy: Unlike OSINT, Nikto makes direct HTTP requests to the target server. Every request appears in the server's access logs. Nikto is not stealthy — it sends thousands of requests in a short period with a distinctive User-Agent string. Run it only against systems you are authorised to test. In professional engagements, Nikto scans should be coordinated with the client's SOC to prevent triggering incident response.
📌 Non-Technical Analogy

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

Example 01Basic scan output

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
Example 02Missing security headers

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
Example 03Dangerous file discovery

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
Example 04Interpreting and prioritising findings

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

📋
Security Headers
X-Frame-Options, CSP, HSTS, X-Content-Type-Options, X-XSS-Protection. Each prevents a class of client-side attack. Missing headers are low-hanging fruit — cheap to fix, frequently overlooked.
📁
Directory Indexing
When a directory has no index file, Apache/Nginx may list all files. Attackers use this to enumerate and download sensitive files — config files, backups, private keys.
🔖
OSVDB References
Nikto uses OSVDB IDs to reference known vulnerabilities. Cross-reference with CVE and NVD for full details and CVSS severity scores. OSVDB itself is defunct but IDs remain in Nikto's database.
Manual Verification
Nikto produces false positives. Always verify findings manually before reporting. A finding in Nikto is a lead, not a confirmed vulnerability — treat it as a hypothesis to test.

Nikto Tuning — Targeting Specific Test Categories

CEH ObjectiveModule 14 — Web application scanning: targeted vulnerability assessment, reducing scan noise

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.

IDCategoryWhat It ChecksWhen to Use
0File UploadForms and endpoints that accept file uploads — potential remote code execution pathsWeb app assessments where file upload is present
1Interesting File / Seen in LogsFiles commonly found in server logs, admin panels, backup pathsInitial recon — high signal-to-noise ratio
2Misconfiguration / Default FileDefault install files, test pages, server-status, server-info endpointsPost-install hardening verification
3Information DisclosureFiles that leak server info, PHPinfo, error messages with stack tracesAll assessments — always worth running
4Injection (XSS/Script/HTML)Cross-site scripting entry points, HTML injection, script injectionWeb application security assessments
5Remote File Retrieval (inside web root)Local file inclusion, path traversal within the web rootPHP applications, legacy web frameworks
6Denial of ServiceRequests that could cause service disruption — use with cautionAvoid in production; lab/staging only
7Remote File Retrieval (outside web root)Directory traversal and LFI outside the web rootOlder web servers, CGI scripts
8Command Execution / Remote ShellCGI vulnerabilities, command injection entry pointsLegacy servers with CGI, command injection testing
9SQL InjectionSQL injection indicators in parameters, error messages, response patternsWeb app DB-backed assessments — complement with sqlmap
aAuthentication BypassDefault credentials, authentication logic bypassesAdmin interface assessments
bSoftware IdentificationIdentify CMS, framework, and software versionsTechnology fingerprinting pass
Example 05Targeted tuning for specific assessment types

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

CEH ObjectiveModule 14 — Web application security: HTTP security headers, client-side attack prevention, HSTS

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.

HeaderWhat It PreventsAbsent RiskSeverity
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
📌 Non-Technical Analogy — Content Security Policy

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

CEH ObjectiveModule 14 — Web server attack techniques: directory traversal, source code disclosure, default file 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.

Example 06Exposed .git directory — Full Source Code Exfiltration

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.

Example 07phpinfo.php — Infrastructure Intelligence Gathering

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
Example 08Apache server-status — Real-Time Process Intelligence

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

CEH ObjectiveModule 14 — Vulnerability assessment: false positive identification, manual verification methodology

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:

ScenarioThe Misleading 200 Response

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.

Example 09Manual verification workflow

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

CEH ObjectiveModule 14 — Web server hardening, secure configuration baseline, defence-in-depth for web infrastructure

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.

Common Root Causes of Nikto Findings

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.

Hardening Checklist

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.

Defender's Quick Win: The fastest way to reduce Nikto findings to near-zero is to implement a web application firewall with a rate-limiting rule (block any source IP generating more than 100 404 responses in 60 seconds) and a post-deployment hardening checklist that explicitly removes default files and enables security headers. Together these two measures address the majority of findings Nikto typically surfaces without requiring any changes to the application itself.

Core Concepts Summary

📋
Security Headers
CSP (blocks XSS), HSTS (prevents SSL stripping), X-Frame-Options (blocks clickjacking), X-Content-Type-Options (prevents MIME sniffing), Referrer-Policy, Permissions-Policy. Each targets a specific browser attack class.
📁
Directory Indexing
Apache Options -Indexes / Nginx autoindex off. When enabled, any directory without an index file lists all contents. Frequently exposes backup files, config files, and source archives. One directive fixes server-wide.
🔖
OSVDB / CVE References
Nikto uses OSVDB IDs (Open Source Vulnerability Database, now defunct). Cross-reference against NVD (nvd.nist.gov) and CVE Details for current CVSS scores, patch status, and exploit availability.
Manual Verification
Custom 404 handlers returning HTTP 200 cause widespread false positives. Every finding needs a manual curl or browser visit to confirm the resource exists and contains what Nikto claims. Never report unverified Nikto output.
🎚️
Tuning (-Tuning)
Run specific test categories (0-9, a, b) to reduce noise and runtime. Tuning 123b for recon. Tuning 459 for web app assessment. Tuning 6 (DoS) should be avoided in production environments.
🐙
.git Exposure
Accessible .git directory allows full repo reconstruction with git-dumper. Secrets deleted in later commits remain in git history. Prevention: configure web server to deny access to all dotfiles and directories.
ℹ️
phpinfo / server-status
phpinfo() reveals PHP version, server paths, loaded modules, env vars (potentially containing credentials), and security configuration. server-status leaks active sessions and internal URLs in real-time. Remove both from production.
🛡️
Detection Evasion & Defence
Default UA "Nikto/2.x" is trivially detected. Rate limiting (100+ 404s/60s from one IP) catches behavioural pattern regardless of UA. WAF + rate limiting + hardening checklist eliminates most Nikto findings before scanning starts.
Ready to put it into practice?
Proceed to the Lab

You've covered the theory. Now apply it hands-on in the simulated environment.

Start Lab — Nikto
← Return to all labs