Esempio n. 1
0
 def __init__(self, binary):
     self.binary = binary
     self.chain_builder = ChainBuilder()
Esempio n. 2
0
class Exrop(object):
    def __init__(self, binary):
        self.binary = binary
        self.chain_builder = ChainBuilder()

    def find_gadgets(self, cache=False):
        if cache:
            fcname = "./{}.exrop_cache".format(self.binary.replace("/", "_"))
            try:
                with open(fcname, "rb") as fc:
                    objpic = fc.read()
                    self.chain_builder.load_analyzed_gadgets(objpic)
                    return
            except FileNotFoundError:
                fc = open(fcname, "wb")
        gadgets = parseRopGadget(self.binary)
        self.chain_builder.load_list_gadget_string(gadgets)
        self.chain_builder.analyzeAll()
        if cache:
            objpic = self.chain_builder.save_analyzed_gadgets()
            fc.write(objpic)
            fc.close()

    def load_raw_gadgets(self, gadgets):
        pass

    def set_regs(self, regs, next_call=None, avoid_char=None):
        self.chain_builder.set_regs(regs)
        self.chain_builder.solve_chain(avoid_char)
        ropchain = self.chain_builder.build_chain(next_call)
        return ropchain

    def set_writes(self, writes, next_call=None):
        self.chain_builder.set_writes(writes)
        self.chain_builder.solve_chain_write()
        ropchain = self.chain_builder.build_chain(next_call)
        return ropchain

    def set_string(self, strs, next_call=None):
        BSIZE = 8
        writes = dict()
        for addr, sstr in strs.items():
            tmpaddr = 0
            for i in range(0, len(sstr), BSIZE):
                tmpstr = int.from_bytes(
                    bytes(sstr[i:i + BSIZE] + "\x00", 'utf-8'), 'little')
                writes[addr + tmpaddr] = tmpstr
                tmpaddr += BSIZE
        return self.set_writes(writes, next_call)

    def func_call(self, func_addr, args, rwaddr=None, convention="sysv"):
        order_reg = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"]
        regsx86_64 = [
            "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11",
            "r12", "r13", "r14", "r15"
        ]
        regs = dict()
        ropchain = RopChain()
        for i in range(len(args)):
            arg = args[i]
            if isinstance(arg, str) and arg not in regsx86_64:
                assert rwaddr, "Please define read write addr"
                arg += "\x00"
                chain = self.set_string({rwaddr: arg})
                ropchain.merge_ropchain(chain)
                regs[order_reg[i]] = rwaddr
                rwaddr += len(arg)
                continue
            regs[order_reg[i]] = arg
        chain = self.set_regs(regs, func_addr)
        ropchain.merge_ropchain(chain)
        return ropchain
Esempio n. 3
0
        avoid_char = data_test['badchars']
    chain_builder.solve_chain_write(avoid_char=avoid_char)


def test_pivot(data_test):
    avoid_char = None
    if 'badchars' in data_test:
        avoid_char = data_test['badchars']
    chain_builder.solve_pivot(data_test['find'], avoid_char=avoid_char)


with open(sys.argv[1], "rb") as fp:
    data_test = eval(fp.read())
    gadgets = data_test['gadgets']
    for addr in gadgets:
        gadgets[addr] = (gadgets[addr], asm_ins(gadgets[addr]))
    chain_builder = ChainBuilder()
    chain_builder.load_list_gadget_string(gadgets)
    chain_builder.analyzeAll()
    code.interact(local=locals())

    if "type" not in data_test or data_test['type'] == 'reg':
        test_reg(data_test)
    elif data_test['type'] == 'write_mem':
        test_write(data_test)
    elif data_test['type'] == 'pivot':
        test_pivot(data_test)

    build_chain = chain_builder.build_chain()
    build_chain.dump()
Esempio n. 4
0
class Exrop(object):
    def __init__(self, binary):
        self.binary = binary
        self.chain_builder = ChainBuilder()

    def find_gadgets(self, cache=False, add_opt="", num_process=1):
        if cache:
            fcname = "./{}.exrop_cache".format(self.binary.replace("/", "_"))
            try:
                with open(fcname, "rb") as fc:
                    objpic = fc.read()
                    self.chain_builder.load_analyzed_gadgets(objpic)
                    return
            except FileNotFoundError:
                fc = open(fcname, "wb")
        gadgets = parseRopGadget(self.binary, add_opt)
        self.chain_builder.load_list_gadget_string(gadgets)
        self.chain_builder.analyzeAll(num_process)
        if cache:
            objpic = self.chain_builder.save_analyzed_gadgets()
            fc.write(objpic)
            fc.close()

    def load_raw_gadgets(self, gadgets):
        pass

    def stack_pivot(self, addr, avoid_char=None):
        self.chain_builder.solve_pivot(addr, avoid_char)
        ropchain = self.chain_builder.build_chain()
        return ropchain

    def set_regs(self, regs, next_call=None, avoid_char=None):
        self.chain_builder.set_regs(regs)
        self.chain_builder.solve_chain(avoid_char)
        ropchain = self.chain_builder.build_chain(next_call)
        return ropchain

    def set_writes(self, writes, next_call=None, avoid_char=None):
        self.chain_builder.set_writes(writes)
        self.chain_builder.solve_chain_write(avoid_char=avoid_char)
        ropchain = self.chain_builder.build_chain(next_call)
        return ropchain

    def set_string(self, strs, next_call=None, avoid_char=None):
        BSIZE = 8
        writes = dict()
        for addr, sstr in strs.items():
            tmpaddr = 0
            sstr += "\x00"
            for i in range(0, len(sstr), BSIZE):
                tmpstr = int.from_bytes(bytes(sstr[i:i + BSIZE], 'utf-8'),
                                        'little')
                writes[addr + tmpaddr] = tmpstr
                tmpaddr += BSIZE
        return self.set_writes(writes, next_call, avoid_char=avoid_char)

    def func_call(self,
                  func_addr,
                  args,
                  rwaddr=None,
                  convention="sysv",
                  type_val_addr=0,
                  comment=""):
        call_convention = {
            "sysv": ["rdi", "rsi", "rdx", "rcx", "r8", "r9"],
            "syscall_x86-64": ["rax", "rdi", "rsi", "rdx", "r10", "r8", "r9"]
        }

        order_reg = call_convention[convention]
        regsx86_64 = [
            "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11",
            "r12", "r13", "r14", "r15"
        ]
        regs = dict()
        ropchain = RopChain()
        for i in range(len(args)):
            arg = args[i]
            if isinstance(arg, str) and arg not in regsx86_64:
                assert rwaddr, "Please define read write addr"
                chain = self.set_string({rwaddr: arg})
                ropchain.merge_ropchain(chain)
                regs[order_reg[i]] = rwaddr
                rwaddr += len(arg) + 1  # for null byte
                continue
            regs[order_reg[i]] = arg
        chain = self.set_regs(regs)
        ropchain.merge_ropchain(chain)
        ropchain.set_next_call(func_addr, type_val_addr, comment=comment)
        return ropchain

    def syscall(self, sysnum, args, rwaddr=None):
        reg_used_syscall = set(["rax", "rdi", "rsi", "rdx", "r10", "r8", "r9"])
        args = (sysnum, ) + args
        syscall = self.chain_builder.get_syscall_addr(
            not_write_regs=reg_used_syscall)
        assert syscall, "can't find syscall gadget!"
        chain = self.func_call(syscall.addr,
                               args,
                               rwaddr,
                               convention="syscall_x86-64",
                               type_val_addr=1,
                               comment=str(syscall))
        if syscall.end_type != TYPE_RETURN:
            chain.is_noreturn = True
        return chain
Esempio n. 5
0
from ChainBuilder import ChainBuilder
from Exrop import Exrop
from Gadget import *
import sys

if len(sys.argv) == 1:
    print("use: {} test_file".format(sys.argv[0]))
    sys.exit(1)

with open(sys.argv[1], "rb") as fp:
    data_test = eval(fp.read())
    chain_builder = ChainBuilder()
    chain_builder.load_list_gadget_string(data_test['gadgets'])
    chain_builder.analyzeAll()
    chain_builder.set_regs(data_test['find'])
    avoid_char = None
    if 'badchars' in data_test:
        avoid_char = data_test['badchars']
    chain_builder.solve_chain(avoid_char=avoid_char)
    build_chain = chain_builder.build_chain()
    build_chain.dump()