Parsing Microsoft DNS Logs

January 20, 2017

f94ac315fd8170a9231553e9c7adb49aI was thinking of starting this with a DNS joke, but then I realized it could take 24 hours before anyone would get it. Now let’s all pretend that I didn’t just tell that joke. Speaking of DNS, has anyone looked at a Microsoft DNS log? Quite an interesting, captivating read, if you were a sloth. To make matters worse, when it starts to get larger than 100 MB opening it isn’t very fun. Let me rephrase my original statement: Sloths also think logs are not fun.  But there is hope.

 

Brah, do you even parse?

Manually reading log files is headed out. If you’re looking for something specific, you need to parse the log file and compare it to something you’re looking for. For this I chose to use Python. I know there are a lot of other ways of doing it, but I’ve been interested in trying some things out with Python.

First, if you don’t know how to setup DNS logging, you’ll need to do that.

  1. Open your DNS snap-in.
  2. Right click your DNS Server and go to Properties.
  3. Go to the Debug Logging
  4. Check the box for Log packets for debugging.
  5. Choose the file path and name of the log.
  6. Choose a size that you’re comfortable with and hit OK.

Moving to the meat of the program we will want to import 2 libraries.

import os.path
import re

After that let’s set the location for the DNS files. You’ll want to customize this.

scriptpath = os.path.dirname(r"\\myserver\location\dnslogs\ ")
dnsFile = os.path.join(scriptpath, 'dns.log')

Then we’ll want to declare a list to be used.

dnsList = []

Let’s parse out the log file now. I even included comments to make this for an easy read.

with open(dnsFile,'r') as myDnsFile:
    for dnsLine in myDnsFile:
        # Only use lines that have Snd to reduce the size of the search.
        if re.findall(r'Snd',dnsLine) == ['Snd']:
            # Use regex to parse everything between the parentheses
            dnsSub = re.findall(r'\)(.+?)\(',dnsLine)
            # Join each using a period to var dnsUrl
            dnsUrl = '.'.join(dnsSub)
            # Use regex to find the IP address
            ipSub = re.findall(r'\d+\.\d+\.\d+\.\d+',dnsLine)
            ipRequest = '.'.join(ipSub)
            # Use regex to find the date
            dateSub = re.findall(r'\d+\/\d+\/\d+',dnsLine)
            date = '/'.join(dateSub)
            # Use regex to find the time
            timeSub = re.findall(r'\d+\:\d+\:\d+ .[M]',dnsLine)
            time = ':'.join(timeSub)
            # Add to dnsList for ease of use.
            dnsList.append([dnsUrl,ipRequest,date,time])

Next we’ll want to compare this against something. Let’s say you want to make sure no one is making requests to known malware. Let’s start by importing a good malware list.

import urllib.request
blackListUrl = urllib.request.urlopen('http://mirror1.malwaredomains.com/files/justdomains')
blackList = []
blackList = blackListUrl.read().decode('utf-8').splitlines()

Wow, that was a whole lot easier to parse out and get good information from.

The last thing would be to compare the two lists.

for eachDnsList in dnsList:
    for eachBlackList in blackList:
        if eachBlackList == eachDnsList[0]:
            print("Match", eachDnsList[0], " was accessed by ", eachDnsList[1])

There you have it. The full file will look like this.

import os.path
import re
import urllib.request

# Location of the DNS File
# You'll want to customize this.
scriptpath = os.path.dirname(r"\\myserver\location\dnslogs\ ")
# DNS file name
dnsFile = os.path.join(scriptpath, 'dns.log')
# Location of black list database
blackListUrl = urllib.request.urlopen('http://mirror1.malwaredomains.com/files/justdomains')

# Declare lists to be used
blackList = []
dnsList = []

# Create a list of lists from the Microsoft DNS file.
with open(dnsFile,'r') as myDnsFile:
    for dnsLine in myDnsFile:
        # Only use lines that have Snd to reduce the size of the search.
        if re.findall(r'Snd',dnsLine) == ['Snd']:
            # Use regex to parse everything between the parentheses
            dnsSub = re.findall(r'\)(.+?)\(',dnsLine)
            # Join each using a period to var dnsUrl
            dnsUrl = '.'.join(dnsSub)
            # Use regex to find the IP address
            ipSub = re.findall(r'\d+\.\d+\.\d+\.\d+',dnsLine)
            ipRequest = '.'.join(ipSub)
            # Use regex to find the date
            dateSub = re.findall(r'\d+\/\d+\/\d+',dnsLine)
            date = '/'.join(dateSub)
            # Use regex to find the time
            timeSub = re.findall(r'\d+\:\d+\:\d+ .[M]',dnsLine)
            time = ':'.join(timeSub)
            # Add to list
            dnsList.append([dnsUrl,ipRequest,date,time])

# Create a list from the black list file.
blackList = blackListUrl.read().decode('utf-8').splitlines()

# Compare both lists
for eachDnsList in dnsList:
    for eachBlackList in blackList:
        if eachBlackList == eachDnsList[0]:
            print("Match", eachDnsList[0], " was accessed by ", eachDnsList[1], " on ", eachDnsList[2], eachDnsList[3]

Some Commands for the Week

March 28, 2010

I do work for different doctor’s offices here and there. I was waiting on some server tasks to complete when I had picked up one of those doctor journals type magazines, I’ll never make that mistake again. I read through some of the paragraphs, I understood what each of the words meant, well most of the words. But putting all of it together to understand what it was trying to convey as a whole was a different task entirely.

So even though I was reading, I was definitely not learning anything from that, because I had no background or pretext to what the journal was really about. You might also say the same thing about non-technical people reading this blog. You know who you are! This can apply to anything that you’re unfamiliar with, unless you’re like one of my other friends who reads a book once and can tell you the names of all of the characters that were in it 3 years after he read it.

I had this same issue when first looking over the dsquery tool. The way it was presented to me was more along the line with creating new user accounts en mass. That would be more useful for a corporate environment, so I didn’t really take the time to sink my teeth into it.

Untill I was tasked to list of all the users at one of the businesses I work with. Rather than typing each of the names out, which would have taken quite a while, I’ve done it for other clients, I remembered the dsquery tool. After some trial an error trying to get it to work, I found the best solution is to run it this way:

dsquery ou domainroot

This will give you all the OUs in their correct form on your domain. From there you would just plug it into the dsquery user command:

Dsquery user "OU=Users,OU=Awesome,DC=SomeDomain,DC=com”

It popped out the list in no time flat. Unfortunatly it wasn’t plain text names. Just had to crop the full OU out of the name, which was easy with notepad.

After realizing how neato of a tool this was, I started thinking of other ways I could use this new found power. You can us this for all sorts of great tools. Like finding computers that haven’t checked into the domain for 12 weeks.

dsquery computer -inactive 12

Or a user that the business owner forgot to tell you quit 4 weeks ago.

dsquery user –inactive 4

Last neat trick. I don’t know how many people hate to change their passwords. Some times they’ll get into their own system and set it so they don’t need to change so and so user’s password. You can get a general idea of how many users have gone so many days with out changing their password

dsquery user "OU=Users,OU=Awesome,DC=SomeDomain,DC=com” -stalepwd 60

Now one warning about being able to use this command. You will need a Domain Functional Level of Windows 2003. And that’s a whole different topic.

Group Policy

March 16, 2010

Over coming obstacles can be challenging, yet rewarding. With the pain and suffering endured during the process, makes for a better story.

I’m a fan of the outdoors, I’ll admit that to the internet. Now my body on the other hand, it’s a fan of the couch. So when I get the idea of doing something physical, you can bet my body will think that is a bad idea. I went on a hike today, a short 6 miles through a moderate mountain range, a few breaks here and there to provide some comfort to the body. I even gave it a warning last week by starting on a smaller 2 mile hike. Well apparently my load was a bit too cumbersome and now I can hardly get to standing up or raising my arm above my head.

The same thing could be said about trying to find out about an elusive group policy issue. When things don’t work as you know they should, it isn’t always the fact that you have group policy setup incorrectly, maybe something more is wrong.

Before leaving one day I dropped by a coworkers desk. He was drilling away setting up a new group policy for some new terminal servers for an outside company. They have been plagued pretty much with BSODs since they were put in and they asked us to setup the group policy lock down for them. My coworker had spent over an hour getting the group policy setup just right to lock down everything under the sun, it was totally sexy.

With a test user he kept logging in and the user seemed to be able to do things that they should not be able to do. The Manage Your Server screen kept popping up as well as Administration Tools in the start menu. Something was definitely wrong. After double checking everything, we enabled the run bar and rant he command gpresult. We double checked all the policies that were being applied, I also noticed something that I’ve seen using this, but never really paid too much attention too. It also showed applied permissions. Oh, this is interesting!

We found that this user had built-in\Administrators access. We checked the local permissions and it only had local Administrator and Domain admins permissions. We double checked the users’ permission and it only had domain users. We went back to our gpresult and we also found that they had Domain Administrator privileges. Wait, what?!

We brought up dsa.msc to check the built in security groups for the domain, and what about floored us was that we found Domain Users in the Domain Administrators group. Not only did they have elevated privileges on the terminal server. They had free range to, well, ANYTHING that they might have had the curiosity to try and figure out.

This explains all the strange software being installed on the server, which who knows how it was being installed, as well as the random almost daily BSOD that happened on them.

We told the local administrator of the site about it and he seemed completely shocked and never even thought to check on that. As painfull as that was to walk through, you definitely learn a lot of great trouble shooting tools and made for quite a colorful story.

Hello world!

March 14, 2010

So this is a blog. I’m new to blogging, so let’s grow together. Let’s start organizing these thoughts.
Some times being able to do things can be challenging.

lol @ the default title of the first post. That’s like the first thing when writing perl or html that they teach you to say.