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:
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
I frequently forget this command shortcut, so this post is simply because I am lazy. To clear your history in iTerm press Command + K. Control + L only clears the screen, so as soon as you run the next command you will see the scroll back again.
If you want to view your command history (for terminal) type:
$ ls -a ~ | grep hist
.zsh_history
$ cat .zsh_history
There are three basic ways to secure email, these are: Sender Policy Framework (SPF), Domain Keys Identified Mail (DKIM), Domain-based Message Authentication, Reporting & Conformance (DMARC) definitions. Lets quickly discuss these before we talk about how to check if they have been setup:
SPF helps prevent spoofing by verifying the sender’s IP address
SPF (Sender Policy Framework) is a DNS record containing information about servers allowed to send emails from a specific domain (eg which servers can send emails from andrewbaker.ninja).
With it, you can verify that messages coming from your domain are sent by mail servers and IP addresses authorized by you. This might be your email servers or servers of another company you use for your email sending. If SPF isn’t set, scammers can take advantage of it and send fake messages that look like they come from you.
It’s important to remember that there can be only one SPF record for one domain. Within one SPF record, however, there can be several servers and IP addresses mentioned (for instance, if emails are sent from several mailing platforms).
DKIM shows that the email hasn’t been tampered with
DKIM (DomainKeys Identified Mail) adds a digital signature to the header of your email message, which the receiving email servers then check to ensure that the email content hasn’t changed. Like SPF, a DKIM record exists in the DNS.
DMARC provides reporting visibility on the prior controls
DMARC (Domain-based Message Authentication, Reporting & Conformance) defines how the recipient’s mail server should process incoming emails if they don’t pass the authentication check (either SPF, DKIM, or both).
Basically, if there’s a DKIM signature, and the sending server is found in the SPF records, the email is sent to the recipient’s inbox.
If the message fails authentication, it’s processed according to the selected DMARC policy: none, reject, or quarantine.
Under the “none” policy, the receiving server doesn’t take any action if your emails fail authentication. It doesn’t impact your deliverability. But it also doesn’t protect you from scammers, so we don’t recommend setting it. Only by introducing stricter policies can you block them in the very beginning and let the world know you care about your customers and brand.
Here, messages that come from your domain but don’t pass the DMARC check go to “quarantine.” In such a case, the provider is advised to send your email to the spam folder.
Under the “reject” policy, the receiving server rejects all messages that don’t pass email authentication. This means such emails won’t reach an addressee and will result in a bounce.
The “reject” option is the most effective, but it’s better to choose it only if you are sure that everything is configured correctly.
Now that we’ve clarified all the terms, let’s see how you can check if you have an existing SPF record, DKIM record, and DMARC policy set in place.
The “v=spf1” part shows that the record is of SPF type (version 1).
The “include” part lists servers allowed to send emails for the domain.
The “~all” part indicates that if any part of the sent message doesn’t match the record, the recipient server will likely decline it.
2. Next Lets Check if DKIM is setup
What is a DKIM record?
A DKIM record stores the DKIM public key — a randomized string of characters that is used to verify anything signed with the private key. Email servers query the domain’s DNS records to see the DKIM record and view the public key.
A DKIM record is really a DNS TXT (“text”) record. TXT records can be used to store any text that a domain administrator wants to associate with their domain. DKIM is one of many uses for this type of DNS record. (In some cases, domains have stored their DKIM records as CNAME records that point to the key instead; however, the official RFC requires these records to be TXT.)
Unlike most DNS TXT records, DKIM records are stored under a specialized name, not just the name of the domain. DKIM record names follow this format:
[selector]._domainkey.[domain]
The selector is a specialized value issued by the email service provider used by the domain. It is included in the DKIM header to enable an email server to perform the required DKIM lookup in the DNS. The domain is the email domain name. ._domainkey. is included in all DKIM record names.
If you want to find the value of the selector, you can view this by selecting “Show Original” when you have the email open in gmail:
Once you are able to view the original email, perform a text search for “DKIM-Signature”. This DKIM-Signature contains an attribute ‘s=’, this is the DKIM selector being used for this domain. In the example below (an amazon email), we can see the DKIM selector is “jvxsykglqiaiibkijmhy37vqxh4mzqr6”.
To look up the DKIM record, email servers use the DKIM selector provided by the email service provider, not just the domain name. Suppose example.com uses Big Email as their email service provider, and suppose Big Email uses the DKIM selector big-email. Most of example.com’s DNS records would be named example.com, but their DKIM DNS record would be under the name big-email._domainkey.example.com, which is listed in the example above.
Content
This is the part of the DKIM DNS record that lists the public key. In the example above, v=DKIM1 indicates that this TXT record should be interpreted as DKIM, and the public key is everything after p=.
Below we query the linuxincluded.com domain using the “dkim” selector.
A DMARC record stores a domain’s DMARC policy. DMARC records are stored in the Domain Name System (DNS) as DNS TXT records. A DNS TXT record can contain almost any text a domain administrator wants to associate with their domain. One of the ways DNS TXT records are used is to store DMARC policies.
(Note that a DMARC record is a DNS TXT record that contains a DMARC policy, not a specialized type of DNS record.)
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.
$ 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
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.
When you open terminal you will see that it defaults the information that you see on the prompt, which can use up quite a bit of the screen real estate.
Last login: Sat Jan 14 11:13:00 on ttys000
cp363412~$
Customize the zsh Prompt in Terminal
Typically, the default zsh prompt carries information like the username, machine name, and location starting in the user’s home directory. These details are stored in the zsh shell’s system file at the /etc/zshrc location.
PS1="%n@%m %1~ %# "
In this string of variables:
%n is the username of your account.
%m is the MacBook’s model name.
%1~ means the current working directory path where the ~ strips the $HOME directory location.
%# means that the prompt will show # if the shell is running with root (administrator) privileges, or else offers % if it doesn’t.
Below are a few other options that I have used previously:
\h The hostname, up to the first . (e.g. andrew)
\H The hostname. (e.g. andrew.ninja.com)
\j The number of jobs currently managed by the shell.
\l The basename of the shell's terminal device name.
\s The name of the shell, the basename of $0 (the portion following
the final slash).
\w The current working directory.
\W The basename of $PWD.
\! The history number of this command.
\# The command number of this command
To change this, open Terminal, type the following command, and hit Return:
nano ~/.zshrc
Below is my favourite, which will just display your login name (use Ctrl + X to exit and save):
PROMPT='%n$ '
I prefer to see the path (less the home directory) in the prompt:
PROMPT='%n:%1~$ '
You can pick a font colour from black, white, yellow, green, red, blue, cyan, and magenta. Here’s how to use them:
PROMPT='%F{cyan}%n%f:~$ '
There are more modifications to this, but this is as far as i go 🙂
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
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-----
If you want to automatically renew your certs then the easiest way is to setup a cron just to call letsencrypt periodically. Below is an example cron job:
First create the bash script to renew the certificate
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.
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):
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.