Beispiel #1
0
 def init(binary):
     BinaryAnalysis.clear()
     BinaryAnalysis.path = binary
     BinaryAnalysis.rawData = list(open(binary, 'rb').read())
     BinaryAnalysis.container = Container.from_stream(open(binary, 'rb'))
     BinaryAnalysis.locDB = BinaryAnalysis.container.loc_db
     BinaryAnalysis.machine = Machine(BinaryAnalysis.container.arch)
     BinaryAnalysis.iraType = BinaryAnalysis.machine.ira
     if isinstance(BinaryAnalysis.container, ContainerPE):
         BinaryAnalysis.binaryInfo = PEInfo(binary)
     elif isinstance(BinaryAnalysis.container, ContainerELF):
         BinaryAnalysis.binaryInfo = ELFInfo(binary)
     if BinaryAnalysis.binaryInfo.type == 'PE':
         if BinaryAnalysis.container.arch == 'x86_32':
             parser = Sandbox_Win_x86_32.parser(description="PE sandboxer")
             options = parser.parse_args()
             BinaryAnalysis.sb = Sandbox_Win_x86_32(BinaryAnalysis.path,
                                                    options, globals())
         elif BinaryAnalysis.container.arch == 'x86_64':
             parser = Sandbox_Win_x86_64.parser(description="PE sandboxer")
             options = parser.parse_args()
             BinaryAnalysis.sb = Sandbox_Win_x86_64(BinaryAnalysis.path,
                                                    options, globals())
     elif BinaryAnalysis.binaryInfo.type == 'ELF':
         if BinaryAnalysis.container.arch == 'x86_32':
             parser = Sandbox_Linux_x86_32.parser(
                 description="PE sandboxer")
             options = parser.parse_args()
             BinaryAnalysis.sb = Sandbox_Linux_x86_32(
                 BinaryAnalysis.path, options, globals())
         elif BinaryAnalysis.container.arch == 'x86_64':
             parser = Sandbox_Linux_x86_64.parser(
                 description="PE sandboxer")
             options = parser.parse_args()
             BinaryAnalysis.sb = Sandbox_Linux_x86_64(
                 BinaryAnalysis.path, options, globals())
     BinaryAnalysis.disasmEngine = BinaryAnalysis.machine.dis_engine(
         BinaryAnalysis.container.bin_stream,
         loc_db=BinaryAnalysis.container.loc_db)
     BinaryAnalysis.disasmEngine.dis_block_callback = detect_func_name
     BinaryAnalysis.maxSizeData = BinaryAnalysis.disasmEngine.attrib // 8
     BinaryAnalysis.strings = BinaryAnalysis.binaryInfo.findStrings()
     BinaryAnalysis.radare = r2pipe.open(binary)
     BinaryAnalysis.radare.cmd('aaa;')
     BinaryAnalysis.detectFunctions()
     BinaryAnalysis.disassembly()
     for start, end in (BinaryAnalysis.binaryInfo.codeRange -
                        BinaryAnalysis.doneInterval):
         BinaryAnalysis.data.append((start - 1, end))
     for start, end in BinaryAnalysis.binaryInfo.dataRange:
         BinaryAnalysis.data.append((start, end - 1))
Beispiel #2
0
    writes the string s and a trailing newline to stdout.
    '''
    ret_addr, args = jitter.func_args_systemv(['target'])
    output = jitter.get_c_str(args.target)
    # Check with expected result
    line = next(expected)
    if output != line.rstrip():
        print("Expected:", line)
        print("Obtained:", output)
        raise RuntimeError("Bad semantic")
    return jitter.func_ret_systemv(ret_addr, 1)


# Parse arguments
parser = Sandbox_Linux_x86_64.parser(description="ELF sandboxer")
parser.add_argument("filename", help="ELF Filename")
parser.add_argument("funcname", help="Targeted function's name")
parser.add_argument("expected", help="Expected output")
options = parser.parse_args()

# Expected output
expected = open(options.expected)

# Create sandbox
loc_db = LocationDB()
sb = Sandbox_Linux_x86_64(loc_db, options.filename, options, globals())
try:
    addr = sb.elf.getsectionbyname(".symtab")[options.funcname].value
except AttributeError:
    raise RuntimeError("The target binary must have a symtab section")
Beispiel #3
0
        for dst, src in dse.symb.modified(mems=False):
            if dst == dse.ir_arch.arch.regs.zf:
                vm_instr += "ZF = {}\n".format(dse.eval_expr(src))
            elif dst in vm_registers_symb and vm_registers_symb[dst] == ExprId(
                    "VM_PC", 64):
                vm_instr += "VM_PC = {}\n".format(dse.eval_expr(src))

    print(vm_instr.strip())

    # remove callback
    del dse.instrumentation[NEXT_ADDR]

    return True


parser = Sandbox_Linux_x86_64.parser("Disassembler for keykoolol challenge")
parser.add_argument("filename", help="Challenge filename")
options = parser.parse_args()

sb = Sandbox_Linux_x86_64(options.filename, options, globals())

dse = DSEEngine(sb.machine)
dse.add_lib_handler(sb.libs, globals())

DISPATCHER_ADDR = 0xa5D
NEXT_ADDR = 0xa77

vm_registers_symb = {}
already_disass = {}

dse.add_instrumentation(DISPATCHER_ADDR, symbolize_vm)
Beispiel #4
0
    data = info.fdesc.read(args.size * args.nmemb)
    jitter.vm.set_mem(args.ptr, data)
    return jitter.func_ret_stdcall(ret_addr, len(data))

def xxx_fclose(jitter):
    '''
    #include <stdio.h>

    int fclose(FILE *stream);
    '''
    ret_addr, args = jitter.func_args_systemv(['stream'])
    del FILE_to_info[args.stream]
    return jitter.func_ret_stdcall(ret_addr, 0)

# Create sandbox
parser = Sandbox_Linux_x86_64.parser(description="ELF sandboxer")
parser.add_argument("filename", help="ELF Filename")
parser.add_argument("--strategy",
                    choices=["code-cov", "branch-cov", "path-cov"],
                    help="Strategy to use for solution creation",
                    default="code-cov")
options = parser.parse_args()
options.mimic_env = True
options.command_line = ["%s" % TEMP_FILE.name]
sb = Sandbox_Linux_x86_64(options.filename, options, globals())

# Init segment
sb.jitter.ir_arch.do_stk_segm = True
sb.jitter.ir_arch.do_ds_segm = True
sb.jitter.ir_arch.do_str_segm = True
sb.jitter.ir_arch.do_all_segm = True
Beispiel #5
0
def run(jitter_setup, dse_setup):
  JitCore_Python.SymbExecClass = ESETrackMemory
  # Create sandbox
  parser = Sandbox_Linux_x86_64.parser(description='PE sandboxer')
  parser.add_argument('filename', help='PE Filename')
  parser.add_argument('-if', '--infile', nargs='?', help='Input buffer from file')
  parser.add_argument('-is', '--insize', nargs='?', default='32', help='Input buffer size')
  parser.add_argument('-fs', '--fullsymb', action='store_true', default=False, help='Forbid fallback to concretizing')
  parser.add_argument('-v', '--verbose', nargs='?', default='2', help='Verbosity level (0-4)')
  parser.add_argument('-df', '--dump', action='store_true', default=False, help='Dump crashing data blobs to files')
  options = parser.parse_args()
  # First thing, set log level
  log.setLevel(50-int(options.verbose)*10)
  options.jitter = 'llvm'
  options.mimic_env= True
  #options.singlestep = True
  # Input params
  if options.infile:
    with open(options.infile, 'rb') as f:
      input_buf= f.read()
  else:
    input_buf = os.urandom(int(options.insize, 0))
  # Instantiate
  loc_db = LocationDB()
  sb = Sandbox_Linux_x86_64(loc_db, options.filename, options, globals())
  jitter_setup(sb.jitter, int(options.address, 16), input_buf, len(input_buf))
  # Create and attach DSE
  dse = SecDSE(sb.machine, loc_db)
  dse.add_lib_handler(sb.libs, globals())
  dse.attach(sb.jitter)
  # Record valid memory ranges
  dse.refresh_valid_jitter_ranges()
  dse.update_state_from_concrete()
  # Configure DSE
  dse_setup(dse, input_buf)
  # Take snapshot
  snapshot = dse.take_snapshot()
  nb_run=0
  while dse.todos:
    nb_run+=1
    current = dse.get_todo()
    # Restore concrete & symb contexts
    dse.restore_snapshot(snapshot, keep_known_solutions=True)
    dse.symbolize_memory(current.to_symbolize)
    # Update the buffer in concrete engine
    sb.jitter.vm.set_mem(dse.input_buffer_ptr, current.buf)
    log.error('-'*80 + ' RUN #%i | %i INSTR visited | %i todos | %i crashes' % (nb_run, len(dse.visited_bbls), \
                                                                          len(dse.todos), len(dse.crashes) \
                                                                         )
             )
    log.error('SYMBOLIZED %s (%i/%i bytes)' % (str(current.to_symbolize), current.to_symbolize.length, len(input_buf)))
    try:
      sb.jitter.continue_run()
    except DriftException as e:
      print(hex(dse.jitter.pc) + ' ' + str(e))
      break
    # TODO: Rename to SymbToConcException
    except MemSquareException as e:
      # TODO: We can just concretize the byte and continue from here
      print(hex(dse.jitter.pc) + ' ' + str(e.info))
      dse.done()
      new_to_symbolize = current.to_symbolize
      for mem in e.ptr:
        # Concretize that byte and retry
        new_to_symbolize -= interval([(mem, mem)])
      # Compute all possible concrete bytes
      if options.fullsymb:
        for buf in dse.gen_new_bufs(e.ptr):
          dse.todos.append(todo(buf, current.to_symbolize)) # Put it in the todo list
      else:
        print('CONCRETIZING: ' + hex(mem))
        dse.todos.insert(0, todo(current.buf, new_to_symbolize))
      # Continue the current run?
      #import pdb; pdb.set_trace()
      continue
    except RuntimeError as e:
      message = str(e)
      log.warning(f'LIVE 0x{dse.jitter.pc:08X}: AV with "{message:s}"')
      dse.crashes.append(crash(dse.jitter.pc, None, 'UNDEFINED', current.buf))
      dse.done()
      continue
    except FnReturnException as e:
      log.info('FUNCTION RET')
      dse.done()
      continue
    except KeyboardInterrupt:
      break
    except Exception as e:
      dse.done()
      print(hex(dse.jitter.pc) + ' ' + str(type(e)) + ': ' + str(e))
      import pdb; pdb.set_trace()
      continue
  log.error('-'*80 + ' RESULTS | %i INSTR visited | %i todos | %i unique crashes' % (len(dse.visited_bbls), \
                                                                                   len(dse.todos), len(set(dse.crashes)) \
                                                                           )
           )
  for i, record in enumerate(set(dse.crashes)):
    if options.dump:
      hashval = record.__hash__()
      with open(f'crash_{hashval:X}', 'wb') as f:
        f.write(record.buf)
    log.error(str(record))
  log.error('-'*80)