One first step when attackers try to tinker with your environment is often referred to as “enumeration”. As I am running multiple web services on my own servers, I am of course curious what all this open source software actually does. So let’s start with enumeration of your web servers. Naturally, I can deep dive into their source code and evaluate their functionality. However, this post shall show you how to find information on your web servers without looking at the code through enumeration.
Let’s start with a remote test. Currently I am at work and could only scan my home network from outside. Let’s do this.
Looking at my home network from outside, we see that there are several ports open. Let’s redo this detection and try to see wether nmap
can get some more information on the services it listed. The -A
flag tells nmap to try to detect the operating system, the versions of software used, to scan for (nmap-) known vulnerabilities and to perform a traceroute to estimate our server location. Also, this time I added the flag -T4
which basically tells nmap to use a faster template scheme. This speeds up the analysis but may be less successful in detecting everything.
1Host is up (0.011s latency).
2Not shown: 994 closed ports
3PORT STATE SERVICE VERSION
423/tcp open ssh OpenSSH 8.3 (protocol 2.0)
553/tcp open domain?
6443/tcp open ssl/http nginx 1.18.0
7| http-robots.txt: 1 disallowed entry
8|_/
9|_http-server-header: nginx/1.18.0
10|_http-title: Jitsi Meet
11| ssl-cert: Subject: commonName=meet.yourhostname.or.ip
12| Subject Alternative Name: DNS:meet.yourhostname.or.ip
13| Not valid before: 2020-08-18T12:17:00
14|_Not valid after: 2020-11-16T12:17:00
15|_ssl-date: TLS randomness does not represent time
16| tls-alpn:
17| h2
18|_ http/1.1
19| tls-nextprotoneg:
20| h2
21|_ http/1.1
222000/tcp open tcpwrapped
235060/tcp open tcpwrapped
248008/tcp open http
25| fingerprint-strings:
26| FourOhFourRequest:
27| HTTP/1.1 302 Found
28| Location: https://:8015/nice%20ports%2C/Tri%6Eity.txt%2ebak
29| Connection: close
30| X-Frame-Options: SAMEORIGIN
31| X-XSS-Protection: 1; mode=block
32| X-Content-Type-Options: nosniff
33| Content-Security-Policy: frame-ancestors
34| GenericLines, HTTPOptions, RTSPRequest, SIPOptions:
35| HTTP/1.1 302 Found
36| Location: https://:8015
37| Connection: close
38| X-Frame-Options: SAMEORIGIN
39| X-XSS-Protection: 1; mode=block
40| X-Content-Type-Options: nosniff
41| Content-Security-Policy: frame-ancestors
42| GetRequest:
43| HTTP/1.1 302 Found
44| Location: https://:8015/
45| Connection: close
46| X-Frame-Options: SAMEORIGIN
47| X-XSS-Protection: 1; mode=block
48| X-Content-Type-Options: nosniff
49|_ Content-Security-Policy: frame-ancestors
50|_http-title: Did not follow redirect to https://yourhostname.or.ip:8015/
51|_https-redirect: ERROR: Script execution failed (use -d to debug)
This time some things changed. While in the simple portscan in the beginning, nmap guessed port 23 would be hosting a telnet service, this time it shows us, there is a OpenSSH server with version 8.3 although you would normally expect it on port 22. Second, port 53 seems to host a dns service. Also, nmap detected that port 443 is actually hosting a webserver running TLS and also that there is Jitsi Meet running on it. For ports 2000 and 5060, we still do not know what’s that. Finally, port 8008 has another webserver on it, however we do not have further information on it.
In fact, all of this is correct. But how did nmap get information on the changed port of ssh? The answer here is banner grabbing. That’s the same process that also shodan.io uses. In short, you open a TCP socket to the port and start receiving bytes from it. I have quickly scripted this in python to demonstrate.
1##!/usr/bin/env python3
2import socket
3import argparse
4
5def main(args):
6 addr = (args.host, args.port)
7 s = socket.socket()
8 s.connect(addr)
9 print(s.recv(1024).decode("utf-8"))
10
11if __name__ == '__main__':
12 prs = argparse.ArgumentParser("Banner grabbing in python")
13 prs.add_argument("--host", type=str, required=True)
14 prs.add_argument("--port", type=int, required=True)
15 args = prs.parse_args()
16 main(args)
If I run this against the skewed service, we get the same information also nmap got.
So, the remaining question is what changes if we have local access to a server and want to check for available services. Long answer short, not much. I scanned my machine with nmap localhost -A
also locally and found some more services which are only published locally or in the internal network. I hope this enables you to get started with nmap and trying to find out, what’s actually on your network. By the way you can also scan a whole network with the CIDR notation like
1nmap 192.168.178.1/24
Before your start with happy network scanning, please keep in mind that you should only do this on your own machines and networks.