commit 1e3d9e75644cc2a1d8ecc325cba612e038d016e0 Author: Minecon724 Date: Wed Jun 12 16:34:55 2024 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f21b54 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/venv/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..7742c59 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +`numfinder` scans for nameservers incrementally to find the first available numerical domain + +WARNING: It's usually inaccurate because a registered domain can (and many do) have no nameservers + +Examples: +- Scan `.com` and `.eu`: + `python3 main.py com eu` +- Scan `.rocks` from 100 up to 1000: + `python3 main.py --min 100 --max 1000 rocks` \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..a7d7fbc --- /dev/null +++ b/main.py @@ -0,0 +1,65 @@ +import argparse +from typing import List + +import dns.message +import dns.query + +from dns.resolver import resolve, NXDOMAIN +from dns.rcode import Rcode + +def get_resolvers(tld: str) -> List[str] | None: + try: + answers = resolve(tld, 'NS') + except NXDOMAIN: + return + + return [resolve(i.target, 'A')[0].address for i in answers] + +def name_exists(name: str, resolver: str) -> bool: + msg = dns.message.make_query(name, 'NS') + answer_msg = dns.query.udp(msg, resolver) + + return answer_msg.rcode() == Rcode.NOERROR + +def main(tld: str, min_num: int, max_num: int) -> int: + resolvers = get_resolvers(tld) + + if resolvers is None: + print(f"Unknown TLD: {tld}") + return 0 + + print(f"Scanning TLD '{tld}' with {len(resolvers)} rootservers") + run_loop(tld, min_num, max_num, resolvers) + +def run_loop(tld: str, min_num: int, max_num: int, resolvers: List[str]): + global name + + for i in range(min_num, max_num): + name = f'{i}.{tld}' + resolver = resolvers[i % len(resolvers)] + + if not name_exists(name, resolver): + print(name) + try: + input('Press Enter to continue, or Ctrl+C to skip TLD') + except KeyboardInterrupt: + print('') + return + + print(f"No free domains found in range {min_num} - {max_num} for TLD: {tld}") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('-m', '--min', help='Min number', type=int, default=10) + parser.add_argument('--max', help='Max number', type=int, default=10000) + parser.add_argument('tld', help='TLD', nargs='+') + + args = parser.parse_args() + + try: + for tld in args.tld: + if main(tld, args.min, args.max) == 1: + break + except KeyboardInterrupt: + print(f"You interrupted at {name}") + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..707711b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +dnspython==2.6.1