Logging DNS hijack visibility

Context

Network system administrators often experience tension between two goals that are at odds with one another:

Goal #1: provide instant always-on DNS services to devices joining and leaving a network

Goal #2: enforce DNS usage to suit the organization’s or network’s needs

For endpoints that have DNS set automatically, there are generally no problems delivering on both of those goals simultaneously as DHCP is provisioned to use the internal on-prem DNS caching resolver, as is the case for all adam:ONE deployments.

Source of tension

However, for endpoints that have some static assignment for DNS, say 8.8.8.8 in our example below, only one of the above goals is achievable… unless we apply an additional enforcement mechanism. The most resource-efficient way to do this is with a Network Address Translation (NAT) rule that redirects and enforces all non-local DNS query attempts to be answered by policy instead.

NAT hijacking of Do53

Check that NAT hijacking is in place:

pfSense

[25.07.1-RELEASE][admin@pfsense.home.arpa]/root: pfctl -s nat | grep domain 
rdr on ix1 inet proto tcp from any to ! (self) port = domain -> 127.0.0.2
rdr on ix1 inet proto udp from any to ! (self) port = domain -> 127.0.0.2

[25.07.1-RELEASE][admin@pfsense.home.arpa]/root: sockstat | grep 127.0.0.2 |grep anmuscle
root     anmuscle   19643 30  udp4   127.0.0.2:53          *:*
root     anmuscle   19643 31  tcp4   127.0.0.2:53          *:*

The above confirms that the NAT hijack is in place and the destination of the hijack has anmuscle listening.

Config switch to show hijacks

A non-default switch is available on pfSense® running adam:ONE® 4.14.2-363 or later.

[25.07.1-RELEASE][admin@pfsense.home.arpa]/root: tail -6 /usr/local/etc/adamone/anmuscle.conf
##
# Custom User Defined Options
# Warning: invalid options set below can prevent anmuscle from starting
## **all user customizations must be below this line**

dns-hijack-ip-address=127.0.0.2

The resulting view on a live log

For any endpoint now attempting to use 8.8.8.8 for example over Do53, the query ie still answered, but hijacked and enforced by policy. Let’s attempt to bypass local DHCP-assigned DNS like this:

david@LegacyEndpoint:~$ dig @8.8.8.8 www.example.com +short
23.223.17.132
23.223.17.135

We got an answer, but importantly, there is now visibility to security and network administrators that can make use of this to go fix the endpoint:

For environments using a SIEM, this information can now be reported on there as well, similar to this log entry:

24/9 13:20:18.032234 19643 DNS? 192.168.94.152@52164 UDP4 www.example.com A | [DNS] (hijacked)

Additional Notes

The NAT hijacking is a function of the underlying firewall engine on all platforms we support. The visibility feature may extend to other platforms in the future but is only available as an option on pfSense® as of this writing. It is a non-default option. IPv4 only. Visibility is for UDP queries only. Other platforms may be considered in the future.