From 4b6c245e1a278f32be44492a4e7ff1bbfca73922 Mon Sep 17 00:00:00 2001 From: nanak-singh <39913517+nanak-singh@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:46:58 +0530 Subject: [PATCH 1/3] Add files via upload --- ttm_aggregate.py | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ ttm_wrapper.py | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 ttm_aggregate.py create mode 100644 ttm_wrapper.py diff --git a/ttm_aggregate.py b/ttm_aggregate.py new file mode 100644 index 0000000..ae7d09b --- /dev/null +++ b/ttm_aggregate.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +import sys +import re +from pathlib import Path +from collections import defaultdict + +# ========================= +# CONFIG (REAL TTM FILES) +# ========================= + +CATEGORIES = { + "fetch": ["_URLs.txt"], + "subdomains": ["_subdomain.txt"], + "backups": ["_backups.txt"], + "archives": ["_archive.txt"], + "parameters": ["_parameters.txt"], + "jwt": ["_jwt.txt"], + "xss": ["_xss.txt"], + "sqli": ["_sqli.txt"], + "lfi": ["_lfi.txt"], + "redirect": ["_redirect.txt"], + "jira": ["_jira.txt"], + "wp": ["_wp.txt"], + "fuzz": ["_fuzz.txt"], +} + +DOMAIN_RE = re.compile(r"^(?=.{1,253}$)(?!-)([a-z0-9-]{1,63}\.)+[a-z]{2,63}$") + +# ========================= +# HELPERS +# ========================= + +def is_under_apex(domain: str, apex: str) -> bool: + return domain == apex or domain.endswith("." + apex) + +# ========================= +# MAIN +# ========================= + +def main(): + if len(sys.argv) != 2: + print("Usage: python ttm_aggregate.py ") + sys.exit(1) + + apex = sys.argv[1].lower().strip() + content_dir = Path("content") + output_dir = Path("output") / apex + + if not content_dir.exists(): + print("[!] content/ directory not found") + sys.exit(1) + + output_dir.mkdir(parents=True, exist_ok=True) + + buckets = defaultdict(set) + + for subdir in content_dir.iterdir(): + if not subdir.is_dir(): + continue + + domain = subdir.name.lower() + + if not DOMAIN_RE.match(domain): + continue + + if not is_under_apex(domain, apex): + continue + + for file in subdir.glob("*.txt"): + for category, suffixes in CATEGORIES.items(): + if any(file.name.endswith(sfx) for sfx in suffixes): + for line in file.read_text(errors="ignore").splitlines(): + line = line.strip() + if line: + buckets[category].add(f"[{domain}] {line}") + + # ========================= + # WRITE OUTPUTS + # ========================= + + for category, values in buckets.items(): + if not values: + continue + + out_file = output_dir / f"{category}_all.txt" + with out_file.open("w", encoding="utf-8") as f: + for entry in sorted(values): + f.write(entry + "\n") + + print(f"[+] Written {out_file} ({len(values)} lines)") + + print(f"\n[✓] Aggregation complete → {output_dir}") + +if __name__ == "__main__": + main() diff --git a/ttm_wrapper.py b/ttm_wrapper.py new file mode 100644 index 0000000..d570135 --- /dev/null +++ b/ttm_wrapper.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +import subprocess +import sys +import re +from pathlib import Path + +# ========================= +# EXACT TTM PIPELINE +# ========================= + +PIPELINE = [ + ["--fetch"], + ["--backups"], + ["--listings"], + ["--parameters"], + ["--jwt"], + ["--attack", "xss"], + ["--attack", "sqli"], + ["--attack", "lfi"], + ["--attack", "redirect"], + ["--attack", "jira"], + ["--attack", "wp"], + ["--attack", "fuzz"], + ["--subdomains"], +] + +DOMAIN_RE = re.compile(r"^(?=.{1,253}$)(?!-)([a-z0-9-]{1,63}\.)+[a-z]{2,63}$") + +# ========================= +# HELPERS +# ========================= + +def normalize(domain: str) -> str: + domain = domain.strip().lower() + domain = re.sub(r"^https?://", "", domain) + return domain.split("/", 1)[0].rstrip(".") + +def load_subdomains(path: Path, apex: str): + results = set() + for line in path.read_text(errors="ignore").splitlines(): + d = normalize(line) + if DOMAIN_RE.match(d) and (d == apex or d.endswith("." + apex)): + results.add(d) + return sorted(results) + +# ========================= +# MAIN +# ========================= + +def main(): + if len(sys.argv) != 3: + print("Usage: python ttm_wrapper.py ") + sys.exit(1) + + apex = normalize(sys.argv[1]) + sub_file = Path(sys.argv[2]) + + base_dir = Path(__file__).resolve().parent + ttm_script = base_dir / "thetimemachine.py" + + if not ttm_script.exists(): + print("[!] thetimemachine.py not found in this directory") + sys.exit(1) + + targets = load_subdomains(sub_file, apex) + + print(f"[+] Apex : {apex}") + print(f"[+] Targets : {len(targets)}") + print(f"[+] TTM Dir : {base_dir}") + + for i, target in enumerate(targets, 1): + print(f"\n==============================") + print(f"[{i}/{len(targets)}] TARGET → {target}") + print(f"==============================") + + for step in PIPELINE: + cmd = ["python", "thetimemachine.py", target] + step + print("\n[CMD]", " ".join(cmd)) + print("-" * 60) + + # 🔥 LIVE OUTPUT — NOTHING HIDDEN + subprocess.run( + cmd, + cwd=base_dir + ) + + print("\n[✓] All scans completed") + print("[i] Check ./content/ for raw results") + +if __name__ == "__main__": + main() From 43ebe33c77ae29a2dbf170f38effe787773cc1bb Mon Sep 17 00:00:00 2001 From: nanak-singh <39913517+nanak-singh@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:50:50 +0530 Subject: [PATCH 2/3] Update ttm_wrapper.py --- ttm_wrapper.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/ttm_wrapper.py b/ttm_wrapper.py index d570135..06b3074 100644 --- a/ttm_wrapper.py +++ b/ttm_wrapper.py @@ -1,12 +1,8 @@ -#!/usr/bin/env python3 import subprocess import sys import re from pathlib import Path -# ========================= -# EXACT TTM PIPELINE -# ========================= PIPELINE = [ ["--fetch"], @@ -26,9 +22,6 @@ DOMAIN_RE = re.compile(r"^(?=.{1,253}$)(?!-)([a-z0-9-]{1,63}\.)+[a-z]{2,63}$") -# ========================= -# HELPERS -# ========================= def normalize(domain: str) -> str: domain = domain.strip().lower() @@ -43,9 +36,6 @@ def load_subdomains(path: Path, apex: str): results.add(d) return sorted(results) -# ========================= -# MAIN -# ========================= def main(): if len(sys.argv) != 3: @@ -78,7 +68,6 @@ def main(): print("\n[CMD]", " ".join(cmd)) print("-" * 60) - # 🔥 LIVE OUTPUT — NOTHING HIDDEN subprocess.run( cmd, cwd=base_dir @@ -89,3 +78,4 @@ def main(): if __name__ == "__main__": main() + From b9ae06a80c22a61c37a153861f10a26896885fed Mon Sep 17 00:00:00 2001 From: nanak-singh <39913517+nanak-singh@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:51:16 +0530 Subject: [PATCH 3/3] Update ttm_aggregate.py --- ttm_aggregate.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/ttm_aggregate.py b/ttm_aggregate.py index ae7d09b..e353b67 100644 --- a/ttm_aggregate.py +++ b/ttm_aggregate.py @@ -1,13 +1,9 @@ -#!/usr/bin/env python3 + import sys import re from pathlib import Path from collections import defaultdict -# ========================= -# CONFIG (REAL TTM FILES) -# ========================= - CATEGORIES = { "fetch": ["_URLs.txt"], "subdomains": ["_subdomain.txt"], @@ -26,16 +22,10 @@ DOMAIN_RE = re.compile(r"^(?=.{1,253}$)(?!-)([a-z0-9-]{1,63}\.)+[a-z]{2,63}$") -# ========================= -# HELPERS -# ========================= def is_under_apex(domain: str, apex: str) -> bool: return domain == apex or domain.endswith("." + apex) -# ========================= -# MAIN -# ========================= def main(): if len(sys.argv) != 2: @@ -74,9 +64,6 @@ def main(): if line: buckets[category].add(f"[{domain}] {line}") - # ========================= - # WRITE OUTPUTS - # ========================= for category, values in buckets.items(): if not values: @@ -93,3 +80,4 @@ def main(): if __name__ == "__main__": main() +