Track 6 · Lesson 4 of 5
Service versions and what they tell you
Ask a service what it is with nmap -sV and curl -I, read the version banner it returns, and understand why a version number is the raw material of a judgement.
A port being open tells you that something is there. A version tells you what it is and roughly how old. Versions are the raw material of the judgement phase, because a known issue is attached to a version, not to a port. In this lesson you will ask a service to identify itself, first with a scan and then by reading the banner it sends. You will also see why the same version string can matter a great deal or not at all, depending on where it is.
What you'll be able to do
- Identify a service and its version with
nmap -sV. - Read a service banner directly with
curl -I. - Say why a version number matters more than the port it sits on.
- Tell what
-sVcan and cannot work out.
Step 1: Start something to identify
A scan can only identify a service that is running, so start one on purpose. Open a second Termux session by swiping in from the left edge of the screen and tapping New session. In that session, start a throwaway web server on a high port.
python3 -m http.server 8010
Serving HTTP on 0.0.0.0 port 8010 (http://0.0.0.0:8010/) ...
Leave it running and go back to your first session. You now have a service on your own device that you can ask about, and it is on a port above 1024, so it needed no root to start.
Step 2: Ask nmap to identify it
The -sV flag asks nmap to go beyond naming the port and work out the service and its version. It does this by connecting and reading the greeting the service sends back.
nmap -sV -n -p 8010 localhost
Starting Nmap 7.95 ( https://nmap.org ) at 2026-10-25 04:36 IST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00064s latency).
Other addresses for localhost (not scanned): ::1
PORT STATE SERVICE VERSION
8010/tcp open http SimpleHTTPServer 0.6 (Python 3.12.13)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.77 seconds
The table now has a VERSION column, and the row is worth reading in full. 8010/tcp is the port. open is the state. http is the service, and SimpleHTTPServer 0.6 (Python 3.12.13) is the version string nmap worked out from what the server said. The line Service detection performed confirms the probe ran. That version string is the point of the whole command: it is the thing a known issue attaches to.
-sV is a best effort, not a promise. Some services say nothing useful, and nmap will then print a question mark or leave the column blank. When that happens, the next step is to read the banner by hand.
Step 3: Read the banner by hand
A service often announces itself in the first line or two it sends. curl with -I asks for the response headers only, which is where a web server puts its version.
curl -sI http://127.0.0.1:8010/
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.12.13
Date: Sun, 25 Oct 2026 04:36:18 GMT
Content-type: text/html; charset=utf-8
Content-Length: 263
The Server line is the banner, and it matches what nmap reported. The -s flag silences the progress meter and -I asks for headers rather than the body, so the output is short and easy to read. Not every service announces a version, and some announce a false one on purpose. Treat a banner as evidence, not as proof, and confirm it another way when it matters.
Every service you identify here is one you started on your own phone. Reading a banner is a request, and sending requests to a system you do not control is no different from scanning it. Keep the target on 127.0.0.1 or your own 192.168 address.
Step 4: Why the version is the part that matters
The port number tells you where a service is, and the version tells you what it is. Only one of those ages. Port 8010 will still be port 8010 next year, but the server behind it will have had releases and fixes in between. When you read a version, you are reading a point in time.
That is also why the same version can matter a great deal or not at all. A version on a port bound to 127.0.0.1 is reachable only from the device itself, so the ways it can be reached are few. The same version on a port bound to 0.0.0.0 is reachable from anywhere on your network, and every issue it carries is now a step closer to being usable. Read the version and the address together, and then go on to judge what you have found.
When you have a version in front of you, the next question is not "is this old" but "who can reach this". A version you cannot reach is a lower priority than a version anyone on the network can reach. The next lesson turns that pair into a decision.
Quick reference
A throwaway web server is the easiest thing to point a version scan at, because you control both ends. The service scan is what turns an open port into a name and a version. Asking for the response headers alone is often enough to read a banner, and a listener listing shows which address a service is bound to, which decides who can reach it.
Next steps
- Finding and judging a vulnerability turns a version and an address into a decision.
- Reading a port scan properly is the step before this one, where the ports are found.
- HTTP and APIs from the shell covers reading responses and headers in more depth.
Test yourself on this
4 questions and 1 task where you run a real command, with the reasoning explained either way.