Macbook OSX: Using gping over a Zero Trust Network Client (like Zscaler)

Once you start using a zero trust network, the first causality is normally the Ping command. The gping (Graphical Ping) command line displays a color coded realtime graph of continuous pings to a specified host and it supports specifying alternate interfaces/gateways.

First lets find which interface to use. The “arp -a” command is used to display the ARP cache on a computer, including both dynamic and static entries. This command is similar to the arp command without any options, but it also displays the status of the entries in the cache.

$ arp -a
unfisecuregateway (192.168.0.1) at 74:83:c2:d0:c8:cd on en0 ifscope [ethernet]
amazon-ce482021d.localdomain (192.168.0.66) at 8:7c:39:e3:de:af on en0 ifscope [ethernet]
km98e898.localdomain (192.168.0.117) at 0:17:c8:87:5a:f7 on en0 ifscope [ethernet]
? (192.168.0.210) at 9c:14:63:5c:aa:de on en0 ifscope [ethernet]
? (192.168.0.211) at 9c:14:63:5c:aa:ac on en0 ifscope [ethernet]
? (192.168.0.212) at 9c:14:63:5c:aa:e1 on en0 ifscope [ethernet]
? (192.168.0.213) at 9c:14:63:5c:ab:20 on en0 ifscope [ethernet]
? (192.168.0.214) at 9c:14:63:5c:aa:9 on en0 ifscope [ethernet]
? (192.168.0.215) at 9c:14:63:5c:aa:74 on en0 ifscope [ethernet]
? (192.168.0.216) at 9c:14:63:5c:ab:64 on en0 ifscope [ethernet]
? (192.168.0.217) at 9c:14:63:2d:23:5f on en0 ifscope [ethernet]
? (192.168.0.255) at ff:ff:ff:ff:ff:ff on en0 ifscope [ethernet]
? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
? (239.255.255.250) at 1:0:5e:7f:ff:fa on en0 ifscope permanent [ethernet]

You will see I have an en0 interface. Lets try an gping via the en0 interface:

$ brew install gping
$ gping -i en0 google.com
google.com (172.217.170.110)             last 27.274ms min 26.945ms  max 134.849ms avg 41.896ms  jtr 2.916ms   p95 107.494ms t/o 0
130.606ms│
         │
         │                   ⢀
         │                   ⢸
         │                   ⢸
112.88ms │                   ⢸
         │                   ⣼
         │                   ⣿
         │        ⡆          ⣿
95.154ms │   ⢀    ⡇          ⣿
         │   ⢸    ⡇          ⣿
         │   ⢸    ⡇          ⣿
         │   ⢸   ⢠⡇          ⣿          ⢀
77.428ms │   ⣼   ⢸⡇      ⡆   ⣿          ⢸
         │   ⣿   ⢸⡇      ⡇  ⢸ ⡇         ⢸
         │   ⣿   ⢸⡇     ⢰⡇⢀ ⢸ ⡇         ⢸
         │   ⣿   ⢸⢇     ⢸⡇⢸ ⢸ ⡇         ⡇⡇
59.702ms │   ⡟⡄  ⢸⢸     ⢸⢇⣼ ⢸ ⡇         ⡇⡇
         │   ⡇⡇  ⢸⢸     ⡸⢸⡏⡆⢸ ⡇         ⡇⡇
         │   ⡇⡇  ⢸⢸     ⡇⢸⡇⡇⢸ ⡇     ⡆   ⡇⡇
         │   ⡇⡇  ⢸⢸ ⢰   ⡇⢸⠃⡇⢸ ⡇    ⢀⢇   ⡇⡇
41.976ms │  ⢸ ⡇  ⡇⢸ ⣼  ⢀⠇⢸ ⡇⡎ ⡇⡆   ⢸⢸   ⡇⡇
         │  ⢸ ⡇  ⡇⢸ ⡿⡀ ⢸   ⢇⡇ ⣷⡇   ⢸⢸  ⢸ ⢸
         │  ⢸ ⡇  ⡇⢸ ⡇⣇⢆⡸   ⢸⡇ ⣿⢱   ⡸⠸⡀⢠⢸ ⢸
         │⣀ ⡸ ⡇  ⡇⢸⢸ ⡿⠈⠇   ⢸⡇ ⡇⢸ ⢀⡀⡇ ⡇⡜⢿ ⢸
24.25ms  │ ⠉  ⠉⠉⠉⠁⠈⠉ ⠁     ⠈   ⠈⠉⠁⠈⠁ ⠉⠁⠈ ⠈⠁
         └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  11:39:10                                                             11:39:25                                                    11:39:40

Mac OSX : Tracing which network interface will be used to route traffic to an IP/DNS address

If you have multiple connections on your device (and maybe you have a zero trust client installed); how do you find out which network interface on your device will be used to route the traffic?

Below is a route get request for googles DNS service:

$ route get 8.8.8.8

   route to: dns.google
destination: dns.google
    gateway: 100.64.0.1
  interface: utun3
      flags: <UP,GATEWAY,HOST,DONE,WASCLONED,IFSCOPE,IFREF>
 recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
       0         0         0         0         0         0      1400         0

If you have multiple interfaces enabled, then the first item in the Service Order will be used. If you want to see the default interface for your device:

$ route -n get 0.0.0.0 | grep interface
  interface: en0

Lets go an see whats going on in my default interface:

$ netstat utun3 | grep ESTABLISHED
tcp4       0      0  100.64.0.1.65271       jnb02s11-in-f4.1.https ESTABLISHED
tcp4       0      0  100.64.0.1.65269       jnb02s02-in-f14..https ESTABLISHED
tcp4       0      0  100.64.0.1.65262       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65261       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65260       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65259       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65258       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65257       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65256       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65255       192.0.73.2.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65254       192.0.78.23.https      ESTABLISHED
tcp4       0      0  100.64.0.1.65253       192.0.76.3.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65252       192.0.78.23.https      ESTABLISHED
tcp4       0      0  100.64.0.1.65251       192.0.76.3.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65250       192.0.78.23.https      ESTABLISHED
tcp4       0      0  100.64.0.1.65249       192.0.76.3.https       ESTABLISHED
tcp4       0      0  100.64.0.1.65248       ec2-13-244-140-3.https ESTABLISHED
tcp4       0      0  100.64.0.1.65247       192.0.73.2.https       ESTABLISHED

Finding and Setting the Maximum Transmission Unit (MTU) on a Windows Machine

If you have just changed ISPs or moved house and your internet suddenly starts misbehaving the likelihood is your Maximum Transmission Unit (MTU) is set too high for your ISP. The default internet facing MTU is 1500 bytes, BUT depending on your setup, this often needs to be set much lower.

Step 1:

First check your current MTU across all your ipv4 interfaces using netsh:

netsh interface ipv4 show subinterfaces
   MTU  MediaSenseState   Bytes In  Bytes Out  Interface
------  ---------------  ---------  ---------  -------------
4294967295                1          0          0  Loopback Pseudo-Interface 1
  1492                1        675        523  Local Area Connection

As you can see, the Local Area Connection interface is set to a 1492 bytes MTU. So how do we find out what it should be? We are going to send a fixed size Echo packet out, and tell the network not to fragment this packet. If somewhere along the line this packet is too big then this request will fail.

Next enter (if it fails then you know your MTU is too high):

ping 8.8.8.8 -f -l 1492

Procedure to find optimal MTU:

For PPPoE, your Max MTU should be no more than 1492 to allow space for the 8 byte PPPoE “wrapper”. 1492 + 8 = 1500. The ping test we will be doing does not include the IP/ICMP header of 28 bytes. 1500 – 28 = 1472. Include the 8 byte PPPoE wrapper if your ISP uses PPPoE and you get 1500 – 28 – 8 = 1464.

The best value for MTU is that value just before your packets get fragmented. Add 28 to the largest packet size that does not result in fragmenting the packets (since the ping command specifies the ping packet size, not including the IP/ICMP header of 28 bytes), and this is your Max MTU setting.

The below is an automated ping sweep, that tests various packet sizes until it fails (increasing in 10 bytes per iteration):

C:\Windows\system32>for /l %i in (1360,10,1500) do @ping -n 1 -w 8.8.8.8 -l %i -f

Pinging 8.8.8.8. with 1400 bytes of data:
Reply from 8.8.8.8: bytes=1400 time=6ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 6ms, Maximum = 6ms, Average = 6ms

Pinging 8.8.8.8 with 1401 bytes of data:
Reply from 8.8.8.8: bytes=1401 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

Pinging 8.8.8.8 with 1402 bytes of data:
Reply from 8.8.8.8: bytes=1402 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms

Pinging 8.8.8.8 with 1403 bytes of data:
Reply from 8.8.8.8: bytes=1403 time<1ms TTL=64

Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms 

Once you find the MTU, you can set it as per below:

set subinterface “Local Area Connection” mtu=1360 store=persistent

Finding and Setting the Maximum Transmission Unit (MTU) on Mac/OSX

If you have just changed ISPs or moved house and your internet suddenly starts misbehaving the likelihood is your Maximum Transmission Unit (MTU) is set too high for your ISP. The default internet facing MTU is 1500 bytes, BUT depending on your setup, this often needs to be set much lower.

Step 1:

First check your current MTU.

$ networksetup -getMTU en0
Active MTU: 1500 (Current Setting: 1500)

As you can see, the Mac is set to 1500 bytes MTU. So how do we find out what it should be? We are going to send a fixed size Echo packet out, and tell the network not to fragment this packet. If somewhere along the line this packet is too big then this request will fail.

Next enter:

$ ping -D -s 1500 www.google.com
PING www.google.com (172.217.170.100): 1500 data bytes
ping: sendto: Message too long
ping: sendto: Message too long
Request timeout for icmp_seq 0
ping: sendto: Message too long
Request timeout for icmp_seq 1
ping: sendto: Message too long

Ok, so our MTU is too high.

Procedure to find optimal MTU:

Hint: For PPPoE, your Max MTU should be no more than 1492 to allow space for the 8 byte PPPoE “wrapper”. 1492 + 8 = 1500. The ping test we will be doing does not include the IP/ICMP header of 28 bytes. 1500 – 28 = 1472. Include the 8 byte PPPoE wrapper if your ISP uses PPPoE and you get 1500 – 28 – 8 = 1464.

The best value for MTU is that value just before your packets get fragmented. Add 28 to the largest packet size that does not result in fragmenting the packets (since the ping command specifies the ping packet size, not including the IP/ICMP header of 28 bytes), and this is your Max MTU setting.

The below is an automated ping sweep, that tests various packet sizes until it fails (increasing in 10 bytes per iteration):

$ ping -g 1300 -G 1600 -h 10 -D www.google.com
PING www.google.com (172.217.170.100): (1300 ... 1600) data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
Request timeout for icmp_seq 5
Request timeout for icmp_seq 6
ping: sendto: Message too long
Request timeout for icmp_seq 7

As you can see it failed on the 7th attempt (giving you a 1300 + 60 MTU).

Once you find the MTU, you can set it as per below:

$ ping -D -s 1360 www.google.com
PING www.google.com (172.217.170.100): 1370 data bytes
Request timeout for icmp_seq 0

So I can set my MTU as 1360 + 28 = 1386:

networksetup -setMTU en0 1386

Macbook: Querying DNS using the Host Command

1. Find a list of IP addresses linked to a domain

To find the IP address for a particular domain, simply pass the target domain name as an argument after the host command.

$ host andrewbaker.ninja
andrewbaker.ninja has address 13.244.140.33

For a comprehensive lookup using the verbose mode, use -a or -v flag option.

$ host -a andrewbaker.ninja
Trying "andrewbaker.ninja"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45489
;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;andrewbaker.ninja.		IN	ANY

;; ANSWER SECTION:
andrewbaker.ninja.	300	IN	A	13.244.140.33
andrewbaker.ninja.	21600	IN	NS	ns-1254.awsdns-28.org.
andrewbaker.ninja.	21600	IN	NS	ns-1514.awsdns-61.org.
andrewbaker.ninja.	21600	IN	NS	ns-1728.awsdns-24.co.uk.
andrewbaker.ninja.	21600	IN	NS	ns-1875.awsdns-42.co.uk.
andrewbaker.ninja.	21600	IN	NS	ns-491.awsdns-61.com.
andrewbaker.ninja.	21600	IN	NS	ns-496.awsdns-62.com.
andrewbaker.ninja.	21600	IN	NS	ns-533.awsdns-02.net.
andrewbaker.ninja.	21600	IN	NS	ns-931.awsdns-52.net.
andrewbaker.ninja.	900	IN	SOA	ns-1363.awsdns-42.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

Received 396 bytes from 100.64.0.1#53 in 262 ms

The -a option is used to find all Domain records and Zone information. You can also notice the local DNS server address utilised for the lookup.

2. Reverse Lookup

The command below performs a reverse lookup on the IP address and displays the hostname or domain name.

$ host 13.244.140.33
33.140.244.13.in-addr.arpa domain name pointer ec2-13-244-140-33.af-south-1.compute.amazonaws.com.

3. To find Domain Name servers

Use the -t option to get the domain name servers. It’s used to specify the query type. Below we pass the -t argument to find nameservers of a specific domain. NS record specifies the authoritative nameservers.

$ host -t ns andrewbaker.ninja
andrewbaker.ninja name server ns-1254.awsdns-28.org.
andrewbaker.ninja name server ns-1514.awsdns-61.org.
andrewbaker.ninja name server ns-1728.awsdns-24.co.uk.
andrewbaker.ninja name server ns-1875.awsdns-42.co.uk.
andrewbaker.ninja name server ns-491.awsdns-61.com.
andrewbaker.ninja name server ns-496.awsdns-62.com.
andrewbaker.ninja name server ns-533.awsdns-02.net.
andrewbaker.ninja name server ns-931.awsdns-52.net.

4. To query certain nameserver for a specific domain

To query details about a specific authoritative domain name server, use the below command.

$ host google.com olga.ns.cloudflare.com
Using domain server:
Name: olga.ns.cloudflare.com
Address: 173.245.58.137#53
Aliases:

google.com has address 172.217.170.14
google.com has IPv6 address 2c0f:fb50:4002:804::200e
google.com mail is handled by 10 smtp.google.com.

5. To find domain MX records

To get a list of a domain’s MX ( Mail Exchanger ) records.

$ host -t MX google.com
google.com mail is handled by 10 smtp.google.com.

6. To find domain TXT records

To get a list of a domain’s TXT ( human-readable information about a domain server ) record.

$ host -t txt google.com
google.com descriptive text "docusign=1b0a6754-49b1-4db5-8540-d2c12664b289"
google.com descriptive text "v=spf1 include:_spf.google.com ~all"
google.com descriptive text "google-site-verification=TV9-DBe4R80X4v0M4U_bd_J9cpOJM0nikft0jAgjmsQ"
google.com descriptive text "facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
google.com descriptive text "atlassian-domain-verification=5YjTmWmjI92ewqkx2oXmBaD60Td9zWon9r6eakvHX6B77zzkFQto8PQ9QsKnbf4I"
google.com descriptive text "onetrust-domain-verification=de01ed21f2fa4d8781cbc3ffb89cf4ef"
google.com descriptive text "globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8="
google.com descriptive text "docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
google.com descriptive text "apple-domain-verification=30afIBcvSuDV2PLX"
google.com descriptive text "google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o"
google.com descriptive text "webexdomainverification.8YX6G=6e6922db-e3e6-4a36-904e-a805c28087fa"
google.com descriptive text "MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB"

7. To find domain SOA record

To get a list of a domain’s Start of Authority record

$ host -t soa google.com
google.com has SOA record ns1.google.com. dns-admin.google.com. 505465897 900 900 1800 60

Use the command below to compare the SOA records from all authoritative nameservers for a particular zone (the specific portion of the DNS namespace).

$ host -C google.com
Nameserver 216.239.36.10:
	google.com has SOA record ns1.google.com. dns-admin.google.com. 505465897 900 900 1800 60
Nameserver 216.239.38.10:
	google.com has SOA record ns1.google.com. dns-admin.google.com. 505465897 900 900 1800 60
Nameserver 216.239.32.10:
	google.com has SOA record ns1.google.com. dns-admin.google.com. 505465897 900 900 1800 60
Nameserver 216.239.34.10:
	google.com has SOA record ns1.google.com. dns-admin.google.com. 505465897 900 900 1800 60

8. To find domain CNAME records

CNAME stands for canonical name record. This DNS record is responsible for redirecting one domain to another, which means it maps the original domain name to an alias.

To find out the domain CNAME DNS records, use the below command.

$ host -t cname www.yahoo.com
www.yahoo.com is an alias for new-fp-shed.wg1.b.yahoo.com.
$ dig www.yahoo.com
]
; <<>> DiG 9.10.6 <<>> www.yahoo.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45503
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.yahoo.com.			IN	A

;; ANSWER SECTION:
www.yahoo.com.		12	IN	CNAME	new-fp-shed.wg1.b.yahoo.com.
new-fp-shed.wg1.b.yahoo.com. 38	IN	A	87.248.100.215
new-fp-shed.wg1.b.yahoo.com. 38	IN	A	87.248.100.216

;; Query time: 128 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Jan 30 17:07:55 SAST 2023
;; MSG SIZE  rcvd: 106

In the above shown example CNAME entry, if you want to reach “www.yahoo.com”, your computer’s DNS resolver will first fire an address lookup for “www.yahoo.com“. Your resolver then sees that it was returned a CNAME record of “new-fp-shed.wg1.b.yahoo.com“, and in response it will now fire another lookup for “new-fp-shed.wg1.b.yahoo.com“. It will then be returned the A record. So its important to note here is that there are two separate and independent DNS lookups performed by the resolver in order to convert a CNAME into a usable A record.

9. To find domain TTL information

TTL Stands for Time to live. It is a part of the Domain Name Server. It is automatically set by an authoritative nameserver for each DNS record.

In simple words, TTL refers to how long a DNS server caches a record before refreshing the data. Use the below command to see the TTL information of a domain name (in the example below its 300 seconds/5 minutes).

$ host -v -t a andrewbaker.ninja
Trying "andrewbaker.ninja"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27738
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;andrewbaker.ninja.		IN	A

;; ANSWER SECTION:
andrewbaker.ninja.	300	IN	A	13.244.140.33

Received 51 bytes from 8.8.8.8#53 in 253 ms

Hacking: Using a Macbook and Nikto to Scan your Local Network

Nikto is becoming one of my favourite tools. I like it because of its wide ranging use cases and its simplicity. So whats an example use case for Nikto? When I am bored right now and so I am going to hunt around my local network and see what I can find…

# First install Nikto
brew install nikto
# Now get my ipaddress range
ifconfig
# Copy my ipaddress into to ipcalculator to get my cidr block
eth0      Link encap:Ethernet  HWaddr 00:0B:CD:1C:18:5A
          inet addr:172.16.25.126  Bcast:172.16.25.63  Mask:255.255.255.224
          inet6 addr: fe80::20b:cdff:fe1c:185a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2341604 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2217673 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:293460932 (279.8 MiB)  TX bytes:1042006549 (993.7 MiB)
          Interrupt:185 Memory:f7fe0000-f7ff0000
# Get my Cidr range (brew install ipcalc)
ipcalc 172.16.25.126
cp363412:~ $ ipcalc 172.16.25.126
Address:   172.16.25.126        10101100.00010000.00011001. 01111110
Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
=>
Network:   172.16.25.0/24       10101100.00010000.00011001. 00000000
HostMin:   172.16.25.1          10101100.00010000.00011001. 00000001
HostMax:   172.16.25.254        10101100.00010000.00011001. 11111110
Broadcast: 172.16.25.255        10101100.00010000.00011001. 11111111
Hosts/Net: 254                   Class B, Private Internet
# Our NW range is "Network:   172.16.25.0/24"

Now lets pop across to nmap to get a list of active hosts in my network

# Now we run a quick nmap scan for ports 80 and 443 across the entire range looking for any hosts that respond and dump the results into a grepable file
nmap -p 80,433 172.16.25.0/24 -oG webhosts.txt
# View the list of hosts
cat webhosts.txt
$ cat webhosts.txt
# Nmap 7.93 scan initiated Wed Jan 25 20:17:42 2023 as: nmap -p 80,433 -oG webhosts.txt 172.16.25.0/26
Host: 172.16.25.0 ()	Status: Up
Host: 172.16.25.0 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.1 ()	Status: Up
Host: 172.16.25.1 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.2 ()	Status: Up
Host: 172.16.25.2 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.3 ()	Status: Up
Host: 172.16.25.3 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.4 ()	Status: Up
Host: 172.16.25.4 ()	Ports: 80/open/tcp//http///, 433/open/tcp//nnsp///
Host: 172.16.25.5 ()	Status: Up

Next we want to grep this webhost file and send all the hosts that responded to the port probe of to Nikto for scanning. To do this we can use some linux magic. First we cat to read the output stored in our webhosts.txt document. Next we use awk. This is a Linux tool that will help search for the patterns. In the command below we are asking it to look for “Up” (meaning the host is up). Then we tell it to print $2, which means to print out the second word in the line that we found the word “Up” on, i.e. to print the IP address. Finally, we send that data to a new file called niktoscan.txt.

cat webhosts.txt | awk '/Up$/{print $2}' | cat >> niktoscan.txt
cat niktoscan.txt
$ cat niktoscan.txt
172.16.25.0
172.16.25.1
172.16.25.2
172.16.25.3
172.16.25.4
172.16.25.5
172.16.25.6
172.16.25.7
172.16.25.8
172.16.25.9
172.16.25.10
...

Now let nikto do its stuff:

nikto -h niktoscan.txt -ssl >> niktoresults.txt
# Lets check what came back
cat niktoresults.txt

Mac OS X: Perform basic vulnerability checks with nmap vulners scripts

This is a very short post to help anyone quickly setup vulnerability checking for a site they own (and have permission to scan). I like the vulners scripts as they cover a lot of basic ground quickly with one script.

## First go to your NMAP script directory
$ cd /usr/local/share/nmap/scripts
## Now install vulners
git clone https://github.com/vulnersCom/nmap-vulners.git
## Now copy the files up a directory
$ cd nmap-vulners
$ ls
LICENSE				example.png			http-vulners-regex.json		paths_regex_example.png		vulners.nse
README.md			http-vulners-paths.txt		http-vulners-regex.nse		simple_regex_example.png
$ sudo cp *.* ..
## Now update NMAP NSE script database
$ nmap --script-updatedb
## Now run the scripts
$ nmap -sV --script vulners tesla.com
## Now do a wildcard scan
$ nmap --script "http-*" tesla.com

Mac OS X: View the details of a websites supported TLS certificates from terminal

The below script will give you basic information on a websites certificate:

$ curl --insecure -vvI https://andrewbaker.ninja 2>&1 | awk 'BEGIN { cert=0 } /^\* SSL connection/ { cert=1 } /^\*/ { if (cert) print }'
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=andrewbaker.ninja
*  start date: Nov  4 23:00:13 2022 GMT
*  expire date: Feb  2 23:00:12 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.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
* Connection #0 to host andrewbaker.ninja left intact

NMAP is provides a simple way to get a list of available ciphers from a host website / server. Additionally, nmap provides a strength rating of strong, weak, or unknown for each available cipher. First, download the ssl-enum-ciphers.nse nmap script (explanation here). Then from the same directory as the script, run nmap as follows:

$ nmap --script ssl-enum-ciphers -p 443 andrewbaker.ninja
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-11 10:40 SAST
Nmap scan report for andrewbaker.ninja (13.244.140.33)
Host is up (0.051s latency).
rDNS record for 13.244.140.33: ec2-13-244-140-33.af-south-1.compute.amazonaws.com

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.3:
|     ciphers:
|       TLS_AKE_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|       TLS_AKE_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|     cipher preference: server
|_  least strength: A

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

Next up (and probably my favourite), sslscan is a really decent tool because it tests connecting with TLS and SSL including obsolete SSL versions. It then reports about the server’s cipher suites and certificate.

$ brew install sslscan
$ sslscan andrewbaker.ninja
Version: 2.0.15
OpenSSL 3.0.7 1 Nov 2022

Connected to 13.244.140.33

Testing SSL server andrewbaker.ninja on port 443 using SNI name andrewbaker.ninja

  SSL/TLS Protocols:
SSLv2     disabled
SSLv3     disabled
TLSv1.0   enabled
TLSv1.1   enabled
TLSv1.2   enabled
TLSv1.3   enabled

  TLS Fallback SCSV:
Server supports TLS Fallback SCSV

  TLS renegotiation:
Secure session renegotiation supported

  TLS Compression:
OpenSSL version does not support compression
Rebuild with zlib1g-dev package for zlib support

  Heartbleed:
TLSv1.3 not vulnerable to heartbleed
TLSv1.2 not vulnerable to heartbleed
TLSv1.1 not vulnerable to heartbleed
TLSv1.0 not vulnerable to heartbleed

  Supported Server Cipher(s):
Preferred TLSv1.3  256 bits  TLS_AES_256_GCM_SHA384        Curve P-256 DHE 256
Accepted  TLSv1.3  256 bits  TLS_CHACHA20_POLY1305_SHA256  Curve P-256 DHE 256
Accepted  TLSv1.3  128 bits  TLS_AES_128_GCM_SHA256        Curve P-256 DHE 256
Preferred TLSv1.2  256 bits  ECDHE-RSA-AES256-GCM-SHA384   Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-GCM-SHA256   Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA          Curve P-256 DHE 256
Accepted  TLSv1.2  128 bits  ECDHE-RSA-AES128-SHA256       Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  ECDHE-RSA-AES256-SHA384       Curve P-256 DHE 256
Accepted  TLSv1.2  256 bits  AES256-GCM-SHA384
Accepted  TLSv1.2  128 bits  AES128-GCM-SHA256
Accepted  TLSv1.2  256 bits  AES256-SHA
Accepted  TLSv1.2  128 bits  AES128-SHA
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-GCM-SHA384     DHE 2048 bits
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-GCM-SHA256     DHE 2048 bits
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA256         DHE 2048 bits
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-SHA256         DHE 2048 bits
Accepted  TLSv1.2  256 bits  DHE-RSA-AES256-SHA            DHE 2048 bits
Accepted  TLSv1.2  128 bits  DHE-RSA-AES128-SHA            DHE 2048 bits
Preferred TLSv1.1  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.1  256 bits  ECDHE-RSA-AES256-SHA          Curve P-256 DHE 256
Accepted  TLSv1.1  256 bits  AES256-SHA
Accepted  TLSv1.1  128 bits  AES128-SHA
Accepted  TLSv1.1  256 bits  DHE-RSA-AES256-SHA            DHE 2048 bits
Accepted  TLSv1.1  128 bits  DHE-RSA-AES128-SHA            DHE 2048 bits
Preferred TLSv1.0  128 bits  ECDHE-RSA-AES128-SHA          Curve P-256 DHE 256
Accepted  TLSv1.0  256 bits  ECDHE-RSA-AES256-SHA          Curve P-256 DHE 256
Accepted  TLSv1.0  256 bits  AES256-SHA
Accepted  TLSv1.0  128 bits  AES128-SHA
Accepted  TLSv1.0  256 bits  DHE-RSA-AES256-SHA            DHE 2048 bits
Accepted  TLSv1.0  128 bits  DHE-RSA-AES128-SHA            DHE 2048 bits

  Server Key Exchange Group(s):
TLSv1.3  128 bits  secp256r1 (NIST P-256)
TLSv1.3  192 bits  secp384r1 (NIST P-384)
TLSv1.3  260 bits  secp521r1 (NIST P-521)
TLSv1.2  128 bits  secp256r1 (NIST P-256)
TLSv1.2  192 bits  secp384r1 (NIST P-384)
TLSv1.2  260 bits  secp521r1 (NIST P-521)

  SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    2048

Subject:  andrewbaker.ninja
Altnames: DNS:andrewbaker.ninja, DNS:www.andrewbaker.ninja
Issuer:   Zscaler Intermediate Root CA (zscaler.net) (t)

Not valid before: May  6 06:30:35 2023 GMT
Not valid after:  May 20 06:30:35 2023 GMT

If you want a detailed dump of the certificate run (you will need openssl installed):

$ openssl s_client -connect andrewbaker.ninja:443 </dev/null 2>/dev/null | openssl x509 -inform pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            03:bd:20:6e:ef:67:55:93:2a:a8:90:9f:40:e4:b2:a8:c0:fe
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Let's Encrypt, CN = R3
        Validity
            Not Before: Nov  4 23:00:13 2022 GMT
            Not After : Feb  2 23:00:12 2023 GMT
        Subject: CN = andrewbaker.ninja
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:c8:30:00:b3:f0:fb:03:10:90:57:4a:df:7f:28:
                    34:b9:2e:94:1a:28:29:41:2b:88:48:3b:c0:48:2a:
                    f0:62:3d:57:0d:32:db:30:9b:c5:98:11:b3:14:a7:
                    a8:e0:30:1d:d7:ec:cc:86:6f:d2:f1:7b:a4:70:9c:
                    98:e0:63:34:ae
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                B9:28:D2:09:38:B0:B1:03:77:DA:8F:C6:AD:2E:51:EF:0F:7F:23:4F
            X509v3 Authority Key Identifier:
                keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6

            Authority Information Access:
                OCSP - URI:http://r3.o.lencr.org
                CA Issuers - URI:http://r3.i.lencr.org/

            X509v3 Subject Alternative Name:
                DNS:andrewbaker.ninja, DNS:www.andrewbaker.ninja
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org

            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : B7:3E:FB:24:DF:9C:4D:BA:75:F2:39:C5:BA:58:F4:6C:
                                5D:FC:42:CF:7A:9F:35:C4:9E:1D:09:81:25:ED:B4:99
                    Timestamp : Nov  5 00:00:13.652 2022 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:46:02:21:00:89:98:62:15:D5:40:1D:80:9D:40:4B:
                                31:B1:E3:C5:3B:65:41:11:4D:98:D2:E1:23:16:45:0D:
                                DA:08:FE:72:AB:02:21:00:A7:F0:5D:49:63:4F:91:4C:
                                CF:60:8D:FF:26:F6:0B:1B:0C:47:9C:B6:70:57:7C:68:
                                AB:F0:9B:35:48:34:08:A4
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 7A:32:8C:54:D8:B7:2D:B6:20:EA:38:E0:52:1E:E9:84:
                                16:70:32:13:85:4D:3B:D2:2B:C1:3A:57:A3:52:EB:52
                    Timestamp : Nov  5 00:00:14.177 2022 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:21:00:E1:8B:7F:3F:75:05:20:8A:27:3D:30:
                                64:BB:4B:FE:EF:24:C9:7E:85:6C:6D:DF:16:ED:BE:23:
                                9C:97:67:E1:DD:02:20:60:89:B6:D9:0F:BE:C4:E0:7B:
                                05:E1:EE:6D:0B:2D:78:C9:58:AA:0F:10:C0:34:FE:79:
                                FA:63:DD:2D:50:01:5B
    Signature Algorithm: sha256WithRSAEncryption
         4a:54:e0:ec:05:b8:58:ef:44:de:a8:5f:89:fc:1d:cb:86:39:
         05:1d:d3:b2:57:73:bd:6d:11:e5:c2:fd:cd:1a:6b:ee:62:11:
         f8:94:6b:22:b9:16:d6:e3:95:ed:04:9e:7c:ba:1b:3e:5f:dc:
         4f:a0:ae:58:ec:3c:25:a0:41:a5:c8:b9:c8:7a:3c:2f:1f:17:
         60:e8:7d:f0:a2:8e:0d:45:cb:7b:b1:06:13:75:3b:b0:cb:f6:
         6e:2f:71:70:6a:55:96:34:58:db:42:06:5a:7f:78:00:8f:7d:
         e3:83:02:30:82:49:52:38:da:07:6b:c3:ba:ad:09:1e:7e:33:
         0c:f5:0b:49:33:9d:b7:4e:1a:16:c2:ef:47:6f:ec:02:03:4a:
         84:75:bb:30:6e:8a:b4:22:da:d6:ac:43:5d:9b:3c:8b:2a:13:
         af:2b:2e:ab:02:58:dd:80:73:04:8c:dc:2e:48:71:ae:57:c4:
         0e:40:8c:6d:52:b5:91:0c:6b:0d:5e:98:01:6f:09:d1:3a:1b:
         41:7c:70:cc:66:9a:89:b3:b7:27:3d:6f:62:10:66:bb:63:67:
         59:08:ed:7e:c0:c3:31:1c:89:dd:ce:f2:6f:42:fd:42:21:94:
         c3:27:6e:d9:ea:d1:5f:5a:6f:58:26:eb:3e:ba:a6:ee:ed:45:
         00:99:e3:9e
-----BEGIN CERTIFICATE-----
MIIEdTCCA12gAwIBAgISA70gbu9nVZMqqJCfQOSyqMD+MA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMjExMDQyMzAwMTNaFw0yMzAyMDIyMzAwMTJaMBwxGjAYBgNVBAMT
EWFuZHJld2Jha2VyLm5pbmphMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyDAA
s/D7AxCQV0rffyg0uS6UGigpQSuISDvASCrwYj1XDTLbMJvFmBGzFKeo4DAd1+zM
hm/S8XukcJyY4GM0rqOCAmQwggJgMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAU
BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUuSjS
CTiwsQN32o/GrS5R7w9/I08wHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsU
wsYwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5j
ci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8wMwYDVR0R
BCwwKoIRYW5kcmV3YmFrZXIubmluamGCFXd3dy5hbmRyZXdiYWtlci5uaW5qYTBM
BgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUFBwIB
FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQUGCisGAQQB1nkCBAIEgfYE
gfMA8QB3ALc++yTfnE26dfI5xbpY9Gxd/ELPep81xJ4dCYEl7bSZAAABhEUWgVQA
AAQDAEgwRgIhAImYYhXVQB2AnUBLMbHjxTtlQRFNmNLhIxZFDdoI/nKrAiEAp/Bd
SWNPkUzPYI3/JvYLGwxHnLZwV3xoq/CbNUg0CKQAdgB6MoxU2LcttiDqOOBSHumE
FnAyE4VNO9IrwTpXo1LrUgAAAYRFFoNhAAAEAwBHMEUCIQDhi38/dQUgiic9MGS7
S/7vJMl+hWxt3xbtviOcl2fh3QIgYIm22Q++xOB7BeHubQsteMlYqg8QwDT+efpj
3S1QAVswDQYJKoZIhvcNAQELBQADggEBAEpU4OwFuFjvRN6oX4n8HcuGOQUd07JX
c71tEeXC/c0aa+5iEfiUayK5Ftbjle0Enny6Gz5f3E+grljsPCWgQaXIuch6PC8f
F2DoffCijg1Fy3uxBhN1O7DL9m4vcXBqVZY0WNtCBlp/eACPfeODAjCCSVI42gdr
w7qtCR5+Mwz1C0kznbdOGhbC70dv7AIDSoR1uzBuirQi2tasQ12bPIsqE68rLqsC
WN2AcwSM3C5Ica5XxA5AjG1StZEMaw1emAFvCdE6G0F8cMxmmomztyc9b2IQZrtj
Z1kI7X7AwzEcid3O8m9C/UIhlMMnbtnq0V9ab1gm6z66pu7tRQCZ454=
-----END CERTIFICATE-----

Mac OS X: Using dig and whois to resolve DNS issues between your DNS server and the authoritive DNS Server

When debugging DNS issues its important to verify the local DNS response with the authoritive DNS nameserver. With dig we can directly query the authoritative name servers for a domain, these are the DNS servers that hold the authoritative records for the domains DNS zone; the source of truth. If a correct response is received from the authoritative DNS server but not when querying against your own DNS server then you should investigate why your local DNS server is not able to resolve the record.

Lets first see where our DNS traffic is going:

$ scutil --dns | grep 'nameserver\[[0-9]*\]'
  nameserver[0] : 100.64.0.1
  nameserver[0] : 192.168.0.
  nameserver[0] : 192.168.0.1

The first DNS server in the list – at 100.64.0.1 will need to accept TCP and UDP traffic over port 53 from our client/server. A port scanner such as the nmap tool can be used to confirm if the DNS server is available on port 53 as shown below.

# First check UDP

$ nmap -sU -p 53 100.64.0.1
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-21 22:04 SAST
Nmap scan report for 100.64.0.1
Host is up.

PORT   STATE         SERVICE
53/udp open|filtered domain

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

## Next check TCP

$ nmap -sT -p 53 100.64.0.1
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-21 22:07 SAST
Nmap scan report for 100.64.0.1
Host is up (0.00059s latency).

PORT   STATE SERVICE
53/tcp open  domain

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

It’s worth noting that scanning UDP with nmap is not reliable due to the nature of UDP, this is why the state is listed as open or filtered. We can clearly see that TCP 53 is definitely open and responding which is a good sign, if the state was reported as filtered the next thing to investigate would be the connectivity to the DNS server, in particular any firewall running on the DNS server would need to be configured to allow TCP and UDP port 53 traffic in.

We can also run tcpdump to watch the traffic going to our local DNS server:

$ sudo tcpdump -n host 100.64.0.1
tcpdump: data link type PKTAP
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on pktap, link-type PKTAP (Apple DLT_PKTAP), snapshot length 524288 bytes
23:17:39.411500 IP 100.64.0.1.58169 > 100.64.0.1.53: 50915+ A? logs.af-south-1.amazonaws.com. (47)
23:17:39.411594 IP 100.64.0.1.58169 > 100.64.0.1.53: 50915+ A? logs.af-south-1.amazonaws.com. (47)
23:17:39.411703 IP 100.64.0.1.53 > 100.64.0.1.58169: 50915 1/0/0 A 100.64.1.18 (63)
23:17:39.411734 IP 100.64.0.1.53 > 100.64.0.1.58169: 50915 1/0/0 A 100.64.1.18 (63)
23:17:39.412167 IP 100.64.0.1.57548 > 100.64.1.18.443: Flags [SEW], seq 630452899, win 65535, options [mss 1360,nop,wscale 6,nop,nop,TS val 542272848 ecr 0,sackOK,eol], length 0
23:17:39.412204 IP 100.64.1.18.57548 > 100.64.0.1.9010: Flags [SEW], seq 630452899, win 65535, options [mss 1360,nop,wscale 6,nop,nop,TS val 542272848 ecr 0,sackOK,eol], length 0
23:17:39.412302 IP 100.64.0.1.9010 > 100.64.1.18.57548: Flags [S.E], seq 2920832254, ack 630452900, win 65535, options [mss 1360,nop,wscale 6,nop,nop,TS val 974661492 ecr 542272848,sackOK,eol], length 0

Next up, query the local DNS response (and you will note that the A record is missing):

$ dig andrewbaker.ninja
; <<>> DiG 9.10.6 <<>> andrewbaker.ninja
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 35921
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;andrewbaker.ninja.		IN	A

;; Query time: 1348 msec
;; SERVER: 100.64.0.1#53(100.64.0.1)
;; WHEN: Mon Nov 21 19:44:32 SAST 2022
;; MSG SIZE  rcvd: 46

Next, to get the authoritive name servers of a domain we can use the ‘whois’ command as shown below.

$ whois andrewbaker.ninja | grep -i "name server"
Name Server: ns-983.awsdns-58.net
Name Server: ns-462.awsdns-57.co
Name Server: ns-1745.awsdns-26.co.uk
Name Server: ns-1363.awsdns-42.org
Name Server: NS-1363.AWSDNS-42.ORG
Name Server: NS-462.AWSDNS-57.COM
Name Server: NS-1745.AWSDNS-26.CO.UK
Name Server: NS-983.AWSDNS-58.NET

As shown andrewbaker.ninja currently has 8 authoritative name servers. If we run a dig directly against any of these we should receive an authoritative response, that is an up to date and non cached response straight from the source rather than from our local DNS server. In the below example we have run our query against @ns-983.awsdns-58.net

$ dig @ns-983.awsdns-58.net andrewbaker.ninja

; <<>> DiG 9.10.6 <<>> @ns-983.awsdns-58.net andrewbaker.ninja
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64987
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 8, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;andrewbaker.ninja.		IN	A

;; ANSWER SECTION:
andrewbaker.ninja.	300	IN	A	13.244.140.33

;; AUTHORITY SECTION:
andrewbaker.ninja.	172800	IN	NS	ns-1254.awsdns-28.org.
andrewbaker.ninja.	172800	IN	NS	ns-1514.awsdns-61.org.
andrewbaker.ninja.	172800	IN	NS	ns-1728.awsdns-24.co.uk.
andrewbaker.ninja.	172800	IN	NS	ns-1875.awsdns-42.co.uk.
andrewbaker.ninja.	172800	IN	NS	ns-491.awsdns-61.com.
andrewbaker.ninja.	172800	IN	NS	ns-496.awsdns-62.com.
andrewbaker.ninja.	172800	IN	NS	ns-533.awsdns-02.net.
andrewbaker.ninja.	172800	IN	NS	ns-931.awsdns-52.net.

;; Query time: 20 msec

You can now see the A record is returned. Also note that in this dig response we now have the “aa” flag in the header which represents that this is an authoritative answer and is not a cached response (note: qr = query response and rd = recursion desired). If we run this same dig command again, the 300 second TTL that was returned in the answer section will continually state that the TTL is 300 seconds as the response is authoritative.

However if we were to run this dig without specifying @ns-983.awsdns-58.net we would be querying our local DNS server which is not authoritative for the andrewbaker.ninja domain, after the first result the record will be cached locally. This can be confirmed by running the dig command again, as the TTL value will drop down until it reaches 0 and is removed from the cache completely.

By querying the authoritative name server directly we ensure that we are getting the most up to date response rather than a potential old cached response from our own local DNS server or local DNS cache.

Linux: Find the maximum packet size (MTU) between two hosts (using do not fragment flag)


If you have ever tried to use jumbo packets, or trace a weird slowness on the network – one of the things that frequently comes up is packet fragmentation. This is basically where a source machine is sending bigger packets than can be consumed along its pathway to a destination machine. This means the packets will need to be split up. This causes a host of performance issues.

So how do you diagnose this? Well Ping is your friend. It allows you to flag packets to not be fragmented and specify a minimum and maximum packet size. The example below sends a 1460 byte do not fragment packet from the host to example.com:

$ ping -M do -s 1460 example.com 
PING example.com (93.184.216.34) 1460(1488) bytes of data. 
1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=45 time=223 ms
1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=45 time=223 ms 1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=45 time=223 ms

Taking the example above and running on a Macbook/OSX:

$ ping -D -s 1460 example.com
PING example.com (93.184.216.34): 1460 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4

The maximum packet size over the internet is 1500 bytes. So 1490 should be fine, right?

$ ping -M do -s 1490 example.com 
PING example.com (93.184.216.34) 1490(1518) bytes of data. 
ping: local error: Message too long, mtu=1500 ping: local error: Message too long, mtu=1500

The same test on Macbook/OSX:

$ ping -D -s 1490 example.com
PING example.com (93.184.216.34): 1460 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4

As you can see, this breaks beneath the expected 1500 byte packet size. Running “ping -M do -s 1490 example.com” says that the ICMP data size is 1490 bytes and fragmentation is not allowed. But remember the size of ICMP data, ICMP size (i.e., header + data) will be 1498 bytes. Next you need to add the IP header and so the new frame size becomes 1518 bytes. The frame size can’t exceed MTU size of the interface and you can see this in the error message (MTU for the interface is 1500 bytes). Without fragmentation, this message can’t be sent. Since fragmentation is not allowed, ping fails saying message is too long.

Ok, so what if I do this?

$ ping -M want -s 1490 example.com 
PING example.com (93.184.216.34) 1490(1518) bytes of data. 
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=45 time=223 ms
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=45 time=223 ms
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=45 time=223 ms

Ok, why did this work? Well -M want will allow local fragmentation.