The files you need for this:
https://psasync.codeplex.com/ – psasync runspaces multi-threading PowerShell module
https://github.com/kurtfalde/DNS-Debug – the DNS Debug scripts
I’ve been bugged recently (@jepayneMSFT) to post some scripts I put together quite a while back so here they are. These were written due to an onsite visit with a customer where we knew various DNS names that were of interest that were being used as C2 hosts and we wanted to track down specifically which clients were making calls to these host names. Like many IT things there are other ways of doing this including proxy/firewall logs etc but in this case seeing I’m a MSFT resource we will be looking at the DNS debug logs on MSFT Windows Servers.
I am making use of a psasync module https://newsqlblog.com/2012/12/17/psasync-module-multithreaded-powershell/ written by Jon Boulineau in this case which allows multithreading via runspaces in PowerShell. I tend to use Boe Prox’s poshrsjob module https://github.com/proxb/PoshRSJob usually now for runspaces but in general they both work fine, it’s just a .net runspaces thing in the background and these modules make it easier to use them.
The solution is composed of the following 3 scripts:
These were designed unfortunately for a customer where they were still running 2003 DC’s at the time (yes it was fully after support had ended for 2003) and the script is focused around not needing the activedirectory PowerShell module.
Enable-DNSDebugAsync.ps1 uses system.directoryservices to get all DC’s in the forest and then uses the dnscmd command line tool to enable the proper amount of dns debug logging across all DC’s in the forest. You will need RPC access to all DC/DNS servers in the environment from the system you run this from. It will set the log file to be 500Mb and be placed in c:\windows\system32\dns\dns.log.
Retrieve-DNSDebugAsync.ps1 (maybe I should have used Get- instead to be more powershelly) basically uses multithreading to reach out to all DC’s and copy these DNS debug logs back to the system you are running the scripts from. This does not use PSRemoting as that was not available so instead uses WMI for some process that I call remotely such as copying the dns.log file to a server-date-dns.log file. It also then makes use of the makecab.exe utility to basically zip/cab up that log file (500Mb of just text compresses really well and helps with transferring across wan links). Once zipped up it moves that file back to the collector system. This is only using 10 runspaces currently but you can change that to whatever works for your collector system/environment.
Search-DNSDebugLogs.ps1 allows you to fill out the $BadThings array with terms that you might be interested in such as domain names of interest and then it will search through the dns debug logs that have been gathered to the collector system. This isn’t as efficient as it could be as it uses get-content which I personally find incredibly slow when you start to get 100’s of MB’s or 10’s of Gb’s worth of log files but I never rewrote this one using streamreader. Also technically it would probably be great to parse these / aggregate into a single file and load into PowerBI which would allow quickly searching/filtering as well.
Anyhow it’s any interesting tactical piece of code, I would expect if you started to do this proactively instead you would probably be looking more at using Azure OMS / Log Analytics / Splunk and automatically gathering the dns.log file via an agent into a SIEM solution and write up queries/alerts there instead. Hopefully this is helpful and interesting to someone let me know if you have any questions.