Skip to content

Commit 3c2b4a8

Browse files
committed
Clean up main package
1 parent 1bc425a commit 3c2b4a8

File tree

4 files changed

+168
-133
lines changed

4 files changed

+168
-133
lines changed

bruteforce.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package sonar
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"sort"
7+
"sync"
8+
)
9+
10+
func BruteForce(threads int, wordlist <-chan string, domain string) Results {
11+
results := make(Results, 0)
12+
13+
fmt.Println("[+] Detecting wildcard")
14+
wildcard, responses, err := detectWildcard(domain)
15+
if err != nil {
16+
// TODO: Fail loudly
17+
}
18+
19+
if wildcard {
20+
fmt.Println("[+] Wildcard detected for domain")
21+
22+
wildcardResult := Result{
23+
Domain: "*." + domain,
24+
Addrs: keys(responses),
25+
}
26+
27+
results = append(results, wildcardResult)
28+
}
29+
30+
fmt.Println("[+] Beginning brute force attempt")
31+
32+
var wg sync.WaitGroup
33+
for i := 0; i < threads; i++ {
34+
wg.Add(1)
35+
go func(wordlist <-chan string) {
36+
nextWord:
37+
for {
38+
word, ok := <-wordlist
39+
if !ok {
40+
break
41+
}
42+
43+
guess := word + "." + domain
44+
answers, err := net.LookupHost(word + "." + domain)
45+
if err != nil {
46+
continue
47+
}
48+
49+
if wildcard {
50+
for _, answer := range answers {
51+
if _, ok := responses[answer]; ok {
52+
// it's a wildcard response
53+
continue nextWord
54+
}
55+
}
56+
}
57+
58+
result := Result{Domain: guess, Addrs: answers}
59+
results = append(results, result)
60+
}
61+
62+
wg.Done()
63+
}(wordlist)
64+
}
65+
66+
wg.Wait()
67+
sort.Sort(results)
68+
69+
return results
70+
}

cmd/sonar/main.go

Lines changed: 4 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
package main
22

33
import (
4-
"crypto/rand"
5-
"encoding/hex"
64
"encoding/json"
75
"encoding/xml"
86
"flag"
97
"fmt"
108
"log"
119
"net"
1210
"os"
13-
"sort"
14-
"strings"
15-
"sync"
1611

1712
"github.com/jrozner/sonar"
18-
"github.com/miekg/dns"
1913
)
2014

2115
func main() {
@@ -35,7 +29,7 @@ func main() {
3529
flag.IntVar(&threads, "threads", 4, "number of threads for brute forcing")
3630
flag.BoolVar(&zt, "zonetransfer", false, "perform zone transfer")
3731
flag.StringVar(&output, "output", "", "write output to specified file")
38-
flag.StringVar(&format, "format", "", "output format (json, xml, csv, nmap)")
32+
flag.StringVar(&format, "format", "", "output format (json, xml, nmap)")
3933
flag.Parse()
4034

4135
if flag.NArg() != 1 {
@@ -54,7 +48,7 @@ func main() {
5448

5549
switch {
5650
case (zt == true):
57-
results = zoneTransfer(domain)
51+
results = sonar.ZoneTransfer(domain)
5852
case (brute == true):
5953
var wl sonar.Wordlist
6054
if wordlist == "" {
@@ -66,7 +60,7 @@ func main() {
6660
}
6761
wl = sonar.NewFile(fp)
6862
}
69-
results = bruteForce(threads, wl.GetChannel(), domain)
63+
results = sonar.BruteForce(threads, wl.GetChannel(), domain)
7064
}
7165

7266
if output == "" {
@@ -94,7 +88,7 @@ func writeOutput(output, format string, results sonar.Results) error {
9488
case "nmap":
9589
serialized, err = sonar.ToNmap(results)
9690
default:
97-
// TODO: return error for invalid format
91+
log.Fatal("invalid output format")
9892
}
9993

10094
if err != nil {
@@ -109,135 +103,12 @@ func writeOutput(output, format string, results sonar.Results) error {
109103
return nil
110104
}
111105

112-
func zoneTransfer(domain string) sonar.Results {
113-
results := sonar.NewResultSet()
114-
fqdn := dns.Fqdn(domain)
115-
116-
servers, err := net.LookupNS(domain)
117-
if err != nil {
118-
log.Fatal(err)
119-
}
120-
121-
for _, server := range servers {
122-
msg := new(dns.Msg)
123-
msg.SetAxfr(fqdn)
124-
125-
transfer := new(dns.Transfer)
126-
answerChan, err := transfer.In(msg, net.JoinHostPort(server.Host, "53"))
127-
if err != nil {
128-
log.Println(err)
129-
continue
130-
}
131-
132-
for envelope := range answerChan {
133-
if envelope.Error != nil {
134-
log.Println(envelope.Error)
135-
break
136-
}
137-
138-
for _, rr := range envelope.RR {
139-
switch v := rr.(type) {
140-
case *dns.A:
141-
results.Add(strings.TrimRight(v.Header().Name, "."), v.A.String())
142-
case *dns.AAAA:
143-
results.Add(strings.TrimRight(v.Header().Name, "."), v.AAAA.String())
144-
default:
145-
}
146-
}
147-
}
148-
}
149-
150-
return results.Results()
151-
}
152-
153-
func bruteForce(threads int, wordlist <-chan string, domain string) sonar.Results {
154-
fmt.Println("[+] Detecting wildcard")
155-
wildcard, responses, err := detectWildcard(domain)
156-
if err != nil {
157-
// TODO: Fail loudly
158-
}
159-
160-
if wildcard {
161-
fmt.Println("[+] Wildcard detected for domain")
162-
}
163-
164-
fmt.Println("[+] Beginning brute force attempt")
165-
166-
results := make(sonar.Results, 0)
167-
168-
var wg sync.WaitGroup
169-
for i := 0; i < threads; i++ {
170-
wg.Add(1)
171-
go func(wordlist <-chan string) {
172-
nextWord:
173-
for {
174-
word, ok := <-wordlist
175-
if !ok {
176-
break
177-
}
178-
179-
guess := word + "." + domain
180-
answers, err := net.LookupHost(word + "." + domain)
181-
if err != nil {
182-
continue
183-
}
184-
185-
if wildcard {
186-
for _, answer := range answers {
187-
if _, ok := responses[answer]; ok {
188-
// it's a wildcard response
189-
continue nextWord
190-
}
191-
}
192-
}
193-
194-
result := sonar.Result{Domain: guess, Addrs: answers}
195-
results = append(results, result)
196-
}
197-
198-
wg.Done()
199-
}(wordlist)
200-
}
201-
202-
wg.Wait()
203-
sort.Sort(results)
204-
205-
return results
206-
}
207-
208106
func printResults(results sonar.Results) {
209107
for _, result := range results {
210108
fmt.Println(result)
211109
}
212110
}
213111

214-
func detectWildcard(domain string) (bool, map[string]struct{}, error) {
215-
bytes := make([]byte, 12)
216-
_, err := rand.Read(bytes)
217-
if err != nil {
218-
return false, nil, err
219-
}
220-
221-
domain = fmt.Sprintf("%s.%s", hex.EncodeToString(bytes), domain)
222-
223-
answers, err := net.LookupHost(domain)
224-
if err != nil {
225-
if asserted, ok := err.(*net.DNSError); ok && asserted.Err == "no such host" {
226-
return false, nil, nil
227-
}
228-
229-
return false, nil, err
230-
}
231-
232-
responses := make(map[string]struct{})
233-
234-
for _, answer := range answers {
235-
responses[answer] = struct{}{}
236-
}
237-
238-
return true, responses, nil
239-
}
240-
241112
func printUsage() {
242113
fmt.Fprintf(os.Stderr, "Usage: %s [options] domain\n", os.Args[0])
243114
flag.PrintDefaults()

wildcard.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package sonar
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/hex"
6+
"fmt"
7+
"net"
8+
)
9+
10+
func detectWildcard(domain string) (bool, map[string]struct{}, error) {
11+
bytes := make([]byte, 12)
12+
_, err := rand.Read(bytes)
13+
if err != nil {
14+
return false, nil, err
15+
}
16+
17+
domain = fmt.Sprintf("%s.%s", hex.EncodeToString(bytes), domain)
18+
19+
answers, err := net.LookupHost(domain)
20+
if err != nil {
21+
if asserted, ok := err.(*net.DNSError); ok && asserted.Err == "no such host" {
22+
return false, nil, nil
23+
}
24+
25+
return false, nil, err
26+
}
27+
28+
responses := make(map[string]struct{})
29+
30+
for _, answer := range answers {
31+
responses[answer] = struct{}{}
32+
}
33+
34+
return true, responses, nil
35+
}
36+
37+
func keys(set map[string]struct{}) []string {
38+
keys := make([]string, 0, len(set))
39+
for key, _ := range set {
40+
keys = append(keys, key)
41+
}
42+
43+
return keys
44+
}

zonetransfer.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package sonar
2+
3+
import (
4+
"log"
5+
"net"
6+
"strings"
7+
8+
"github.com/miekg/dns"
9+
)
10+
11+
func ZoneTransfer(domain string) Results {
12+
results := NewResultSet()
13+
fqdn := dns.Fqdn(domain)
14+
15+
servers, err := net.LookupNS(domain)
16+
if err != nil {
17+
log.Fatal(err)
18+
}
19+
20+
for _, server := range servers {
21+
msg := new(dns.Msg)
22+
msg.SetAxfr(fqdn)
23+
24+
transfer := new(dns.Transfer)
25+
answerChan, err := transfer.In(msg, net.JoinHostPort(server.Host, "53"))
26+
if err != nil {
27+
log.Println(err)
28+
continue
29+
}
30+
31+
for envelope := range answerChan {
32+
if envelope.Error != nil {
33+
log.Println(envelope.Error)
34+
break
35+
}
36+
37+
for _, rr := range envelope.RR {
38+
switch v := rr.(type) {
39+
case *dns.A:
40+
results.Add(strings.TrimRight(v.Header().Name, "."), v.A.String())
41+
case *dns.AAAA:
42+
results.Add(strings.TrimRight(v.Header().Name, "."), v.AAAA.String())
43+
default:
44+
}
45+
}
46+
}
47+
}
48+
49+
return results.Results()
50+
}

0 commit comments

Comments
 (0)