| 5 | |
| 6 | |
| 7 | class Exploit: |
| 8 | def __init__(self, exploit_name, exploit_func, require_disabled_protections, required_information, least_width): |
| 9 | # log.info( |
| 10 | # f'Load exploit: {exploit_name}, need binary without or bypassed {require_disabled_protections}, ' |
| 11 | # f'need {required_information} and payload len at least {least_width}') |
| 12 | self.exploit_name = exploit_name |
| 13 | self.exploit_func = exploit_func |
| 14 | self.require_disabled_protections = require_disabled_protections |
| 15 | self.required_information = required_information |
| 16 | self.least_width = least_width |
| 17 | self.available = True |
| 18 | |
| 19 | def run(self, state_raw: angr.SimState, challenge: Challenge, new_mem: list): |
| 20 | log.info(f"Trying exploit {self.exploit_name}") |
| 21 | try: |
| 22 | self.exploit_func(state_raw, challenge, new_mem, state_raw.globals['binary']) |
| 23 | except SimUnsatError: |
| 24 | log.failure(f"payload constraint unset") |
| 25 | # except AttributeError: |
| 26 | # log.failure(f"payload gadget unset") |
| 27 | self.available = False |
| 28 | log.failure(f"Exploit {self.exploit_name} failed") |
| 29 | |
| 30 | def satisfy(self, binary: InteractiveBinary, try_lazy=False): |
| 31 | if self.available: |
| 32 | if 'lazy' in self.exploit_name and not try_lazy: |
| 33 | return False |
| 34 | if '_align' in self.exploit_name and binary.arch_bytes != 8: |
| 35 | return False # Since we do not trace the stack in shared libs, we need to consider the alignment |
| 36 | return all([i in binary.io_seg_addr for i in self.required_information]) and \ |
| 37 | all([not binary.challenge.protection[i] for i in self.require_disabled_protections]) and \ |
| 38 | binary.payload_len >= binary.arch_bytes * self.least_width - 1 |
| 39 | |
| 40 | |
| 41 | def init_exploits(): |