Banner Grabs
Banner Grabs
Undserstanding what server is responding, if it’s even responding sometimes provides clues that the application client or browser does not tell you.
WAF are often configured to only respond to correct responses (if you telnet on port 22 to an ssh server, it’s not actually sending ssh protocols, so WAF blocks), but this is still a test that might provide good info.
IF the server responds at all, then you know routes are good, AND firewall is not blocking it. The application could still be misconfigured, encryption could be failing. Note, you cannot test telnet on another port through an application firewall if it is checking for application fingerprints. Palo Alto firewalls can be configured to check application fingerprints, and they likely are configured for such checks. As long as you don’t have a web application firewall, you can test with simple port checks like this on both linux and windows (and many appliances). ANY response means the port is open. Telnet cannot speak “SSH” in this example, but the banner appeared, letting us know we can reach port 22 at least.
telnet 192.168.1.201 22
Trying 192.168.1.201...
Connected to 192.168.1.201.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.3
^C^C^C^C
Connection closed by foreign host.
IF the connection is refused, that means it is actively blocked by a firewall. It’s not best practice to give a message back from the blocking device, because a bad actor could determine open/closed ports by process of elimination this way.
telnet 192.168.1.201 22222
Connection Refused...
IF the connection times out it could be several things: no network, wrong subnets, wrong ip, no route, wrong port, filtered by application firewall, etc. So a timed out doesn’t tell you anything really. It could mean “blocked with no response”, or it could mean “server isn’t even listening on this port” or it could mean “there is no server up at this ip address”.
telnet 192.168.1.201 22222
Trying 192.168.1.201...
Sometimes the screen will be blank because it cannot read the header or send the proper response headers to continue. Blank or no response, but not a time out, means it did receive a banner, and thus the port is open. If it says Connected or Connecting, the firewall is not blocking and routes are good.
Connection refused typically means the firewall or some other ACL is blocking the connection. Remember, it could be an application inspection too. If you try to use ssh port, but telnet client, an application firewall will reject it (and may or may not respond with a message).
Telnet will not typically say “Unable to Connect” from the client side. Some other clients will say this when a service times out though.
There are many ways to get banner grabs. Here are a few:
Net Cat
$ nc -v somesite.com 22
Connection to somesite.com (162.243.23.116) 22 port [tcp/ssh] succeeded!
SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7
NMAP
$ nmap -sV -p22 somesite.com
Starting Nmap 7.80 ( https://nmap.org ) at 2022-10-13 14:24 CDT
Nmap scan report for somesite.com (162.243.23.116)
Host is up (0.061s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Python
def bannergrabbing(addr, port):
'''Connect to process and return application banner'''
print "Gettig service information for port: ", port
socket.setdefaulttimeout(2)
bannergrabber = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
bannergrabber.connect((addr, port))
bannergrabber.send('WhoAreYou\r\n')
banner = bannergrabber.recv(100)
bannergrabber.close()
print banner, "\n"
except:
print "Cannot connect to port ", port
bannergrabbing("https://foo.com",5061)
Telnet/Bash with Proxy
#!/usr/bin/env bash
proxy_host="example.proxy.local"
proxy_port="8080"
uri="http://www.google.com/"
# This is the STDIN for telnet, keep in mind that this needs to be running
# as long as the request is handled. You can test the result by removing the
# sleep.
send_headers () {
# Note the use of HTTP/1.0. 1.1 would keep the connection open
# and you will need to wait for the 10 second timout below.
echo "GET $uri HTTP/1.0"
echo
echo
# 10 second timeout to keep STDIN open
sleep 10
}
# This reads the telnet output per line, do your stuff here
while read -r line; do
echo "$line"
done < <(telnet "$proxy_host" "$proxy_port" < <(send_headers))
netcat
echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
curl (basic headers)
curl -sI https://grimoire.jamesfraze.com:443
HTTP/1.1 200 OK
Date: Thu, 13 Oct 2022 19:36:22 GMT
Server: Apache
Link: <https://grimoire.jamesfraze.com/wp-json/>; rel="https://api.w.org/"
Link: <https://grimoire.jamesfraze.com/wp-json/wp/v2/pages/10>; rel="alternate"; type="application/json"
Link: <https://grimoire.jamesfraze.com/>; rel=shortlink
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=UTF-8
curl (all headers)
curl -Isvk https://grimoire.jamesfraze.com
* Trying 162.243.23.116:443...
* Connected to somesite.com (162.243.23.116) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=somesite.com
* start date: Apr 12 12:14:19 2023 GMT
* expire date: Jul 11 12:14:18 2023 GMT
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> HEAD / HTTP/1.1
> Host: somesite.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Mon, 15 May 2023 12:48:19 GMT
Date: Mon, 15 May 2023 12:48:19 GMT
< Server: Apache
Server: Apache
< Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: strict-origin-when-cross-origin
< Content-Security-Policy: upgrade-insecure-requests; report-uri https://grimoire.jamesfraze.com
Content-Security-Policy: upgrade-insecure-requests; report-uri https://grimoire.jamesfraze.com
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< Permissions-Policy: accelerometer=(), autoplay=(), camera=(), fullscreen=*, geolocation=(self), gyroscope=(), microphone=(), payment=*
Permissions-Policy: accelerometer=(), autoplay=(), camera=(), fullscreen=*, geolocation=(self), gyroscope=(), microphone=(), payment=*
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< Access-Control-Allow-Origin: null
Access-Control-Allow-Origin: null
< Access-Control-Allow-Methods: GET,PUT,POST,DELETE
Access-Control-Allow-Methods: GET,PUT,POST,DELETE
< Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Headers: Content-Type, Authorization
< X-Content-Security-Policy: img-src *; media-src * data:;
X-Content-Security-Policy: img-src *; media-src * data:;
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Content-Security-Policy: report-uri https://grimoire.jamesfraze.com
Content-Security-Policy: report-uri https://grimoire.jamesfraze.com
< Referrer-Policy: strict-origin-when-cross-origin
Referrer-Policy: strict-origin-when-cross-origin
< Cross-Origin-Embedder-Policy-Report-Only: unsafe-none; report-to="default"
Cross-Origin-Embedder-Policy-Report-Only: unsafe-none; report-to="default"
< Cross-Origin-Embedder-Policy: unsafe-none; report-to="default"
Cross-Origin-Embedder-Policy: unsafe-none; report-to="default"
< Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="default"
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="default"
< Cross-Origin-Resource-Policy: cross-origin
Cross-Origin-Resource-Policy: cross-origin
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< Permissions-Policy: accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), document-domain=(), encrypted-media=(), fullscreen=*, geolocation=(self), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=*, picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), xr-spatial-tracking=(), gamepad=(), serial=(), window-placement=()
Permissions-Policy: accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), document-domain=(), encrypted-media=(), fullscreen=*, geolocation=(self), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=*, picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), xr-spatial-tracking=(), gamepad=(), serial=(), window-placement=()
< Feature-Policy: display-capture 'self'
Feature-Policy: display-capture 'self'
< X-Permitted-Cross-Domain-Policies: none
X-Permitted-Cross-Domain-Policies: none
< Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
< Link: <https://grimoire.jamesfraze.com/wp-json/>; rel="https://api.w.org/"
Link: <https://grimoire.jamesfraze.com/wp-json/>; rel="https://api.w.org/"
< Link: <https://grimoire.jamesfraze.com/wp-json/wp/v2/pages/10>; rel="alternate"; type="application/json"
Link: <https://grimoire.jamesfraze.com/wp-json/wp/v2/pages/10>; rel="alternate"; type="application/json"
< Link: <https://grimoire.jamesfraze.com/>; rel=shortlink
Link: <https://grimoire.jamesfraze.com/>; rel=shortlink
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host somesite.com left intact