From e97d392bf586844ad90600a0fa23ef04e845e252 Mon Sep 17 00:00:00 2001 From: Kevin Phoenix Date: Thu, 15 Aug 2024 16:29:34 -0700 Subject: [PATCH] Use BVV from claripy (#109) --- rex/exploit/technique.py | 18 ++++++++++-------- .../techniques/call_jmp_sp_shellcode.py | 5 ++++- rex/exploit/techniques/ret2libc.py | 6 +++--- rex/exploit/techniques/rop_to_accept_system.py | 4 ++-- rex/exploit/techniques/rop_to_execl.py | 3 ++- rex/exploit/techniques/rop_to_system.py | 3 ++- .../techniques/rop_to_system_complicated.py | 3 ++- .../techniques/shellcode_leak_address.py | 3 +-- .../techniques/shellcode_set_register.py | 2 +- 9 files changed, 27 insertions(+), 20 deletions(-) diff --git a/rex/exploit/technique.py b/rex/exploit/technique.py index ed03127..030e532 100644 --- a/rex/exploit/technique.py +++ b/rex/exploit/technique.py @@ -5,6 +5,8 @@ from abc import abstractmethod import angr +import claripy + from angrop.errors import RopException from ..exploit import CannotExploit @@ -197,7 +199,7 @@ def _write_with_ROP(self, data): # constrain the address to be the chain chain_mem = self.crash.state.memory.load(chain_addr, len(chain.payload_str())) - chain_bvv = self.crash.state.solver.BVV(chain.payload_str()) + chain_bvv = claripy.BVV(chain.payload_str()) # the chain should be guaranteed to be satisfiable here self.crash.state.add_constraints(chain_mem == chain_bvv) @@ -206,7 +208,7 @@ def _write_with_ROP(self, data): self._windup_to_unconstrained_successor() glob_data = self.crash.state.memory.load(addr, len(data)) - data_bvv = self.crash.state.solver.BVV(data) + data_bvv = claripy.BVV(data) return addr, (glob_data == data_bvv) def _find_global_address_for_string(self, data): @@ -260,7 +262,7 @@ def _read_in_global_data_with_read(self, data): # constrain the address to be the chain chain_mem = self.crash.state.memory.load(chain_addr, len(chain.payload_str())) - chain_bvv = self.crash.state.solver.BVV(chain.payload_str()) + chain_bvv = claripy.BVV(chain.payload_str()) # the chain should be guaranteed to be satisfiable here self.crash.state.add_constraints(chain_mem == chain_bvv) @@ -269,7 +271,7 @@ def _read_in_global_data_with_read(self, data): self._windup_to_unconstrained_successor() glob_data = self.crash.state.memory.load(read_to, len(data)) - data_bvv = self.crash.state.solver.BVV(data) + data_bvv = claripy.BVV(data) return read_to, (glob_data == data_bvv) def _read_in_global_data_with_gets(self, data): @@ -297,7 +299,7 @@ def _read_in_global_data_with_gets(self, data): # constrain the address to be the chain chain_mem = self.crash.state.memory.load(chain_addr, len(chain.payload_str())) - chain_bvv = self.crash.state.solver.BVV(chain.payload_str()) + chain_bvv = claripy.BVV(chain.payload_str()) # the chain should be guaranteed to be satisfiable here self.crash.state.add_constraints(chain_mem == chain_bvv) @@ -306,7 +308,7 @@ def _read_in_global_data_with_gets(self, data): self._windup_to_unconstrained_successor() glob_data = self.crash.state.memory.load(read_to, len(data)) - data_bvv = self.crash.state.solver.BVV(data) + data_bvv = claripy.BVV(data) return read_to, (glob_data == data_bvv) def _find_func_address(self, symbol): @@ -424,7 +426,7 @@ def _ip_overwrite_call_shellcode(self, shellcode, variables=None): new_nop_constraints = [ ] sym_nop_mem = self.crash.state.memory.load(mem, length) - nop_sld_bvv = self.crash.state.solver.BVV(b"\x90" * length) + nop_sld_bvv = claripy.BVV(b"\x90" * length) nop_const = sym_nop_mem == nop_sld_bvv # can the nop sled exist? @@ -547,7 +549,7 @@ def _ip_overwrite_with_chain(self, chain, state=None, assert_next_ip_controlled= mem = state.memory.load(chain_addr, chain_cp.payload_len) try: - cbvv = state.solver.BVV(chain_cp.payload_str()) + cbvv = claripy.BVV(chain_cp.payload_str()) except angr.SimUnsatError: # it's completely possibly that the values we need need in the chain can't exist due to # constraints on memory, for example if we need the value '1' to exist in our chain, when diff --git a/rex/exploit/techniques/call_jmp_sp_shellcode.py b/rex/exploit/techniques/call_jmp_sp_shellcode.py index cf341bd..e9546cd 100644 --- a/rex/exploit/techniques/call_jmp_sp_shellcode.py +++ b/rex/exploit/techniques/call_jmp_sp_shellcode.py @@ -1,4 +1,7 @@ import logging + +import claripy + from rex import Vulnerability from rex.exploit import Exploit, CannotExploit, NoSuchShellcode from ..technique import Technique @@ -24,7 +27,7 @@ def check(self): def apply(self, **kwargs): # add the constraint that our shellcode must exist at sp - shellcode = self.crash.state.solver.BVV(self.shellcode.get_default()) + shellcode = claripy.BVV(self.shellcode.get_default()) stack_mem = self.crash.state.memory.load(self.crash.state.regs.sp, len(shellcode) // 8) self.crash.state.add_constraints(stack_mem == shellcode) if not self.crash.state.satisfiable(): diff --git a/rex/exploit/techniques/ret2libc.py b/rex/exploit/techniques/ret2libc.py index bf32ef9..1fecf22 100644 --- a/rex/exploit/techniques/ret2libc.py +++ b/rex/exploit/techniques/ret2libc.py @@ -110,7 +110,7 @@ def _write_cmd_str(self, cmd_str): l.debug("Applying all the constraints, fingers crossed...") payload = chain.payload_str(timeout=len(chain._values)*2) chain_mem = self.crash.state.memory.load(chain_addr, len(payload)) - chain_bvv = self.crash.state.solver.BVV(payload) + chain_bvv = claripy.BVV(payload) self.crash.state.add_constraints(chain_mem == chain_bvv) # windup @@ -133,7 +133,7 @@ def _invoke_system(self, system_addr, cmd_addr): # add the constraint to the state that the chain must exist at the address chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) payload = chain.payload_str(timeout=len(chain._values)*2) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(payload)) + self.crash.state.add_constraints(chain_mem == claripy.BVV(payload)) return # mips does some weird shit, we need to handle it separately @@ -141,7 +141,7 @@ def _invoke_system(self, system_addr, cmd_addr): chain, chain_addr = self._ip_overwrite_with_chain(chain, state=self.crash.state, rop=self.libc_rop) chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) payload = chain.payload_str(timeout=len(chain._values)*2) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(payload)) + self.crash.state.add_constraints(chain_mem == claripy.BVV(payload)) self._windup_to_unconstrained_successor() # list all potential JOP gadgets diff --git a/rex/exploit/techniques/rop_to_accept_system.py b/rex/exploit/techniques/rop_to_accept_system.py index 1b97e37..de6e198 100644 --- a/rex/exploit/techniques/rop_to_accept_system.py +++ b/rex/exploit/techniques/rop_to_accept_system.py @@ -1,6 +1,6 @@ import logging -from angrop.errors import RopException +import claripy from ...vulnerability import Vulnerability from .. import Exploit, CannotExploit @@ -79,7 +79,7 @@ def apply(self, **kwargs): # add the constraint to the state that the chain must exist at the address chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(chain.payload_str())) + self.crash.state.add_constraints(chain_mem == claripy.BVV(chain.payload_str())) if not self.crash.state.satisfiable(): raise CannotExploit("[%s] generated exploit is not satisfiable" % self.name) diff --git a/rex/exploit/techniques/rop_to_execl.py b/rex/exploit/techniques/rop_to_execl.py index 256ecf6..18e95d3 100644 --- a/rex/exploit/techniques/rop_to_execl.py +++ b/rex/exploit/techniques/rop_to_execl.py @@ -1,5 +1,6 @@ import logging +import claripy from angrop.errors import RopException from ...vulnerability import Vulnerability @@ -76,7 +77,7 @@ def apply(self, **kwargs): # add the constraint to the state that the chain must exist at the address chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(chain.payload_str())) + self.crash.state.add_constraints(chain_mem == claripy.BVV(chain.payload_str())) if not self.crash.state.satisfiable(): raise CannotExploit("[%s] generated exploit is not satisfiable" % self.name) diff --git a/rex/exploit/techniques/rop_to_system.py b/rex/exploit/techniques/rop_to_system.py index 1e6c752..29f6835 100644 --- a/rex/exploit/techniques/rop_to_system.py +++ b/rex/exploit/techniques/rop_to_system.py @@ -1,5 +1,6 @@ import logging +import claripy from angrop.errors import RopException from ...vulnerability import Vulnerability @@ -102,7 +103,7 @@ def apply(self, cmd=b'/bin/sh', **kwargs):# pylint:disable=arguments-differ # add the constraint to the state that the chain must exist at the address chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(chain.payload_str())) + self.crash.state.add_constraints(chain_mem == claripy.BVV(chain.payload_str())) if not self.crash.state.satisfiable(): raise CannotExploit("[%s] generated exploit is not satisfiable" % self.name) diff --git a/rex/exploit/techniques/rop_to_system_complicated.py b/rex/exploit/techniques/rop_to_system_complicated.py index c571f59..cc5bb7f 100644 --- a/rex/exploit/techniques/rop_to_system_complicated.py +++ b/rex/exploit/techniques/rop_to_system_complicated.py @@ -1,6 +1,7 @@ import logging import struct +import claripy from angrop.errors import RopException from ...vulnerability import Vulnerability @@ -129,7 +130,7 @@ def apply(self, to_exec=None, **kwargs): #pylint:disable=arguments-differ # add the constraint to the state that the chain must exist at the address chain_mem = self.crash.state.memory.load(chain_addr, chain.payload_len) - self.crash.state.add_constraints(chain_mem == self.crash.state.solver.BVV(chain.payload_str())) + self.crash.state.add_constraints(chain_mem == claripy.BVV(chain.payload_str())) if not self.crash.state.satisfiable(): raise CannotExploit("[%s] generated exploit is not satisfiable" % self.name) diff --git a/rex/exploit/techniques/shellcode_leak_address.py b/rex/exploit/techniques/shellcode_leak_address.py index 55098fb..1097364 100644 --- a/rex/exploit/techniques/shellcode_leak_address.py +++ b/rex/exploit/techniques/shellcode_leak_address.py @@ -1,7 +1,6 @@ import logging import claripy from rex import Vulnerability -from rex.exploit import CannotExploit from rex.exploit.cgc import CGCType2ShellcodeExploit from ..technique import Technique @@ -55,7 +54,7 @@ def apply(self, **kwargs): if jump_addr != shellcode_addr: nop_len = shellcode_addr - jump_addr sym_mem = ccp.state.memory.load(jump_addr, nop_len) - nop_bvv = ccp.state.solver.BVV(b"\x90" * nop_len) + nop_bvv = claripy.BVV(b"\x90" * nop_len) ccp.state.add_constraints(sym_mem == nop_bvv) shc_sym_mem = ccp.state.memory.load(shellcode_addr, len(shellcode)//8) diff --git a/rex/exploit/techniques/shellcode_set_register.py b/rex/exploit/techniques/shellcode_set_register.py index 4671c75..84ba82d 100644 --- a/rex/exploit/techniques/shellcode_set_register.py +++ b/rex/exploit/techniques/shellcode_set_register.py @@ -51,7 +51,7 @@ def set_register(self, register): if jump_addr != shellcode_addr: nop_len = shellcode_addr - jump_addr sym_mem = ccp.state.memory.load(jump_addr, nop_len) - nop_bvv = ccp.state.solver.BVV(b"\x90" * nop_len) + nop_bvv = claripy.BVV(b"\x90" * nop_len) ccp.state.add_constraints(sym_mem == nop_bvv) shc_sym_mem = ccp.state.memory.load(shellcode_addr, len(shellcode)//8)