Skip to content

Instantly share code, notes, and snippets.

@mnixry
Created April 22, 2023 15:02
Show Gist options
  • Save mnixry/6a4c8735792de6c42533cd2196be780d to your computer and use it in GitHub Desktop.
Save mnixry/6a4c8735792de6c42533cd2196be780d to your computer and use it in GitHub Desktop.
DASCTF 2023, dump leaked directory
import asyncio
import re
from pathlib import Path
from urllib.parse import urljoin, urlparse
from anyio import open_file
from httpx import AsyncClient
from loguru import logger
MATCH_QUOTES = re.compile(r'["\'](.*?)["\']')
PARALLEL = 4
HOST = "http://114.117.174.147:18886"
ENTRY_FILE = "app.js"
SAVE_DIRECTORY = Path("./website")
touched_paths = set[str]()
client = AsyncClient(base_url=HOST, http2=True)
sem = asyncio.Semaphore(PARALLEL)
def enum_paths(basic_path: str):
return [
basic_path,
f"{basic_path}.js",
f"{basic_path}/index.js",
]
async def get_file_content(path):
logger.debug(f"Getting file: {path!r}")
async with sem:
resp = await client.get(path)
if not resp.is_success:
return
logger.info(f"Found file: {path!r}, size {len(resp.content)}")
await save_file(path, resp.content)
strings = [matched[1] for matched in MATCH_QUOTES.finditer(resp.text)]
possible_paths = []
for string in strings:
parsed_path = urlparse(urljoin(str(resp.url), string))
if parsed_path.hostname != urlparse(HOST).hostname:
continue
basic_path = parsed_path.path
if basic_path in touched_paths:
continue
touched_paths.add(basic_path)
paths = [
*enum_paths(basic_path),
*enum_paths(basic_path.rstrip("/")),
*enum_paths("/api/" + basic_path.lstrip("/")),
]
basic_path = basic_path.lstrip("/")
possible_paths.extend(paths)
await asyncio.gather(
*[get_file_content(path) for path in possible_paths], return_exceptions=True
)
@logger.catch
async def save_file(path: str, content: bytes):
save_path = SAVE_DIRECTORY / path.replace("//", "/").lstrip("/")
save_path.parent.mkdir(parents=True, exist_ok=True)
async with await open_file(save_path, "wb") as file:
await file.write(content)
if __name__ == "__main__":
asyncio.run(get_file_content(ENTRY_FILE))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment