import-ligolo-sheet.py (4142B)
1 #!/usr/bin/env python3 2 """Import the local Ligolo-ng guide and its rendered Rose Pine diagrams.""" 3 4 from __future__ import annotations 5 6 import re 7 import shutil 8 from pathlib import Path 9 10 11 SOURCE_ROOT = Path("/home/daemon-sec/Downloads/Kimi_Agent_Rose-Pine Flowcharts") 12 SOURCE_MARKDOWN = SOURCE_ROOT / "Ligolo-ng Cheat sheet.md" 13 SOURCE_DIAGRAMS = SOURCE_ROOT / "diagrams" 14 SOURCE_ARCHIVE = SOURCE_ROOT / "ligolo-dawn-diagrams.zip" 15 16 REPO_ROOT = Path(__file__).resolve().parents[1] 17 DEST_MARKDOWN = REPO_ROOT / "src/content/sheets/tunneling-pivoting/ligolo-ng.md" 18 DEST_DIAGRAMS = REPO_ROOT / "public/diagrams/ligolo-ng" 19 20 DIAGRAMS = [ 21 ("01-three-players", "The three Ligolo-ng players", "Attacker proxy, pivot agent, and internal target"), 22 ("02-four-bricks", "The four pieces of a working tunnel", "Session, interface, route, and tunnel flow"), 23 ("03-which-workflow", "Choose the right Ligolo-ng workflow", "Decision tree for first pivots, multiple pivots, and reverse connections"), 24 ("04-workflow-a", "Workflow A — first pivot", "First-pivot autoroute sequence"), 25 ("05-double-pivot", "Workflow B — double pivot", "Two Ligolo-ng agents and two routed interfaces"), 26 ("06-listener-direction", "Listener direction", "Connections enter the agent address and exit on the proxy side"), 27 ("07-reverse-shell", "Reverse-shell relay", "Internal callback relayed through a Ligolo-ng listener"), 28 ("08-troubleshooting", "Troubleshooting flow", "Route, tunnel, reachability, and scan checks"), 29 ] 30 31 FRONTMATTER = """--- 32 title: "Ligolo-ng CLI: Routes, Listeners, and Multi-Hop Pivoting" 33 description: "Ligolo-ng v0.9.x CLI guide covering managed routes, listeners, first pivots, multi-hop tunnels, reverse connections, scanning, and troubleshooting." 34 category: tunneling-pivoting 35 tags: [ligolo-ng, pivoting, tunneling, networking] 36 tools: [Ligolo-ng, Nmap] 37 difficulty: intermediate 38 updated: "2026-08-25" 39 source: "local:Kimi Agent Rose-Pine Flowcharts/Ligolo-ng Cheat sheet.md" 40 --- 41 """ 42 43 44 def diagram_figure(stem: str, title: str, alt: str) -> str: 45 public = f"/diagrams/ligolo-ng/{stem}" 46 return f"""<figure class="diagram-plate corners"> 47 <a class="diagram-plate__image" href="{public}.png" target="_blank" rel="noopener"> 48 <img src="{public}.png" alt="{alt}" loading="lazy" decoding="async" /> 49 </a> 50 <figcaption> 51 <span>{title}</span> 52 <span class="diagram-plate__downloads"> 53 <a href="{public}.png" download>PNG</a> 54 <a href="{public}.mmd" download>Mermaid source</a> 55 </span> 56 </figcaption> 57 </figure>""" 58 59 60 def main() -> None: 61 body = SOURCE_MARKDOWN.read_text(encoding="utf-8") 62 if not body.startswith("---\n"): 63 raise SystemExit(f"Expected YAML frontmatter in {SOURCE_MARKDOWN}") 64 _, _, body = body.split("---\n", 2) 65 66 blocks = list(re.finditer(r"```mermaid\n.*?\n```", body, flags=re.DOTALL)) 67 if len(blocks) != len(DIAGRAMS): 68 raise SystemExit(f"Expected {len(DIAGRAMS)} Mermaid blocks, found {len(blocks)}") 69 70 replacements = iter(diagram_figure(*diagram) for diagram in DIAGRAMS) 71 body = re.sub(r"```mermaid\n.*?\n```", lambda _: next(replacements), body, flags=re.DOTALL) 72 73 download_note = """ 74 > [!info] Rose Pine Dawn diagram pack 75 > Each flowchart below opens at full resolution and includes its Mermaid source. 76 > [Download all eight diagrams and sources as a ZIP](/diagrams/ligolo-ng/ligolo-dawn-diagrams.zip). 77 """ 78 body = body.replace("# Ligolo-ng CLI Cheat Sheet\n", "# Ligolo-ng CLI Cheat Sheet\n" + download_note, 1) 79 80 DEST_MARKDOWN.parent.mkdir(parents=True, exist_ok=True) 81 DEST_MARKDOWN.write_text(FRONTMATTER + body.lstrip(), encoding="utf-8") 82 83 DEST_DIAGRAMS.mkdir(parents=True, exist_ok=True) 84 for stem, _, _ in DIAGRAMS: 85 for suffix in (".png", ".mmd"): 86 shutil.copy2(SOURCE_DIAGRAMS / f"{stem}{suffix}", DEST_DIAGRAMS / f"{stem}{suffix}") 87 shutil.copy2(SOURCE_ARCHIVE, DEST_DIAGRAMS / SOURCE_ARCHIVE.name) 88 89 print(f"Imported {DEST_MARKDOWN.relative_to(REPO_ROOT)}") 90 print(f"Copied {len(DIAGRAMS)} PNGs, {len(DIAGRAMS)} Mermaid sources, and the ZIP archive") 91 92 93 if __name__ == "__main__": 94 main()