From 956ed81170c658cffe9be14a494b531a8a9eee28 Mon Sep 17 00:00:00 2001 From: 5amu Date: Wed, 6 Jul 2022 13:08:00 +0200 Subject: [PATCH] #3 - zone transfer check implemented --- internal/check.go | 1 + internal/dnschecks/zonetransfer.go | 85 ++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/internal/check.go b/internal/check.go index 9677a7e..3aa167c 100644 --- a/internal/check.go +++ b/internal/check.go @@ -17,4 +17,5 @@ var CheckList = []Check{ new(dnschecks.SOACheck), new(dnschecks.GLUECheck), new(dnschecks.ANYCheck), + new(dnschecks.AXFRCheck), } diff --git a/internal/dnschecks/zonetransfer.go b/internal/dnschecks/zonetransfer.go index 8c220d7..396a7fb 100644 --- a/internal/dnschecks/zonetransfer.go +++ b/internal/dnschecks/zonetransfer.go @@ -1 +1,86 @@ package dnschecks + +import ( + "fmt" + "net" + + "github.com/5amu/dnshunter/internal/common" + "github.com/5amu/dnshunter/internal/output" + "github.com/miekg/dns" +) + +type AXFRCheck struct { + client *dns.Client + output *output.CheckOutput +} + +func (c *AXFRCheck) Init(client *dns.Client) error { + c.client = client + return nil +} + +func (c *AXFRCheck) Start(domain string, nameservers *common.Nameservers) error { + m := new(dns.Msg) + m.SetQuestion(dns.Fqdn(domain), dns.TypeAXFR) + + var isVuln bool + var message string + + message += "\nThe nameserver allows zone transfers from unauthorized sources, this\n" + message += "leads to the disclosure of all the zone's domains handled by the dns\n" + message += "(at best). In the worse case scenario, the attacker might be able to\n" + message += "get ownership on the zone handled by the dns.\n\n" + + for _, ns := range nameservers.IPs { + vulnerable := false + fqdn, err := nameservers.IPv4ToFQDN(ns.String()) + if err != nil { + message += fmt.Sprintf("nameserver %v don't accept unauthenticated zone transfers\n", fqdn) + continue + } + + conn, err := net.Dial("tcp", net.JoinHostPort(ns.String(), "53")) + if err != nil { + message += fmt.Sprintf("nameserver %v don't accept unauthenticated zone transfers\n", fqdn) + continue + } + transfer := &dns.Transfer{Conn: &dns.Conn{Conn: conn}} + channel, err := transfer.In(m, ns.String()) + if err != nil { + message += fmt.Sprintf("nameserver %v don't accept unauthenticated zone transfers\n", fqdn) + continue + } + + var vuln []dns.RR + for r := range channel { + if r.Error != nil || len(r.RR) == 0 { + message += fmt.Sprintf("nameserver %v don't accept unauthenticated zone transfers\n", fqdn) + continue + } + vulnerable = true + vuln = append(vuln, r.RR...) + } + + if vulnerable { + message += common.Warn(fmt.Sprintf("nameserver %v accepts unauthenticated zone transfers\n", fqdn)) + for _, v := range vuln { + message += common.Warn(fmt.Sprintln(v.String())) + } + } + isVuln = vulnerable || isVuln + } + + c.output = &output.CheckOutput{ + Name: "Unprotected Zone Transfer", + Domain: domain, + Nameservers: nameservers.ToFQDNs(), + Vulnerable: isVuln, + Message: message, + } + + return nil +} + +func (c *AXFRCheck) Results() *output.CheckOutput { + return c.output +}