본문 바로가기
CTF./Angr Tutorial For CTF

06_angr_symbolic_daynamic_memory #Angr Tutorial For CTF

by 낭람._. 2022. 8. 25.
반응형

 

이번엔 동적 할당을 한 변수가 나왔다.

 

start_address는 scanf 이후로 한다.

 

  start_address = 0x08048699
  initial_state = project.factory.blank_state(
    addr=start_address,
    add_options = { angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
                    angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS}
  )

  # The binary is calling scanf("%8s %8s").
  # (!)
  password0 = claripy.BVS('password0', 64)
  password1 = claripy.BVS('password1', 64)

 

동적 할당한다면 어디에 할당되는지 주소를 모른다. 따라서 fake_heap_address 와 같이 가상의 주소를 임의로 지정해줘야한다.

  fake_heap_address0 = 0x602000
  pointer_to_malloc_memory_address0 = 0x0ABCC8A4
  initial_state.memory.store(pointer_to_malloc_memory_address0, fake_heap_address0, endness=project.arch.memory_endness)
  fake_heap_address1 = 0x602010
  pointer_to_malloc_memory_address1 = 0x0ABCC8AC
  initial_state.memory.store(pointer_to_malloc_memory_address1, fake_heap_address1, endness=project.arch.memory_endness)

    
    #fake_heap_addr = 0x602000
    #init_state.mem[buffer0_address].uint32_t = fake_heap_addr
    #init_state.mem[buffer1_address].uint32_t = fake_heap_addr + 9

아래 주석부분과 같이 짜도 된다. buffer0_address 부분에 pointer_to_malloc_memory_address0을 넣으면 된다.

 

pointer_to_malloc_memory_adress의 주소는 아래와 같이 bss영역에 있는 buffer0과 buffer1의 주소를 넣는다.

 

import angr
import claripy
import sys

def main(argv):
  path_to_binary = '06_angr_symbolic_dynamic_memory'
  project = angr.Project(path_to_binary)

  start_address = 0x08048699
  initial_state = project.factory.blank_state(
    addr=start_address,
    add_options = { angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
                    angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS}
  )

  # The binary is calling scanf("%8s %8s").
  # (!)
  password0 = claripy.BVS('password0', 64)
  password1 = claripy.BVS('password1', 64)

  # Instead of telling the binary to write to the address of the memory
  # allocated with malloc, we can simply fake an address to any unused block of
  # memory and overwrite the pointer to the data. This will point the pointer
  # with the address of pointer_to_malloc_memory_address0 to fake_heap_address.
  # Be aware, there is more than one pointer! Analyze the binary to determine
  # global location of each pointer.
  # Note: by default, Angr stores integers in memory with big-endianness. To
  # specify to use the endianness of your architecture, use the parameter
  # endness=project.arch.memory_endness. On x86, this is little-endian.
  # (!)
  fake_heap_address0 = 0x602000
  pointer_to_malloc_memory_address0 = 0x0ABCC8A4
  initial_state.memory.store(pointer_to_malloc_memory_address0, fake_heap_address0, endness=project.arch.memory_endness)
  fake_heap_address1 = 0x602010
  pointer_to_malloc_memory_address1 = 0x0ABCC8AC
  initial_state.memory.store(pointer_to_malloc_memory_address1, fake_heap_address1, endness=project.arch.memory_endness)

    
    #fake_heap_addr = 0x602000
    #init_state.mem[buffer0_address].uint32_t = fake_heap_addr
    #init_state.mem[buffer1_address].uint32_t = fake_heap_addr + 9


  # Store our symbolic values at our fake_heap_address. Look at the binary to
  # determine the offsets from the fake_heap_address where scanf writes.
  # (!)
  initial_state.memory.store(fake_heap_address0, password0)
  initial_state.memory.store(fake_heap_address1, password1)


  simulation = project.factory.simgr(initial_state)

  def is_successful(state):
    stdout_output = state.posix.dumps(sys.stdout.fileno())
    return b"Good Job." in state.posix.dumps(sys.stdout.fileno())

  def should_abort(state):
    stdout_output = state.posix.dumps(sys.stdout.fileno())
    return b"Try again." in state.posix.dumps(sys.stdout.fileno())

  simulation.explore(find=is_successful, avoid=should_abort)

  if simulation.found:
    solution_state = simulation.found[0]

    solution0 = solution_state.solver.eval(password0,cast_to=bytes).decode()
    solution1 = solution_state.solver.eval(password1,cast_to=bytes).decode()
    
    solution = solution0+" "+solution1

    print(solution)
  else:
    raise Exception('Could not find the solution')

if __name__ == '__main__':
  main(sys.argv)

 

반응형

댓글