Banner Grabbing and Service Enumeration on Kali Linux

Tested on Kali GNU/Linux Rolling 2026.2 (kali-rolling)
Package nmap 7.99+dfsg-1kali1
netcat-openbsd 1.10-50.1
curl 8.21.0-2
wget 1.25.0-3
nikto 1:2.6.0-0kali4
dmitry 1.3a-8
Lab environment Pentest lab
Cert prep CompTIA PenTest+ PT0-003 — Domain 2 (Reconnaissance and Enumeration)
Privilege Normal user for most commands; sudo for package installs
Scope Active banner grabbing with Nmap, Netcat, curl, wget, openssl s_client, Nikto, and Dmitry against Metasploitable 2 ($TARGET) for FTP, SSH, SMTP, and HTTP banners. Covers multi-port version scans and CVE mapping. Optional modern SSH comparison requires a separate Linux VM. Does not cover passive OSINT platforms in depth, WAF evasion, or exploitation after version discovery.
Related guides Nmap command cheat sheet
Short on time?Beta Get the gist of this 16-minute read in seconds, then ask follow-up questions

Banner grabbing turns an open port into a product name and version string before you search CVE databases or load Metasploit modules. You connect to a service or request a web URL, then read the greeting line or HTTP headers the server returns.

This walkthrough runs Nmap, Netcat, curl, OpenSSL, and secondary scanners on the pentest lab. Metasploitable 2 ($TARGET) supplies FTP, SSH, SMTP, and Apache banners for every core exercise.

IMPORTANT
Run banner grabbing only against hosts and networks covered by your engagement authorization. Confirm scope and logging rules in your penetration testing rules of engagement before you connect to client or third-party systems.

Set your Metasploitable IP once per shell session. Replace the address below with your lab VM if it differs:

bash
export TARGET=192.168.56.127

After network reconnaissance shows port 21 open on $TARGET, connect with Netcat and read the FTP greeting:

bash
nc -w 2 "$TARGET" 21
output
220 (vsFTPd 2.3.4)

That 220 line is the banner: the service name and version the server sends as soon as TCP connects. Nmap automates the same idea across many ports with the banner script:

bash
nmap -n -Pn -p 22 --script banner "$TARGET"
output
Nmap scan report for 192.168.56.127
Host is up (0.00089s latency).

PORT   STATE SERVICE
22/tcp open  ssh
|_banner: SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
MAC Address: 08:00:27:33:AF:98 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds

The |_banner: line is the raw SSH greeting Nmap captured. Netcat prints the same string when you connect to port 22 manually.


What is banner grabbing?

Banner grabbing reads the software name and version a service advertises when you connect. Penetration testers use that string during reconnaissance to narrow CVE lookup, module search, and exploitation planning. It is not exploitation by itself.

Banner grabbing and service version detection are related but not identical. Banner grabbing reads information a service voluntarily returns, such as an SSH greeting or HTTP Server header. Nmap -sV goes further by sending protocol-specific probes and matching the responses against service fingerprints, so it can identify software even when no useful banner is exposed. The banner NSE script simply connects and prints data sent by the listening service; version detection uses additional probes.

Some services send a greeting immediately after the TCP handshake:

  • SSH — SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
  • FTP — 220 (vsFTPd 2.3.4)
  • SMTP — 220 metasploitable.localdomain ESMTP Postfix (Ubuntu)

Others, especially HTTP and HTTPS, usually require a valid protocol request before useful headers or certificate details are returned. That is why nc host 21 works on its own, while web banner grabbing needs HEAD or GET.

Method Example Direct target connection from tester?
Active banner grabbing Nmap, Netcat, curl Yes
Passive observation Wireshark, tcpdump No new connection; inspect existing traffic

Shodan and Censys are passive reconnaissance from the tester's perspective because your machine does not connect to the target, but the underlying banner data was originally collected through active Internet scanning. This lesson focuses on active grabs in an authorized lab.

Ranking tutorials and exam prep material follow the same loop:

  1. Discover open ports with Nmap or your port-scanning workflow
  2. Pull banners with --script banner, Netcat, or HTTP header tools; use -sV when you need fingerprinting beyond the raw greeting
  3. Manually verify anything you plan to exploit — automated fingerprints can be wrong or incomplete
  4. Map confirmed versions to CVE databases and record port, product, and version in your notes

Prepare the Kali banner-grabbing lab

Variable Purpose
TARGET Metasploitable 2 IP from your lab guide — legacy FTP, SSH, HTTP, and Samba banners

Read the VM address with ip addr on the console. In this retest, Metasploitable was 192.168.56.127. Export it once per shell session:

bash
export TARGET=192.168.56.127

Kali and Metasploitable must share one host-only adapter. Confirm with ping -c 1 "$TARGET" before you run banner tools.

Install or refresh the tools if your Kali image is missing a package:

bash
sudo apt update

Pull the banner-grabbing packages from the Kali repositories:

bash
sudo apt install -y nmap netcat-openbsd curl wget nikto dmitry

The netcat-openbsd package provides the nc command used in the Netcat section below.


Compare banner grabbing tools

Tool Best for Banner type
Nmap (--script banner, -sV) Multi-port lab inventory Raw banner plus version fingerprint
Netcat Quick manual check on one port Immediate greetings (FTP, SMTP) or raw HTTP requests
curl / wget HTTP and HTTPS headers Server, X-Powered-By, and other response metadata
Nikto Web attack surface plus banners Server banner and outdated component warnings
Dmitry (-pb) Bundled port scan with banners Mixed protocols on discovered open ports
openssl s_client TLS services on port 443 Certificate subject, issuer, negotiated cipher

Start with Netcat when you want to see one banner immediately. Use Nmap after your port scan for multi-port inventory, then curl or OpenSSL for HTTP and HTTPS verification.


Grab banners with Nmap

Nmap is the default choice for banner work at scale. It combines port discovery, version detection (-sV), and the banner NSE script. For more script categories and --script-args, see Nmap NSE scripts for enumeration.

Raw SSH banner with the banner script

Point the script at one port where you already know a service listens:

bash
nmap -n -Pn -p 22 --script banner "$TARGET"
output
Nmap scan report for 192.168.56.127
Host is up (0.0013s latency).

PORT   STATE SERVICE
22/tcp open  ssh
|_banner: SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1
MAC Address: 08:00:27:33:AF:98 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds

-Pn skips normal host discovery and tells Nmap to proceed as though the target is online. It is useful when discovery probes may be blocked or when you already know the target is running.

Version fingerprint with -sV

Version detection runs additional probes and prints a normalized product string:

bash
nmap -n -Pn -p 22 -sV "$TARGET"
output
Nmap scan report for 192.168.56.127
Host is up (0.0013s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
MAC Address: 08:00:27:33:AF:98 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 1.31 seconds

Use -sV when you want a concise VERSION column across many ports, not only the raw banner text.

Tune probe depth with --version-intensity

Nmap accepts intensity 0 through 9 (default 7). Higher values run more probes and take longer:

bash
nmap -n -Pn -p 22 -sV --version-intensity 9 "$TARGET"

On Metasploitable SSH, intensity 9 returned the same OpenSSH line as the default in this lab run. Raise intensity when -sV returns unknown on a non-default port. Lower it when you need a faster scan on a large subnet.

Scan several services in one pass

Grab banners and versions on the ports that matter for your next exercise:

bash
nmap -n -Pn -sV -p 21,22,80,139,445,5900 "$TARGET"
output
Nmap scan report for 192.168.56.127
Host is up (0.0011s latency).

PORT     STATE SERVICE     VERSION
21/tcp   open  ftp         vsftpd 2.3.4
22/tcp   open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
80/tcp   open  http        Apache httpd 2.2.8 ((Ubuntu) DAV/2)
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
5900/tcp open  vnc         VNC (protocol 3.3)
MAC Address: 08:00:27:33:AF:98 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 12.66 seconds

The FTP, SSH, and HTTP rows give specific product and version clues. Samba 3.X - 4.X and VNC protocol results are broader fingerprints, so run protocol-specific enumeration before you pick a CVE or Metasploit module.


Grab banners with Netcat

Netcat (nc) opens a TCP connection and prints whatever the service sends first. It works well for FTP, SMTP, and other line-based protocols that greet you immediately.

Telnet can also be used for manual banner grabbing on text-based services such as FTP and SMTP. Netcat is generally more flexible for raw protocol interaction, so the examples below use nc.

Connect to FTP on port 21 and read the banner line. Add -w 2 so Netcat closes after the greeting instead of waiting for input:

bash
nc -w 2 "$TARGET" 21
output
220 (vsFTPd 2.3.4)

The 220 prefix is normal FTP syntax. The product string vsFTPd 2.3.4 matches what Nmap reported on port 21.

SMTP follows the same pattern on port 25:

bash
nc -w 2 "$TARGET" 25
output
220 metasploitable.localdomain ESMTP Postfix (Ubuntu)

HTTP is different: the server waits for a request. Pipe a minimal HEAD request through Netcat to read the Server header:

bash
printf 'HEAD / HTTP/1.1\r\nHost: metasploitable\r\nConnection: close\r\n\r\n' \
  | nc -w 3 "$TARGET" 80
output
HTTP/1.1 200 OK
Date: Mon, 31 Aug 2026 00:17:07 GMT
Server: Apache/2.2.8 (Ubuntu) DAV/2
X-Powered-By: PHP/5.2.4-2ubuntu5.10
Connection: close
Content-Type: text/html

Netcat sends the raw protocol bytes. curl -I does the same HTTP-specific job more conveniently, which is why many testers learn the technique with nc first and switch to curl for routine header inspection. Omit -w on FTP or SMTP when you want an interactive session; press Ctrl+C to close it.


Grab HTTP headers with curl and wget

The most direct HTTP banner clues usually appear in response headers such as Server and X-Powered-By. Framework signatures, error pages, and HTML comments can also reveal technology, but this walkthrough focuses on header inspection.

curl

Request headers only with -I (HEAD). -sS hides the progress meter and still prints errors if the connection fails:

bash
curl -sS -I "http://$TARGET/"
output
HTTP/1.1 200 OK
Date: Mon, 31 Aug 2026 00:02:45 GMT
Server: Apache/2.2.8 (Ubuntu) DAV/2
X-Powered-By: PHP/5.2.4-2ubuntu5.10
Content-Type: text/html

Server names the web daemon; X-Powered-By exposes PHP. See the curl command guide for more header and download options.

wget

wget prints response headers to stderr while discarding the body:

bash
wget -q -S -O /dev/null "http://$TARGET/"
output
  HTTP/1.1 200 OK
  Date: Mon, 31 Aug 2026 00:02:45 GMT
  Server: Apache/2.2.8 (Ubuntu) DAV/2
  X-Powered-By: PHP/5.2.4-2ubuntu5.10
  Content-Length: 891
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Content-Type: text/html

-q quiets download progress; -S shows server headers. The wget command guide covers recursion and mirrors when you move past header inspection.


Grab TLS metadata with OpenSSL

HTTPS and other TLS services do not send a plaintext greeting like FTP or SSH. openssl s_client completes a TLS handshake and exposes certificate subject, issuer, and negotiated cipher details. That is TLS metadata rather than a traditional banner, but it helps identify the hostname, certificate issuer, certificate chain, and TLS configuration exposed by the service.

The default Metasploitable 2 image in this lab does not listen on port 443. Confirm before you run OpenSSL against $TARGET:

bash
nmap -n -Pn -p 443 "$TARGET"
output
PORT    STATE  SERVICE
443/tcp closed https

When you find HTTPS open on an authorized target, set HOST to the hostname or IP and run:

bash
export HOST=example.com
openssl s_client -connect "$HOST:443" -servername "$HOST" </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer
output
subject=CN=example.com
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3

Add -showcerts to the s_client command when you need the full chain in your notes. For day-to-day HTTPS header inspection on port 443, curl -sS -I "https://$HOST/" is often faster than parsing certificate output.


Grab banners with Nikto

Nikto is a secondary web scanner that surfaces server banners and outdated components alongside misconfiguration checks. It is louder and slower than curl -I, but useful when you want path probes in the same pass.

Scan the Metasploitable web service on port 80. Add -maxtime 60s when you only need the banner section:

bash
nikto -h "$TARGET" -maxtime 60s

The first lines confirm the target and print the web server banner Nikto detected:

output
+ Target IP:          192.168.56.127
+ Target Hostname:    192.168.56.127
+ Target Port:        80
+ Server: Apache/2.2.8 (Ubuntu) DAV/2
+ [999986] /: Retrieved x-powered-by header: PHP/5.2.4-2ubuntu5.10.

Nikto is louder and slower than curl -I, but it can surface the same Server header while probing common web paths. Expect a long report on real targets; increase -maxtime when you need the full crawl.


Grab banners with Dmitry

Dmitry bundles WHOIS, subdomains, and port banner collection. The -pb flag combines a port scan with banner output.

Run it against the lab target:

bash
dmitry -pb "$TARGET"
output
ERROR: Unable to locate Host Name for 192.168.56.127
Continuing with limited modules
HostIP:192.168.56.127

Gathered TCP Port information for 192.168.56.127
---------------------------------

 Port		State

21/tcp		open
>> 220 (vsFTPd 2.3.4)

22/tcp		open
>> SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1

25/tcp		open
>> 220 metasploitable.localdomain ESMTP Postfix (Ubuntu)

Dmitry warns that it cannot resolve a hostname when you pass a bare IP. The port banner module still runs. Binary protocols such as telnet on port 23 can produce garbled banner lines; verify those with Nmap or a protocol-specific tool.


Optional: compare against a modern SSH server

The core exercises above use Metasploitable only. This optional section requires an additional Linux VM on the same host-only segment — for example Ubuntu 26.04 at 192.168.56.121 — if you want to contrast legacy OpenSSH on Metasploitable with a current distro package.

Export the second host once per shell session:

bash
export UBUNTU_LAB=192.168.56.121

Repeat the same banner script you ran on Metasploitable:

bash
nmap -n -Pn -p 22 --script banner "$UBUNTU_LAB"
output
Nmap scan report for 192.168.56.121
Host is up (0.0016s latency).

PORT   STATE SERVICE
22/tcp open  ssh
|_banner: SSH-2.0-OpenSSH_10.2p1 Ubuntu-2ubuntu3.5
MAC Address: 08:00:27:CD:3B:E9 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.77 seconds

The workflow is identical; only the version string changes. Record both hosts in your notes so you can contrast legacy Metasploitable services with a current Ubuntu OpenSSH package during report writing. Skip this section if you have not built a second Linux VM.


Map banners to CVE research

Banner version ≠ confirmed vulnerability. A version string is a research lead, not proof that an exploit will work on that host.

On Linux distributions, do not judge vulnerability status from the upstream version number alone. Debian, Ubuntu, RHEL, and other distributions may backport security fixes without upgrading to the newest upstream release. Verify the complete package version against the distribution's security advisory or package changelog before you assume a CVE applies.

Record the service, version, and port before you search a CVE database:

Port Banner (from lab) Research note
21 vsFTPd 2.3.4 Check CVE-2011-2523 build scope before assuming backdoor
22 OpenSSH 4.7p1 (Metasploitable) Match OpenSSH advisories to distro package age
25 Postfix (Ubuntu) Match mail-server advisories to distro package age
80 Apache 2.2.8, PHP 5.2.4 Both are end-of-life; expect many historical CVEs

A banner is only a clue. CVE-2011-2523 applies to vsFTPd 2.3.4 archives downloaded during a specific June–July 2011 window, so the version string alone does not prove every vsFTPd 2.3.4 server is vulnerable. NVD documents that limited affected-build scope.

When a CVE matches your lab fingerprint, continue with targeted exploitation in the Metasploitable 2 walkthrough on systems you are authorized to test.


Troubleshooting

Symptom Likely cause Fix
No banner line from nc Wrong port, filtered service, or binary protocol Confirm the port is open with nmap -n -Pn -p PORT "$TARGET"; try Nmap --script banner
nc hangs on HTTP Sent no request body Pipe a HEAD or GET line ending in \r\n\r\n, or use curl -I
curl hangs HTTP service down or wrong URL Use http://$TARGET/ explicitly; try nmap -n -Pn -p 80 "$TARGET"
openssl s_client fails on $TARGET Port 443 closed in default Metasploitable VM Use curl -I on port 80, or run OpenSSL against a host where HTTPS is in scope
Nmap shows filtered or closed Target offline or wrong network Confirm Metasploitable is running and Kali shares the lab segment per your lab guide
Dmitry hostname error on IP Expected without reverse DNS Ignore if -pb banners still appear; use Nmap for IP-only labs
Nikto runs for a long time Full crawl on a busy web app Add -maxtime 120s for lab demos; read the Server: line first
smb or Samba shows 3.X - 4.X only Broad Nmap fingerprint Run SMB-specific enumeration before CVE selection

Summary

Banner grabbing turns an open port into actionable intelligence: the difference between “something on 22” and “OpenSSH 4.7p1 on Linux.” In this lab you practiced that loop with Netcat on FTP, SMTP, and raw HTTP, Nmap’s banner script and -sV probes on Metasploitable, HTTP header pulls with curl and wget, TLS certificate inspection with OpenSSL, and secondary passes with Nikto and Dmitry.

Nmap remains the workhorse for multi-service labs because one scan fills a version table you can feed into CVE lookup or Metasploit search. Netcat makes the concept obvious on line-based protocols; curl stays the fastest routine HTTP banner check. The vsFTPd banner on port 21 is a worked example of CVE research: a version string points you toward CVE-2011-2523, but you still verify whether the build is actually affected.

Treat every banner as a hypothesis until you verify it. Services can lie, hide behind proxies, or return incomplete strings on the first connect. When a version string looks exploitable, continue in your isolated lab with the Metasploitable walkthrough, not against hosts you are not authorized to test.


References


Frequently Asked Questions

What is banner grabbing in ethical hacking?

Banner grabbing reads the first text a service sends when you connect to an open port, or the headers a web server returns on HTTP. That banner often names the software and version, which you map to CVE databases during reconnaissance.

Is banner grabbing illegal?

Banner grabbing is appropriate on systems you own or are explicitly authorized to test. Laws, provider terms, and organizational policies vary, so obtain written permission before scanning or connecting to third-party systems.

When should I use Nmap -sV versus the banner script?

Use --script banner when you want the raw greeting string a service voluntarily returns on a specific port. Use -sV when you want Nmap to send additional protocol probes and match responses against its fingerprint database, which can identify software even when no useful banner is exposed. Combining both on the same scan is common in lab work.

What is the difference between active and passive banner grabbing?

Active banner grabbing means you connect directly to the target service from your workstation. Passive banner identification can come from observing existing network traffic without initiating a connection, for example with Wireshark or tcpdump. Third-party services such as Shodan and Censys are another indirect reconnaissance source: your system does not contact the target, although those services collected their data through their own scanning.

Why does Dmitry fail to resolve my target hostname?

Dmitry expects a resolvable hostname for some modules. When you pass a bare IP, it continues with limited modules but -pb port banners still work. Use Nmap or Netcat when you only have an IP address.

Can I use Netcat instead of Nmap for banner grabbing?

Netcat works well for one port and line-based protocols such as FTP and SMTP. Nmap scales better when you need version columns across many ports or want the banner NSE script. Many testers run Nmap first, then verify interesting lines with nc.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)