In 03-01 we obtained a table of open ports per host: on dev (10.10.10.15) we saw 22, 80, 3306, 8080, and a mysterious 54321; on db-interno (10.10.10.40) 53 and 161/UDP; on the store 80 and 443. But that 3306/tcp mysql is just a label Nmap slaps on based on the port number: anyone can run any service on any port. We don't know which version is running, which web server serves port 80, or what on earth 54321 is.
Enumerating services is answering exactly that: for each open port, what service it is, what version, what operating system hosts it, and what information it exposes. The deliverable of this lesson is an inventory of services with versions —the piece we'll cross-reference against known vulnerabilities in 03-03—. Here we identify and inventory; we still don't assess or prioritize vulnerabilities. And, as always, within scope: enumeration also generates traffic and some probes (resource brute-forcing, massive SNMP queries) can be intrusive, so they're agreed on and documented.
Contents
- From open port to identified service
- Version detection with Nmap (
-sV) - Operating system detection (
-O) - Manual banner grabbing
- Per-protocol enumeration: overview
- HTTP/HTTPS: whatweb, nikto, and NSE
- SMB: enum4linux and smbclient
- SNMP: snmpwalk
- Others: FTP, SSH, SMTP, DNS, MySQL
- TechNova's service inventory
- Defensive counterpart
- Common mistakes and tips
- Exercises
- Conclusion
- From open port to identified service
Port scanning tells you where something is listening; enumeration tells you what is listening and what it says about itself. The difference is enormous for a pentester:
- "3306 is open" → I don't know if it's exploitable.
- "3306 is MySQL 5.5.62, no TLS, and accepts connections from the network" → now I can hunt for concrete vulnerabilities in that version.
The version is the most valuable piece of data in this phase, because known vulnerabilities are tied to specific versions (we'll see this in 03-03 with CVE and CPE). That's why the central goal is to sharpen each open port down to a service + version.
- Version detection with Nmap (
-sV)
-sV)-sV makes Nmap, after finding an open port, interrogate the service by sending probes and comparing the responses against its signature database (nmap-service-probes). It returns the real service and, often, the exact version.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) 3306/tcp open mysql MySQL 5.5.62-0ubuntu0.14.04.1 8080/tcp open http Jetty 9.4.z-SNAPSHOT 54321/tcp open http Werkzeug httpd 0.14.1 (Python 3.6.9)
Line by line:
22 ... OpenSSH 7.6p1 Ubuntu: not just "ssh", but the exact version and that the system is Ubuntu (a free OS data point).80 ... Apache httpd 2.4.29: the web server is Apache 2.4.29.3306 ... MySQL 5.5.62: the database is no longer a label: it's MySQL 5.5.62, an old version (a lead for 03-03).8080 ... Jetty 9.4.z: a Java Jetty server, probably a different application.54321 ... Werkzeug httpd 0.14.1 (Python 3.6.9): the mystery is solved: the odd port is a Python/Flask web app (Werkzeug is its development server). Running the development server on an exposed port is in itself a sign of misconfiguration.
Useful options: --version-intensity 0-9 tunes how many probes it sends (higher intensity = more accurate but noisier); -sV --version-light is a fast compromise.
- Operating system detection (
-O)
-O)-O tries to guess the OS by analyzing details of the TCP/IP stack (fingerprinting): initial TTL values, window size, TCP options... Each OS has a distinct "fingerprint".
Running: Linux 4.X|5.X OS CPE: cpe:/o:linux:linux_kernel:4 OS details: Linux 4.15 - 5.6 Network Distance: 1 hop
Running: Linux 4.X|5.X: it's a Linux with a kernel in the 4 or 5 series.OS CPE: cpe:/o:linux:linux_kernel:4: the CPE appears, the standardized identifier we'll use in 03-03 to search for vulnerabilities.Network Distance: 1 hop: it's one hop away (same network), consistent with the internal audit.
A widely used shortcut is -A, which combines -sV -O plus default scripts and traceroute:
It's convenient, but noisier; in stealthy scenarios it's preferable to launch -sV and -O separately and controlled.
- Manual banner grabbing
You don't always need Nmap. Many services introduce themselves on connection (the banner). Connecting by hand with netcat or openssl confirms versions and sometimes reveals details Nmap summarizes:
# HTTP headers: we request and read the server's response
printf 'HEAD / HTTP/1.0\r\n\r\n' | nc 10.10.10.15 80The header X-Powered-By: PHP/7.2.24 is gold: it confirms that behind Apache there's PHP 7.2 (the unsupported version we already suspected of the store). For services over TLS, use openssl s_client -connect host:443 instead of nc.
- Per-protocol enumeration: overview
From the version onward, each protocol has its own enumeration techniques to extract information. A map of what to look at depending on the port:
| Port | Service | What to enumerate | Tools |
|---|---|---|---|
| 80/443 | HTTP/S | Technologies, paths, files, headers | whatweb, nikto, nmap NSE, dirb |
| 139/445 | SMB | Shares, users, policies | enum4linux, smbclient, nmap NSE |
| 161/UDP | SNMP | Interfaces, processes, users, routes | snmpwalk, onesixtyone |
| 21 | FTP | Anonymous access, version, listings | nmap NSE, ftp |
| 22 | SSH | Version, authentication methods | nmap NSE, banner |
| 25 | SMTP | Users (VRFY/EXPN), open relay | nmap NSE, smtp-user-enum |
| 53 | DNS | Records, zone transfer | dig, nslookup, nmap NSE |
| 3306 | MySQL | Version, users, remote access | nmap NSE, mysql |
Nmap ships with the NSE (Nmap Scripting Engine): categorized scripts. Here we use the enumeration safe category (not vuln, which belongs to 03-03). The scripts live in /usr/share/nmap/scripts/ and are invoked with --script.
- HTTP/HTTPS: whatweb, nikto, and NSE
The store is the star target, so its web enumeration is a priority. First whatweb to identify technologies:
http://tienda.technova.lab [200 OK] Apache[2.4.29], PHP[7.2.24], Country[RESERVED][ZZ], HTTPServer[Ubuntu][Apache/2.4.29 (Ubuntu)], JQuery[1.12.4], Script, X-Powered-By[PHP/7.2.24]
It confirms Apache 2.4.29, PHP 7.2.24, and jQuery 1.12.4 (all old versions). Then nikto, a web server scanner that looks for known files and configurations (we use it here as reconnaissance, not as a vulnerability verdict):
+ Server: Apache/2.4.29 (Ubuntu) + /admin/: Directory indexing found. + /config.php.bak: Backup file found, possibly discloses credentials. + /phpinfo.php: Output from the phpinfo() function was found. + Cookie PHPSESSID created without the httponly flag.
Very useful enumeration findings: an /admin/ directory with listing, a config.php.bak (possible credential leak), and a phpinfo.php (reveals the entire PHP configuration). With NSE we broaden the picture using safe scripts:
80/tcp open http | http-title: TechNova - Tienda Online | http-methods: | Supported Methods: GET HEAD POST OPTIONS | http-enum: | /admin/: Possible admin folder | /login.php: Possible admin login
- SMB: enum4linux and smbclient
If ports 139/445 show up on a Windows or Samba host, SMB is a very rich source. At TechNova there are workstations and a network controller; let's suppose 10.10.10.55 (a workstation) has them open. enum4linux automates the enumeration:
[+] Server allows sessions using username '', password '' (null session) ... [+] Users via RID cycling: TECHNOVA\Administrador (RID 500) TECHNOVA\jlopez (RID 1103) TECHNOVA\mgarcia (RID 1104) [+] Share Enumeration: Sharename Type Comment --------- ---- ------- RRHH Disk Documentos RRHH IPC$ IPC IPC Service
A null session (session without credentials) lets us list users (jlopez and mgarcia from recon reappear!) and shares like RRHH. With smbclient we try to access the share (within scope):
Being able to list RRHH with -N (no password) is a serious configuration flaw. We document it; exploiting it in depth is the subject of later modules.
- SNMP: snmpwalk
In 03-01 we saw 161/UDP (SNMP) open on db-interno. SNMP with the default community (public) exposes an enormous dump of internal information. First we guess the community with onesixtyone, then snmpwalk:
SNMPv2-MIB::sysDescr.0 = STRING: Linux db-interno 4.15.0-112-generic HOST-RESOURCES-MIB::hrSWRunName.42 = STRING: mysqld IP-MIB::ipAdEntAddr.10.10.10.40 = IpAddress: 10.10.10.40 TCP-MIB::tcpConnLocalPort = INTEGER: 3306
SNMP hands us: the exact OS (Linux 4.15.0-112), the running processes (mysqld running), the network interfaces, and the local ports. It's internal enumeration for almost free, which is why SNMP with public is a classic finding.
- Others: FTP, SSH, SMTP, DNS, MySQL
A sweep of other common protocols with NSE and native clients:
# FTP: check anonymous access and version
nmap --script ftp-anon,ftp-syst -p 21 10.10.10.60
# SMTP: enumerate valid users and check for open relay
nmap --script smtp-commands,smtp-open-relay -p 25 correo.technova.lab
# DNS: server version
dig @10.10.10.40 version.bind chaos txt
# MySQL: version and capabilities (safe/info script)
nmap --script mysql-info -p 3306 10.10.10.15Example output of mysql-info:
3306/tcp open mysql | mysql-info: | Protocol: 10 | Version: 5.5.62-0ubuntu0.14.04.1 | Capabilities flags: 63487 | Salt: k5*Lp2...
It confirms MySQL 5.5.62 from the protocol itself (not just from -sV), and that it accepts connections from the network —a database shouldn't be exposed like this—.
- TechNova's service inventory
We consolidate everything into the lesson's deliverable: an inventory of services with versions. Sorted, it's the direct input to 03-03.
| Host | Port | Service | Version | OS | Enumeration notes |
|---|---|---|---|---|---|
| tienda.technova.lab | 80 | Apache | 2.4.29 | Ubuntu | PHP 7.2.24, jQuery 1.12.4, /admin/, config.php.bak |
| tienda.technova.lab | 443 | Apache (TLS) | 2.4.29 | Ubuntu | Same vhost over HTTPS |
| 10.10.10.15 (dev) | 22 | OpenSSH | 7.6p1 | Ubuntu | — |
| 10.10.10.15 (dev) | 80 | Apache | 2.4.29 | Ubuntu | PHP app |
| 10.10.10.15 (dev) | 3306 | MySQL | 5.5.62 | Ubuntu | Exposed to the network |
| 10.10.10.15 (dev) | 8080 | Jetty | 9.4.z | Ubuntu | Java app |
| 10.10.10.15 (dev) | 54321 | Werkzeug/Flask | 0.14.1 (Py 3.6.9) | Ubuntu | Exposed development server |
| 10.10.10.40 (db) | 161/UDP | SNMP | v2c community public |
Linux 4.15 | Internal dump accessible |
| 10.10.10.55 (wks.) | 445 | Samba/SMB | — | Windows | Null session, RRHH share |
Notice: we go from "open ports" to a who's-who with versions ready to search for CVEs. That's exactly the material the next lesson needs.
- Defensive counterpart
All this enumeration rests on services giving away too much information. The corresponding hardening:
- Hide banners and versions.
ServerTokens Prodin Apache, removeX-Powered-Byfrom PHP, neutral banners on SSH/SMTP. It doesn't stop the attack, but it makes mapping harder. - Close SMB null sessions (
restrict anonymous), disable SMBv1, and don't expose shares likeRRHHwithout authentication. - SNMP: change the
publiccommunity, use SNMPv3 with authentication and encryption, or disable it if unused. - Don't expose databases (
bind-address 127.0.0.1in MySQL); never leave development servers (Werkzeug,phpinfo.php,.bak) on reachable systems. - Detection: enumeration with
-sVand NSE generates full connections and recognizable patterns; a well-tuned IDS and the logging of anomalous access (many requests to nonexistent paths, external SNMP queries) give it away.
- Common Mistakes and Tips
- Trusting the
SERVICEby port number.3306might not be MySQL. Always confirm with-sVor banner grabbing. - Jumping straight to
--script vuln. That's 03-03. Here the job is to inventory withsafe/enumeration scripts; mixing phases muddies the work. - Ignoring UDP and SNMP. SNMP with
publicwrites half the report for you, and many people never look at it because it's UDP. - Web enumeration without context. nikto and whatweb spew a lot of noise; note what's relevant (versions, paths, sensitive files) and discard the rest.
- Undocumented null sessions. If a null session gives you users and shares, it's a finding in itself: record it, don't take it for granted.
- Being too intrusive. Some probes (aggressive directory brute-forcing, massive SNMP queries) load the service. Tune the intensity and respect the window.
- Tip: keep a living inventory in a table (host/port/service/version/notes) from the very first command. That document is literally the input to 03-03.
- Exercises
Exercise 1. You have dev's 8080/tcp open but Nmap only said "http-proxy" in 03-01. Write the command to identify the service and version of that port and explain what information you'd expect to get and why it's more useful than "http-proxy".
Exercise 2. On 10.10.10.55 an enum4linux -a returns a null session with the user list and an RRHH share accessible with smbclient -N. Classify what is enumeration (proper to this lesson) and what would already be exploitation (later modules), and what you should do here and now.
Exercise 3. Justify, with two concrete examples from TechNova's inventory, why the version is the most valuable data point in this phase looking ahead to the next lesson (03-03).
Solutions
Solution 1.
-sV interrogates the service and compares it against Nmap's signatures; with high intensity it sharpens the version. We'd expect something like Jetty 9.4.z-SNAPSHOT (a Java server) instead of the generic "http-proxy" label. It's more useful because "http-proxy" is just a guess by port number, whereas "Jetty 9.4.z" identifies the real software and its version, which is what enables searching for concrete vulnerabilities in 03-03.
Solution 2. Enumeration (this lesson): discovering the null session exists, listing users (jlopez, mgarcia, Administrador), and listing/reading the names in the RRHH share. All of that is inventorying exposed information. Exploitation (later modules): using those users for password attacks (Module 4), or downloading and exfiltrating the RRHH files as part of an access. Here and now: document the flaw (SMB allows a null session and exposes RRHH without authentication) with evidence, and add it to the inventory; don't go beyond what scope authorizes in this phase.
Solution 3. Example A: MySQL 5.5.62 — without the version we'd only know "there's a database"; with the version we can search the NVD/exploit-db for the CVEs specific to MySQL 5.5.62 (03-03). Example B: PHP 7.2.24 / Apache 2.4.29 — concrete unsupported versions whose known CVEs we'll be able to list and prioritize. The version is the search key that connects a service with its list of known vulnerabilities; without it, the next lesson's vulnerability detection would be guesswork.
Conclusion
We've transformed the table of open ports into an inventory of services with versions: we no longer have "3306 open", but "MySQL 5.5.62 exposed to the network on an Ubuntu 4.15 host"; not "80 open", but "Apache 2.4.29 with PHP 7.2.24, with a listable /admin/ and a config.php.bak"; and we've solved mysteries like 54321 (a Werkzeug/Flask development server). Along the way we used -sV, -O, manual banner grabbing, and protocol-specific enumeration (whatweb, nikto, enum4linux, smbclient, snmpwalk, NSE), always identifying and inventorying, without yet assessing severity.
And that's exactly the boundary we cross now. We have a list of software with concrete versions, many of them visibly old (MySQL 5.5, PHP 7.2, jQuery 1.12, an exposed development server, SMB with a null session, SNMP public). The question is no longer "what's there", but "which of this is vulnerable, how severe, and where is it best to start".
In 03-03 Vulnerability Detection, the last lesson of the module, we'll cross this inventory against the known-vulnerability databases (CVE, CPE, NVD, exploit-db), run scanners (Nessus/OpenVAS, nmap --script vuln, nuclei) and, above all, critically validate the results to separate the false positive from the real finding. The result will be a prioritized list of candidate vulnerabilities: the bridge toward the exploitation of Module 4.
Pentesting Course: Penetration Testing Techniques
Module 1: Introduction to Pentesting
- What Is Pentesting?
- Types of Pentesting
- Pentesting Phases
- Ethics and Legality in Pentesting
- Industry Methodologies and Standards
Module 2: Reconnaissance and Information Gathering
- Passive Reconnaissance
- Active Reconnaissance
- Information Gathering Tools
- OSINT and Attack Surface Analysis
Module 3: Scanning and Enumeration
Module 4: Vulnerability Exploitation
- Introduction to Exploitation
- Web Exploitation
- Network Exploitation
- System Exploitation
- Password and Authentication Attacks
Module 5: Post-Exploitation
- Privilege Escalation
- Maintaining Access
- Pivoting and Lateral Movement
- Covering Tracks and Anti-Forensics
