// SPDX-License-Identifier: MIT /** * eBPF Port Knocking Program * Cross-platform: Linux and Windows * * This program monitors incoming TCP connection attempts and tracks sequences * of ports. When the correct sequence (7000, 8000, 9000 by default) is * detected, it allows access to port 31337. * Some includes and other files are missing because this is not the full PoC. */ #include #include #define SEQUENCE_LEN 3 #define TARGET_PORT 31337 #ifdef _WIN32 #include "bpf_helpers.h" #include "xdp_hooks.h" typedef xdp_md_t xdp_md_ctx_t; typedef xdp_action_t xdp_return_t; #define XDP_RETURN_PASS XDP_PASS #define XDP_RETURN_DROP XDP_DROP #else #include #include #include #include #include #include typedef struct xdp_md xdp_md_ctx_t; typedef int xdp_return_t; #define XDP_RETURN_PASS XDP_PASS #define XDP_RETURN_DROP XDP_DROP #endif struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); __type(key, uint32_t); __type(value, uint32_t); __uint(max_entries, 1024); } knock_tracker SEC(".maps"); #ifndef _WIN32 char _license[] SEC("license") = "GPL"; #endif SEC("xdp") xdp_return_t port_knock_xdp(xdp_md_ctx_t* ctx) { #ifdef _WIN32 void* data = ctx->data; void* data_end = ctx->data_end; #else void* data = (void*)(long)ctx->data; void* data_end = (void*)(long)ctx->data_end; #endif if ((unsigned char*)data + 54 > (unsigned char*)data_end) return XDP_RETURN_PASS; unsigned char* pkt = (unsigned char*)data; if (pkt[12] != 0x08 || pkt[13] != 0x00) return XDP_RETURN_PASS; if (pkt[23] != 6) return XDP_RETURN_PASS; uint32_t src_ip = pkt[26] | (pkt[27] << 8) | (pkt[28] << 16) | (pkt[29] << 24); if ((pkt[47] & 0x02) != 0x02) return XDP_RETURN_PASS; uint16_t dport = (pkt[36] << 8) | pkt[37]; bpf_printk("Packet: src_ip=%d, dport=%d", src_ip, dport); if (dport == TARGET_PORT) { uint32_t* val = bpf_map_lookup_elem(&knock_tracker, &src_ip); uint32_t state = val ? *val : 0; bpf_printk("Target port check: state=%d", state); if (state == 3) { bpf_printk("ALLOWED: IP authorized"); return XDP_RETURN_PASS; } else { bpf_printk("DENIED: IP not authorized"); return XDP_RETURN_DROP; } } if (dport == 7000 || dport == 8000 || dport == 9000) { uint32_t* val = bpf_map_lookup_elem(&knock_tracker, &src_ip); uint32_t state = val ? *val : 0; bpf_printk("Knock port: dport=%d, current_state=%d", dport, state); /* Only advance if we're moving forward in the sequence */ if ((state == 0 && dport == 7000) || (state == 1 && dport == 8000) || (state == 2 && dport == 9000)) { if (state == 2) { /* Complete sequence */ uint32_t new_state = 3; bpf_map_update_elem(&knock_tracker, &src_ip, &new_state, 0); bpf_printk("Sequence COMPLETE! IP authorized"); } else { /* Advance to next stage */ uint32_t new_state = state + 1; bpf_map_update_elem(&knock_tracker, &src_ip, &new_state, 0); bpf_printk("Advanced to stage %d", new_state); } } /* Don't update state on retries - just pass */ } return XDP_RETURN_PASS; }