├── README.md ├── subdomain.png ├── subdomainTakeOver.ps1 ├── subdomainTakeOver.py └── subdomais.txt /README.md: -------------------------------------------------------------------------------- 1 | # Subdomain Takeover Finder 2 | 3 | ![image](subdomain.png) 4 | 5 | ## Subdomain Takeover? 6 | 7 | Subdomain Takeover? is a BugBounty tool / Pentesting Tool. This script automate the finding of potential subdomain that could be tookover by looking for alias vulnerability in the subdomain DNS. The script is available in **python3** or **Powershell**. 8 | ### **Python Version** 9 | 10 | #### **Usage :** 11 | 12 | python3 subdomainTakeOver.py -l targets 13 | 14 | subdomainTakeOver.py -> script name 15 | -l -> for list 16 | file.txt -> file that contain subdomain 17 | 18 | #### **Help :** 19 | python3 subdomainTakeOver.py -h 20 | 21 | ### **Powershell Version** 22 | 23 | 24 | #### **Usage :** 25 | 26 | .\subdomainTakeOver.ps1 .\subdomains.txt 27 | 28 | .\subdomainTakeOver.ps1 subdomain.exemple.com 29 | 30 | #### **Parameter :** 31 | A specefic subdomain or a .TXT file with a list of subdomain. 32 | 33 | #### **Output :** 34 | A list of all the potential vulnerable subdomain found. 35 | -------------------------------------------------------------------------------- /subdomain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrlew1s/SubdomainTakeover/cf387fd7399b7564c48a98b967c3583ddbd2ab66/subdomain.png -------------------------------------------------------------------------------- /subdomainTakeOver.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Position=1)] 3 | [string]$subDomainURLORTxtFilePath = "" 4 | ) 5 | 6 | <# 7 | Description: 8 | BugBounty tool. This script automate the finding of potential subdomain that could be tookover by looking for a potential alias vulnerability in the subdomain DNS. 9 | 10 | Entry(Not mendatory): 11 | A specefic subdomain or a .TXT file with a list of subdomain. 12 | 13 | Output: 14 | A list of all the potential vulnerable subdomain found. 15 | Command exemple : 16 | .\subdomainTakeOver.ps1 17 | .\subdomainTakeOver.ps1 .\subdomains.txt 18 | .\subdomainTakeOver.ps1 subdomain.exemple.com 19 | 20 | #> 21 | 22 | 23 | Write-Host " 24 | 25 | 26 | #################################################################################################### 27 | _____ _ ______ _ 28 | / ___| | | | _ \ (_) 29 | \ `--. _ _| |__ | | | |___ _ __ ___ __ _ _ _ __ 30 | `--. \ | | | '_ \| | | / _ \| '_ ` _ \ / _` | | '_ \ 31 | /\__/ / |_| | |_) | |/ / (_) | | | | | | (_| | | | | | 32 | \____/ \__,_|_.__/|___/ \___/|_| |_| |_|\__,_|_|_| |_| 33 | 34 | _____ _ _____ ___ 35 | |_ _| | | | _ | |__ \ 36 | | | __ _| | _____ | | | |_ _____ _ __ ) | 37 | | |/ _` | |/ / _ \| | | \ \ / / _ \ '__/ / 38 | | | (_| | < __/\ \_/ /\ V / __/ | |_| 39 | \_/\__,_|_|\_\___| \___/ \_/ \___|_| (_) 40 | 41 | 42 | 43 | ______ ___ ___ _ __ 44 | | ___ \ _ | \/ | | | / | 45 | | |_/ /_ _ (_) | . . |_ __ | | _____ __`| | ___ 46 | | ___ \ | | | | |\/| | '__| | |/ _ \ \ /\ / / | |/ __| 47 | | |_/ / |_| | _ | | | | | _ | | __/\ V V / _| |\__ \ 48 | \____/ \__, | (_) \_| |_/_| (_) |_|\___| \_/\_/ \___/___/ 49 | __/ | 50 | |___/ 51 | ##################################################################################################### 52 | " 53 | 54 | 55 | 56 | $SubDomainsArray = @() 57 | $DNSEntryArray = @() 58 | $FilteredDomainArray = @() 59 | $RecordsTypes = @("A","AAAA","NS","CNAME","CAA","MX","NS","PRT","SOA","SRV","TXT") 60 | #$RecordsTypes = @("ALL") 61 | 62 | 63 | if ($subDomainURLORTxtFilePath -eq "") { 64 | $subDomainURLORTxtFilePath = Read-Host -Prompt ' A specefic subdomain or a .TXT file with a list of subdomains: ' 65 | } 66 | 67 | 68 | if ($subDomainURLORTxtFilePath.Substring($subDomainURLORTxtFilePath.Length-4) -eq ".txt") { 69 | $content = Get-content -Path $subDomainURLORTxtFilePath 70 | foreach ($subdomain in $content){ 71 | $SubDomainsArray += $subdomain 72 | } 73 | }else{ 74 | $SubDomainsArray = @($subDomainURLORTxtFilePath) 75 | } 76 | 77 | 78 | foreach ($url in $SubDomainsArray){ 79 | try 80 | { 81 | 82 | $Response = Invoke-WebRequest -Uri $url -ErrorAction Stop 83 | # This will only execute if the Invoke-WebRequest is successful. 84 | Write-Host "$($url) is reachable...Subdomain Dropped" -ForegroundColor Red 85 | } 86 | catch 87 | { 88 | $FilteredDomainArray += $url 89 | Write-Host "$($url) is unreachable...Subdomain Added" -ForegroundColor Green 90 | } 91 | } 92 | 93 | Write-Host "[Looking For DNS records....]"-ForegroundColor Yellow 94 | foreach ($element in $FilteredDomainArray) { 95 | $DNSEntryObject = @{} 96 | foreach($record in $RecordsTypes){ 97 | 98 | try{ 99 | $DNSEntryObject = Resolve-DnsName -Name $element -Type $record -erroraction silentlycontinue 100 | if ($DNSEntryObject.Type -eq "CNAME"){ 101 | Write-Host "$($element) : CNAME response received" -ForegroundColor Green 102 | $DNSEntryArray += $DNSEntryObject 103 | } 104 | 105 | }catch{Continue} 106 | } 107 | } 108 | Write-Host "[Done.] 109 | "-ForegroundColor Yellow 110 | 111 | Write-Host "Potential Subdomain Takeover :" -ForegroundColor Cyan 112 | 113 | if ($DNSEntryArray.Count -eq 0) { 114 | Write-Host "None where found..." 115 | } 116 | else { 117 | foreach ($element in $DNSEntryArray) { 118 | if ($element.Type -eq "CNAME"){ 119 | Write-Host "URL: $($element.name) CNAME : $($element.NameHost)" 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /subdomainTakeOver.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import argparse 3 | import re 4 | import os 5 | import dns.resolver 6 | 7 | 8 | RED = "\033[91m" 9 | GREEN = "\033[92m" 10 | BLUE = "\033[94m" 11 | WHITE = "\033[0;37m" 12 | 13 | 14 | class PSudomainTO: 15 | def __init__(self, domain, cname): 16 | self.domain = domain 17 | self.cname = cname 18 | 19 | class util: 20 | 21 | def formating(domainList): 22 | if os.path.isfile(domainList): 23 | readWords = open(domainList, 'r') 24 | 25 | else: 26 | exit("{}File Not Found...".format(RED)) 27 | 28 | print("{}[+] Loading Targets.... [+]\033[94m\n".format(WHITE)) 29 | subdomainlist = [] 30 | 31 | for words in readWords: 32 | if not words.isspace(): 33 | words = words.rstrip() 34 | words = words.replace("https://", "") 35 | words = words.replace("http://", "") 36 | words = words.replace("https://www.", "") 37 | words = words.replace("http://www.", "") 38 | words = words.replace("/", "") 39 | words = "http://{}".format(words) 40 | subdomainlist.append(words) 41 | 42 | 43 | readWords.close() 44 | 45 | return subdomainlist 46 | 47 | 48 | def deformating(domainlist): 49 | deformatedsubdomain = [] 50 | 51 | for domain in domainlist: 52 | domain = domain.replace("http://","") 53 | deformatedsubdomain.append(domain) 54 | 55 | return deformatedsubdomain 56 | 57 | 58 | 59 | if __name__ == "__main__": 60 | 61 | print(""" 62 | 63 | _____ _ ______ _ 64 | / ___| | | | _ \ (_) 65 | \ `--. _ _| |__ | | | |___ _ __ ___ __ _ _ _ __ 66 | `--. \ | | | '_ \| | | / _ \| '_ ` _ \ / _` | | '_ \ 67 | /\__/ / |_| | |_) | |/ / (_) | | | | | | (_| | | | | | 68 | \____/ \__,_|_.__/|___/ \___/|_| |_| |_|\__,_|_|_| |_| 69 | _____ _ _____ ___ 70 | |_ _| | | | _ | |__ \ 71 | | | __ _| | _____ | | | |_ _____ _ __ ) | 72 | | |/ _` | |/ / _ \| | | \ \ / / _ \ '__/ / 73 | | | (_| | < __/\ \_/ /\ V / __/ | |_| 74 | \_/\__,_|_|\_\___| \___/ \_/ \___|_| (_) 75 | 76 | By Mr.Lew1s 77 | 78 | """) 79 | 80 | 81 | 82 | parser = argparse.ArgumentParser(description="Subdomain Takeover") 83 | parser.add_argument('-l','--list',default='',help='python3 subdomainTakeOver.py [-l, --list] file contain list of domains') 84 | args = parser.parse_args() 85 | domainList = args.list 86 | 87 | if len(str(domainList)) > 0: 88 | 89 | potentialvulnerablesubdomain = [] 90 | potentialVulnerableSubdomainWithCNAMEDnsRecord = [] 91 | 92 | subList = util.formating(domainList) 93 | 94 | if len(subList) > 0: 95 | print(WHITE,"\n[!] Total {} subdomain(s) as been Loaded [!]\033[94m".format(len(subList))) 96 | 97 | print("{}[!] Looking For Subdomain Takeover..... [!]\n\033[94m".format(WHITE)) 98 | 99 | for domain in subList: 100 | print("{}[-] Testing {} [-]\033[94m".format(WHITE, domain)) 101 | 102 | try: 103 | subDoamin = requests.get("{}".format(domain.rstrip()), timeout=5).text 104 | print("{} -- Not Vulnerable {}\033[94m \n".format(BLUE, domain)) 105 | 106 | except: 107 | potentialvulnerablesubdomain.append(domain) 108 | print("{} -- Domain is unreachable...Added to potential subdomain takeover\033[94m \n".format(BLUE)) 109 | 110 | 111 | if len(potentialvulnerablesubdomain) > 0: 112 | print("{}[!] Checking DNS Records of {} potential vulnerable subdomain(s)... [!]\n\033[94m".format(WHITE, len(potentialvulnerablesubdomain))) 113 | 114 | potentialvulnerablesubdomain = util.deformating(potentialvulnerablesubdomain) 115 | 116 | for domain in potentialvulnerablesubdomain: 117 | try: 118 | print("{}[-] Looking DNS Record for {} [-]\033[94m".format(WHITE, domain)) 119 | 120 | dnsrecord = dns.resolver.resolve(domain, 'CNAME') 121 | 122 | for data in dnsrecord: 123 | 124 | print("{} -- DNS Record Found : {} \n".format(GREEN, data, domain)) 125 | potentialVulnerableSubdomainWithCNAMEDnsRecord.append(PSudomainTO(domain,data)) 126 | 127 | except: 128 | print("{} -- No DNS Record Found \033[94m \n".format(BLUE, domain)) 129 | 130 | 131 | if len(potentialVulnerableSubdomainWithCNAMEDnsRecord) > 0: 132 | takeover = open('takeover.txt','a') 133 | print("{}Potential subdomain that could be took over : \033[94m \n".format(WHITE)) 134 | for obj in potentialVulnerableSubdomainWithCNAMEDnsRecord: 135 | print ("{}Domain : {} CNAME : {} \n".format(GREEN,obj.domain,obj.cname)) 136 | takeover.write("{}Domain : {} CNAME : {} \n".format(GREEN,obj.domain,obj.cname)) 137 | takeover.close() 138 | else: 139 | print("{}[-] No DNS Record was Found in the list of potential vulnerable Subdomain [-]\033[94m".format(RED)) 140 | 141 | 142 | else: 143 | print(RED,"\n[!] No potential vunerable subdomain was found from the {} subdomain(s) targeted [!]\033[94m".format(len(subList))) 144 | 145 | else: 146 | print("Author: Mr.Lew1s\nArguments:\n\t--help, -h: Show Help\n\t--list, -l: file contain list of domains\n") 147 | -------------------------------------------------------------------------------- /subdomais.txt: -------------------------------------------------------------------------------- 1 | exemple.domain1.com 2 | exemple.domain2.com 3 | exemome.domain3.com 4 | --------------------------------------------------------------------------------