Skip to content

Instantly share code, notes, and snippets.

@mathyourlife
Created November 18, 2016 12:54
Show Gist options
  • Save mathyourlife/d5c33e53400a0289fd0ae5210d4e47a4 to your computer and use it in GitHub Desktop.
Save mathyourlife/d5c33e53400a0289fd0ae5210d4e47a4 to your computer and use it in GitHub Desktop.
// based on
// https://raw.githubusercontent.com/bmorton/dnswatch/0eec21738a7f9b3786c43e6c13c2d6c32cc60f73/dnswatch.go
package main
import (
"flag"
"fmt"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func recordName(dnsType layers.DNSType) string {
if dnsType == layers.DNSTypeA {
return "A"
} else if dnsType == layers.DNSTypeNS {
return "NS"
} else if dnsType == layers.DNSTypeMD {
return "MD"
} else if dnsType == layers.DNSTypeMF {
return "MF"
} else if dnsType == layers.DNSTypeCNAME {
return "CNAME"
} else if dnsType == layers.DNSTypeSOA {
return "SOA"
} else if dnsType == layers.DNSTypeMB {
return "MB"
} else if dnsType == layers.DNSTypeMG {
return "MG"
} else if dnsType == layers.DNSTypeMR {
return "MR"
} else if dnsType == layers.DNSTypeNULL {
return "NULL"
} else if dnsType == layers.DNSTypeWKS {
return "WKS"
} else if dnsType == layers.DNSTypePTR {
return "PTR"
} else if dnsType == layers.DNSTypeHINFO {
return "HINFO"
} else if dnsType == layers.DNSTypeMINFO {
return "MINFO"
} else if dnsType == layers.DNSTypeMX {
return "MX"
} else if dnsType == layers.DNSTypeTXT {
return "TXT"
} else if dnsType == layers.DNSTypeAAAA {
return "AAAA"
} else if dnsType == layers.DNSTypeSRV {
return "SRV"
}
return "UNKNOWN"
}
func main() {
var deviceInterface string
flag.StringVar(&deviceInterface, "interface", "wlan0", "device interface to listen for DNS packets")
flag.Parse()
handle, err := pcap.OpenLive(deviceInterface, 65535, true, 1000)
if err != nil {
panic(err)
}
err = handle.SetBPFFilter("port 53")
if err != nil {
panic(err)
}
fmt.Printf("Watching for DNS packets on %s...\n", deviceInterface)
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
packetChan := packetSource.Packets()
for {
select {
case packet := <-packetChan:
handlePacket(packet)
}
}
}
// From ANY query
// &layers.DNS{BaseLayer:layers.BaseLayer{
// Contents:[]uint8{0x60, 0x70, 0x81, 0x80, 0x0, 0x1, 0x0, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x77, 0x77, 0x77, 0x6, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0xff, 0x0, 0x1, 0xc0, 0xc, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x26, 0x0, 0x4, 0xac, 0xd9, 0x4, 0x44, 0xc0, 0xc, 0x0, 0x1c, 0x0, 0x1, 0x0, 0x0, 0x0, 0x25, 0x0, 0x10, 0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4, 0x0, 0x0, 0x29, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
// Payload:[]uint8(nil)},
// ID:0x6070, QR:true, OpCode:0x0, AA:false, TC:false, RD:true, RA:true, Z:0x0,
// ResponseCode:0x0, QDCount:0x1,
// ANCount:0x2, NSCount:0x0,
// ARCount:0x1, Questions:[]layers.DNSQuestion{
// layers.DNSQuestion{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}, Type:0xff, Class:0x1}},
// Answers:[]layers.DNSResourceRecord{
// layers.DNSResourceRecord{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}, Type:0x1,
// Class:0x1, TTL:0x26, DataLength:0x4,
// Data:[]uint8{0xac, 0xd9, 0x4, 0x44}, IP:net.IP{0xac, 0xd9, 0x4, 0x44}, NS:[]uint8(nil),
// CNAME:[]uint8(nil), PTR:[]uint8(nil),
// TXTs:[][]uint8(nil),
// SOA:layers.DNSSOA{MName:[]uint8(nil),
// RName:[]uint8(nil), Serial:0x0,
// Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0},
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0,
// Name:[]uint8(nil)},
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)},
// layers.DNSResourceRecord{Name:[]uint8{0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d},
// Type:0x1c, Class:0x1, TTL:0x25, DataLength:0x10,
// Data:[]uint8{0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4},
// IP:net.IP{0x26, 0x7, 0xf8, 0xb0, 0x40, 0x6, 0x8, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x4},
// NS:[]uint8(nil), CNAME:[]uint8(nil), PTR:[]uint8(nil), TXTs:[][]uint8(nil),
// SOA:layers.DNSSOA{MName:[]uint8(nil), RName:[]uint8(nil), Serial:0x0, Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0},
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0, Name:[]uint8(nil)},
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)}},
// Authorities:[]layers.DNSResourceRecord(nil),
// Additionals:[]layers.DNSResourceRecord{layers.DNSResourceRecord{Name:[]uint8(nil), Type:0x29,
// Class:0x1000, TTL:0x0, DataLength:0x0, Data:[]uint8{}, IP:net.IP(nil), NS:[]uint8(nil),
// CNAME:[]uint8(nil), PTR:[]uint8(nil), TXTs:[][]uint8(nil),
// SOA:layers.DNSSOA{MName:[]uint8(nil), RName:[]uint8(nil), Serial:0x0, Refresh:0x0, Retry:0x0, Expire:0x0, Minimum:0x0},
// SRV:layers.DNSSRV{Priority:0x0, Weight:0x0, Port:0x0, Name:[]uint8(nil)},
// MX:layers.DNSMX{Preference:0x0, Name:[]uint8(nil)}, TXT:[]uint8(nil)}},
// buffer:[]uint8{0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d}}
func handlePacket(packet gopacket.Packet) {
metadata := packet.Metadata()
dnsLayer := packet.Layer(layers.LayerTypeDNS)
dns, _ := dnsLayer.(*layers.DNS)
if len(dns.Answers) == 0 {
return
}
fmt.Printf("%#v\n", dns)
for _, question := range dns.Questions {
if question.Type == layers.DNSTypeA || question.Type == layers.DNSTypeAAAA {
fmt.Printf("%s - %s [%d]\n", metadata.Timestamp.Format(time.ANSIC), string(question.Name), dns.ID)
}
}
for _, answer := range dns.Answers {
fmt.Printf("\t\t\t -> %s %s\n", recordName(answer.Type), answer.String())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment