def find_double_jumps(rop_finder,
                      allow_double=True,
                      allow_iret=True,
                      verbose=False):
    """
    Find gadgets that call a function and maintain control to jump to the next
    gadget.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadget + mipsrop.DoubleGadget)
    """
    gadgets = []
    if allow_double:
        doubles = rop_finder.find_doubles()
        gadgets.extend(doubles.gadgets)
    if allow_iret:
        move_t9 = mipsrop.MipsInstruction('move', 't9', '[sav][012345678]')
        irets = rop_finder.find_instructions([move_t9],
                                             controllable_calls=False,
                                             overwrite_register=['ra'])
        gadgets.extend(irets.gadgets)
    if verbose:
        print 'Found %d gadgets to call sleep and maintain control' % len(
            gadgets)
    return gadgets
def find_epilogue(rop_finder, controlled_registers):
    """
    Find epilogues that grant control of each register. Will only return 
    epilogues that grant control over more registers than originally used.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :param controlled_registers: Registers controlled.
    :type controlled_registers: list(str)

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadgets)
    """
    epilogue = mipsrop.MipsInstruction('.*lw', 'ra')
    function_epilogue = []

    for i in range(0, len(mipsropchain.REGISTERS)):
        control_registers = mipsropchain.REGISTERS[:i + 1]
        if all(reg in controlled_registers for reg in control_registers):
            continue
        epilogue_gadget = rop_finder.find_instructions(
            [epilogue],
            controllable_calls=False,
            overwrite_register=control_registers,
            preserve_register=mipsropchain.REGISTERS[i + 1:])
        if epilogue_gadget.gadgets:
            function_epilogue.append(epilogue_gadget.gadgets[0])
    return function_epilogue
示例#3
0
def find_stack_finders(rop_finder, terminating, controllable, verbose):
    """
    Find gadgets that move a stack pointer to a register. Movement to a0 is
    specifically ignored because the system gadget finder does that.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :param terminating: Return tail gadgets.
    :type terminating: bool

    :param controllable: Return controllable calls.
    :type controllable: bool

    :param verbose: Enable verbose output.
    :type verbose: bool

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadget)
    """
    sf_saved_reg = mipsrop.MipsInstruction('.*addiu', '[sva][012345678]', 'sp')
    stack_finders = rop_finder.find_instructions(
        [sf_saved_reg],
        terminating_calls=terminating,
        controllable_calls=controllable)
    if verbose:
        print 'Found %d gadgets to find shellcode on the stack.' % \
            len(stack_finders.gadgets)
    return stack_finders.gadgets
示例#4
0
def find_epilogue(rop_finder, controlled_registers):
    """
    Find epilogues that grant control of each register. Ideal will return nine
    gadgets one that gives control of s0, one that gives control of s0 and s1,
    one that gives control of s0/s1/s2, etc.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadgets)
    """
    epilogue = mipsrop.MipsInstruction('.*lw', 'ra')
    function_epilogue = []

    for i in range(0, len(mipsropchain.REGISTERS)):
        control_registers = mipsropchain.REGISTERS[:i + 1]
        if all(reg in controlled_registers for reg in control_registers):
            continue
        epilogue_gadget = rop_finder.find_instructions(
            [epilogue],
            controllable_calls=False,
            overwrite_register=control_registers,
            preserve_register=mipsropchain.REGISTERS[i + 1:])
        if epilogue_gadget.gadgets:
            function_epilogue.append(epilogue_gadget.gadgets[0])
    return function_epilogue
示例#5
0
def find_system_calls(rop_finder, terminating, controllable, verbose):
    """
    Find single gadget chains to call system with a controllable string in
    a0.

    :param rop_finder: MIPS rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :param terminating: Return tail gadgets.
    :type terminating: bool

    :param controllable: Return controllable calls.
    :type controllable: bool

    :param verbose: Enable verbose output.
    :type verbose: bool

    :returns: Discovered gadgets
    :rtype: list(mipsrop.RopGadgets)
    """
    system_call = mipsrop.MipsInstruction('.*addiu', 'a0', 'sp')
    stack_finders = rop_finder.find_instructions(
        [system_call],
        terminating_calls=terminating,
        controllable_calls=controllable)
    if verbose:
        print 'Found %d gadgets to call system.' % \
            len(stack_finders.gadgets)
    return stack_finders.gadgets
def find_shellcode_jump(rop_finder, verbose):
    """
    Find gadgets that call a register.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadget)
    """
    move_t9 = mipsrop.MipsInstruction('mov', 't9')
    call_register = rop_finder.find_instructions([move_t9])
    if verbose:
        print 'Found %d gadgets to call shellcode.' % len(
            call_register.gadgets)
    return call_register.gadgets
def find_lia0_calls(rop_finder, vebose):
    """
    Find calls the load a value smaller than 16 into $a0.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadget)
    """
    li_a0 = mipsrop.MipsInstruction('.*li', 'a0', '0x[0-9a-f]')
    small_value = rop_finder.find_instructions([li_a0])
    if verbose:
        print 'Found %d gadgets to load a small value into a0' % \
            len(small_value.gadgets)
    return small_value.gadgets
def find_stack_finders(rop_finder, verbose):
    """
    Find gadgets that move a stack pointer to a register.

    :param rop_finder: Mips rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :returns: Gadgets found.
    :rtype: list(mipsrop.RopGadget)
    """
    sf_saved_reg = mipsrop.MipsInstruction('.*addiu', '[sva][012345678]', 'sp')
    stack_finder_gadgets = rop_finder.find_instructions(
        [sf_saved_reg], terminating_calls=False)
    if verbose:
        print 'Found %d gadgets to find shellcode on the stack.' % \
            len(stack_finder_gadgets.gadgets)
    return stack_finder_gadgets.gadgets
示例#9
0
def system_tail_two_jump(chain_builder, mips_rop):
    """
    Search for chain that moves a stack string to a0 in a tail call.

    :param chain_builder: Initialized chain builder class.
    :type chain_builder: mipsropchain.ChainBuilder

    :param mips_rop: Mips rop finder class.
    :type mips_rop: mipsrop.MipsRop
    """
    stack_finders = find_system_calls(mips_rop, True, False, verbose)
    chain_builder.add_gadgets('Find command on the stack from tail call',
                              stack_finders)

    move_t9 = mipsrop.MipsInstruction('mov', 't9')
    call_register = mips_rop.find_instructions([move_t9],
                                               preserve_register='a0',
                                               terminating_calls=False)
    chain_builder.add_gadgets('Call system.', call_register.gadgets)
    chain_builder.generate_chain()
    chain_builder.gadgets = []
示例#10
0
def find_move_a0(rop_finder, verbose):
    """
    Find gadget that moves a register to a0.

    :param rop_finder: MIPS rop finder class.
    :type rop_finder: mipsrop.MipsRop

    :param verbose: Enable verbose output.
    :type verbose: bool

    :returns: Discovered gadgets
    :rtype: list(mipsrop.RopGadgets)
    """
    move_a0_ins = mipsrop.MipsInstruction('.*move', 'a0', '[sva][012345678]')
    # System cannot be called from an epilogue. $gp is calculated based on the
    # call occurring from $t9.
    move_a0 = rop_finder.find_instructions([move_a0_ins],
                                           terminating_calls=False)
    if verbose:
        print 'Found %d gadgets to move a register to $a0.' % \
            len(move_a0.gadgets)
    return move_a0.gadgets
示例#11
0
# Find MIPS ROP gadgets for gaining control of more registers through function epilogues.
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Gadgets.Epilogue

from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

registers = ['s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8']

min_reg = askChoice('Minimum Register',
                    'What is the lowest register you want to control?',
                    ['Any'] + registers, 'Any')
if min_reg == 'Any':
    min_reg = None

if min_reg:
    print 'Searching for function epilogues that grant control of registers up to %s...' % min_reg

epilogue = mipsrop.MipsInstruction('.*lw', 'ra')

mips_rop = mipsrop.MipsRop(currentProgram)
function_epilogue = mips_rop.find_instructions(
    [epilogue],
    overwrite_register=registers[:registers.index(min_reg) + 1],
    controllable_calls=False)

function_epilogue.pretty_print()
示例#12
0
# Find MIPS ROP gadgets that load a small value into a0. Useful for calling sleep.
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Gadgets.Li a0


from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

li_a0 = mipsrop.MipsInstruction('.*li', 'a0', '0x.*')

mips_rop = mipsrop.MipsRop(currentProgram)
sleep_calls = mips_rop.find_instructions([li_a0])

sleep_calls.pretty_print()
示例#13
0
# Find MIPS ROP gadgets that perform an indirect return. (Call t9, return to ra.)
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Gadgets.Indirect Return

from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

move_t9 = mipsrop.MipsInstruction('move', 't9', '[sav][012345678]')

mips_rop = mipsrop.MipsRop(currentProgram)
indirect_returns = mips_rop.find_instructions([move_t9],
                                              controllable_calls=False,
                                              overwrite_register=['ra'])

indirect_returns.pretty_print()
示例#14
0
# Find MIPS ROP gadgets near the beginning of functions that allow for stack pointer movement.
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Gadgets.Prologue


from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

prologue = mipsrop.MipsInstruction('.*addiu', 'sp', 'sp', '-.*')

mips_rop = mipsrop.MipsRop(currentProgram)
function_prologue = mips_rop.find_instructions([prologue])

function_prologue.pretty_print()
示例#15
0
# Find MIPS ROP gadgets for calling system with a user controlled argument.
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Gadgets.System Calls

from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

set_a0 = mipsrop.MipsInstruction('.*addiu', 'a0', 'sp')

mips_rop = mipsrop.MipsRop(currentProgram)
system_rops = mips_rop.find_instructions([set_a0],
                                         'a0',
                                         terminating_calls=False)

system_rops.pretty_print()
示例#16
0
import re
from utils import mipsrop, utils

utils.allowed_processors(currentProgram, 'MIPS')

op1 = None
op2 = None
op3 = None

search = askString('MIPS ROP Find',
                   'What instruction do you want to search for?')
try:
    search = re.sub(' +', ' ', search)
    mnem, operands = search.split(' ', 1)
    operands = operands.replace(' ', '')
    operands = operands.split(',')
    op1, op2, op3 = operands + [None] * (3 - len(operands))
except ValueError:
    mnem = search

if not mnem.startswith('.*'):
    mnem = '.*' + mnem

search_ins = mipsrop.MipsInstruction(mnem, op1, op2, op3)

mips_rop = mipsrop.MipsRop(currentProgram)
indirect_returns = mips_rop.find_instructions([search_ins])

indirect_returns.pretty_print()
示例#17
0
# Find MIPS ROP gadgets that put a stack address in a register.
#@author fuzzywalls
#@category TNS
#@menupath TNS.Mips Rops.Stack Finder

from utils import mipsrop

sf_saved_reg = mipsrop.MipsInstruction('.*addiu', '[sva][012345678]', 'sp')

mips_rop = mipsrop.MipsRop(currentProgram)
stack_finders = mips_rop.find_instructions([sf_saved_reg])

stack_finders.pretty_print()