Skip to content

Commit

Permalink
Merge pull request #12 from typosquatter/Sn0wAlice/main
Browse files Browse the repository at this point in the history
Sn0w alice/main
  • Loading branch information
DavidCruciani authored Oct 3, 2023
2 parents 8d1962d + dc4209d commit 0afaef6
Show file tree
Hide file tree
Showing 31 changed files with 1,806 additions and 1,507 deletions.
115 changes: 115 additions & 0 deletions ail_typo_squatting/dns_local/resolving.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import random, json


type_request = ['A', 'AAAA', 'NS', 'MX']

# This is a catch all function
def catchAll(current_domain):
import dns.resolver

is_catch_all = False

chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
ca_str = ''
for _ in range(10):
ca_str += random.choice(chars)

domain_catch_all = f"{ca_str}.{current_domain}"
try:
answer = dns.resolver.resolve(domain_catch_all, 'A')
if len(answer):
is_catch_all = True
except:
pass
if is_catch_all:
return domain_catch_all
return False

# This is a dns resolving function
def dnsResolving(resultList, domain, pathOutput, verbose=False, givevariations=False, dns_limited=False, catch_all=False):
"""Do a dns resolving on each variations and then create a json"""

import dns.name
import dns.resolver

if verbose:
print("[+] Dns Resolving...")

domain_resolve = dict()

for result in resultList:
if givevariations:
variation = result[1]
result = result[0]

if not variation in list(domain_resolve.keys()):
domain_resolve[variation] = list()
loc_dict = dict()
loc_dict[result] = dict()
try:
n = dns.name.from_text(result)
except Exception as e:
print(e)
print(result)
try:
resultList.remove(result)
except:
pass
continue

for t in type_request:
try:
answer = dns.resolver.resolve(n, t)
loc = list()
for rdata in answer:
loc.append(rdata.to_text())
if len(loc) > 0:
loc_dict[result][t] = loc
except:
pass

if len(loc_dict[result]) == 0:
if dns_limited:
loc_dict = dict()
else:
loc_dict[result]['NotExist'] = True
else:
loc_dict[result]['NotExist'] = False
if catch_all:
loc_dict[result]['CatchAll'] = catchAll(n)

if loc_dict:
domain_resolve[variation].append(loc_dict)

else:
domain_resolve[result] = dict()
n = dns.name.from_text(result)

for t in type_request:
try:
answer = dns.resolver.resolve(n, t)
loc = list()
for rdata in answer:
loc.append(rdata.to_text())
if len(loc) > 0:
domain_resolve[result][t] = loc
except:
pass

if len(domain_resolve[result]) == 0:
if dns_limited:
del domain_resolve[result]
else:
domain_resolve[result]['NotExist'] = True
else:
domain_resolve[result]['NotExist'] = False
if catch_all:
domain_resolve[result]['CatchAll'] = catchAll(n)

if pathOutput and not pathOutput == "-":
with open(f"{pathOutput}/{domain}_resolve.json", "w", encoding='utf-8') as write_json:
json.dump(domain_resolve, write_json, indent=4)
if pathOutput == '-':
print(json.dumps(domain_resolve), flush=True)

return domain_resolve
55 changes: 55 additions & 0 deletions ail_typo_squatting/format/output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import yaml

from format.yara import formatYara
from format.regex import formatRegex, formatRegexRetrie
from format.yaml import formatYaml

def formatOutput(format, resultList, domain, pathOutput, givevariations=False, betterRegex=False):
"""
Call different function to create the right format file
"""

if format == "text":
if pathOutput and not pathOutput == "-":
with open(f"{pathOutput}/{domain}.txt", "w", encoding='utf-8') as write_file:
for element in resultList:
if givevariations:
write_file.write(f"{element[0]}, {element[1]}\n")
else:
write_file.write(element + "\n")
elif pathOutput == "-":
for element in resultList:
if givevariations:
print(f"{element[0]}, {element[1]}")
else:
print(element)

elif format == "yara":
yara = formatYara(resultList, domain, givevariations)
if pathOutput and not pathOutput == "-":
with open(f"{pathOutput}/{domain}.yar", "w", encoding='utf-8') as write_file:
write_file.write(yara)
elif pathOutput == "-":
print(yara)

elif format == "regex":
if betterRegex:
regex = formatRegexRetrie(resultList, givevariations)
else:
regex = formatRegex(resultList, givevariations)
if pathOutput and not pathOutput == "-":
with open(f"{pathOutput}/{domain}.regex", "w", encoding='utf-8') as write_file:
write_file.write(regex)
elif pathOutput == "-":
print(regex)

elif format == "yaml":
yaml_file = formatYaml(resultList, domain, givevariations)
if pathOutput and not pathOutput == "-":
with open(f"{pathOutput}/{domain}.yml", "w", encoding='utf-8') as write_file:
yaml.dump(yaml_file, write_file)
elif pathOutput == "-":
print(yaml_file)
else:
print(f"Unknown format: {format}. Will use text format instead")
formatOutput("text", resultList, domain, pathOutput, givevariations)
31 changes: 31 additions & 0 deletions ail_typo_squatting/format/regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import string
from retrie.trie import Trie

def formatRegex(resultList, givevariations=False):
"""Output in regex format"""
regex = ""
for result in resultList:
if givevariations:
result = result[0]
reg = ""
for car in result:
if car in string.ascii_letters or car in string.digits:
reg += car
elif car in string.punctuation:
reg += "\\" + car
regex += f"{reg}|"
regex = regex[:-1]

return regex

def formatRegexRetrie(resultList, givevariations=False):
"""Output in regex format"""

trie = Trie()
if not givevariations:
trie.add(*resultList)
else:
loc_list = [element[0] for element in resultList]
trie.add(*loc_list)

return trie.pattern()
14 changes: 14 additions & 0 deletions ail_typo_squatting/format/yaml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
def formatYaml(resultList, domain, givevariations=False):
"""Output in yaml format"""
yaml_file = {"title": domain}
variations = list()

for result in resultList:
if givevariations:
variations.append(result[0])
else:
variations.append(result)

yaml_file["variations"] = variations

return yaml_file
18 changes: 18 additions & 0 deletions ail_typo_squatting/format/yara.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
def formatYara(resultList, domain, givevariations=False):
"""Output in yara format"""
domainReplace = domain.replace(".", "_")

rule = f"rule {domainReplace} {{\n\tmeta:\n\t\t"
rule += f'domain = "{domain}"\n\t'
rule += "strings: \n"

cp = 0
for result in resultList:
if givevariations:
result = result[0]
rule += f'\t\t$s{cp} = "{result}"\n'
cp += 1

rule += "\tcondition:\n\t\t any of ($s*)\n}"

return rule
54 changes: 54 additions & 0 deletions ail_typo_squatting/generator/addDash.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Import all the utils
from .utils.generator_functions import *

"""
Original Domain Typosquatted Domain
+----------------+ +-------------------+
| circl.lu | | ci-rcl.lu |
+----------------+ +-------------------+
"""

# Add Dash
def addDash(domain, resultList, verbose, limit, givevariations=False, keeporiginal=False, combo=False):
"""Add a dash between the first and last character in a string"""

if not len(resultList) >= limit:
if verbose:
print("[+] Add Dash")

resultLoc = list()
loclist = list()

prefix, domain_without_tld, tld = parse_domain(domain)
domainList = [domain_without_tld]

for name in domainList:
if len(name) == 1:
resultLoc.append(prefix + name)
else:
resultLoc.append(prefix + name)
for i in range(1, len(name)):
if prefix + name[:i] + '-' + name[i:] not in resultLoc:
resultLoc.append(prefix + name[:i] + '-' + name[i:])

if resultLoc:
loclist.append(resultLoc)
resultLoc = list()

loclist.append([tld])
rLoc = globalAppend(loclist)

if verbose:
print(f"{len(rLoc)}\n")

if combo:
rLoc = checkResult(rLoc, resultList, givevariations, "addDash")
rLoc = final_treatment(domain, rLoc, limit, givevariations, keeporiginal, "addDash")
return rLoc

resultList = checkResult(rLoc, resultList, givevariations, "addDash")
resultList = final_treatment(domain, resultList, limit, givevariations, keeporiginal, "addDash")

return resultList
49 changes: 49 additions & 0 deletions ail_typo_squatting/generator/addDynamicDns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Import all the utils
from .utils.generator_functions import *
from .utils.get_pathetc import get_path_etc

import requests, json

pathEtc = get_path_etc()

# Add Dynamic DNS
def addDynamicDns(domain, resultList, verbose, limit, givevariations=False, keeporiginal=False, combo=False):
"""Add dynamic dns"""

if not len(resultList) >= limit:
if verbose:
print("[+] Dynamic DNS")

try:
r = requests.get("https://raw.githubusercontent.com/MISP/misp-warninglists/main/lists/dynamic-dns/list.json")
dynamicdns = r.json()['list']
with open(pathEtc + "/dynamic-dns.json", "w") as write_json:
json.dump(r.json(), write_json, indent=4)
except:
with open(pathEtc + "/dynamic-dns.json", "r") as read_json:
dynamicdns = json.load(read_json)["list"]


resultLoc = list()

domain_replace = [domain[::-1].replace(".", "-", 1)[::-1], domain.replace(".", "-"), domain.replace(".", "_")]

for ddns in dynamicdns:
for replace in domain_replace:
d_loc = replace + ddns
if d_loc not in resultLoc:
resultLoc.append(d_loc)

if verbose:
print(f"{len(resultLoc)}\n")

if combo:
resultLoc = checkResult(resultLoc, resultList, givevariations, "addDynamicDns")
resultLoc = final_treatment(domain, resultLoc, limit, givevariations, keeporiginal, "addDynamicDns")
return resultLoc

resultList = checkResult(resultLoc, resultList, givevariations, "addDynamicDns")
resultList = final_treatment(domain, resultList, limit, givevariations, keeporiginal, "addDynamicDns")

return resultList

43 changes: 43 additions & 0 deletions ail_typo_squatting/generator/addTld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Import all the utils
from .utils.generator_functions import *
from .utils.get_pathetc import get_path_etc

pathEtc = get_path_etc()

"""
Original Domain Typosquatted Domain
+----------------+ +------------------------+
| circl.lu | | circl.lu.com |
+----------------+ +------------------------+
"""

# Add Tld
def addTld(domain, resultList, verbose, limit, givevariations=False, keeporiginal=False, combo=False):
"""Adding a tld before the original tld"""
# https://data.iana.org/TLD/tlds-alpha-by-domain.txt
# Version 2022012800

if not len(resultList) >= limit:
if verbose:
print("[+] Adding Tld")
with open(pathEtc + "/tlds-alpha-by-domain.txt", "r") as read_file:
tlds = read_file.readlines()

cp = 0
loc_result_list = resultList.copy()
for tld in tlds:
cp += 1
if givevariations:
loc_result_list.append([domain + "." + tld.lower().rstrip("\n"), 'addTld'])
else:
loc_result_list.append(domain + "." + tld.lower().rstrip("\n"))

if verbose:
print(f"{cp}\n")

return final_treatment(domain, loc_result_list, limit, givevariations, keeporiginal, "addTld")

return resultList

Loading

0 comments on commit 0afaef6

Please sign in to comment.