T1205.002 Microsoft Sentinel · KQL

Detect Socket Filters in Microsoft Sentinel

Adversaries may attach Berkeley Packet Filter (BPF) programs or libpcap-based filters to raw network sockets to create passive backdoors that activate only upon receipt of crafted "magic" packets. Unlike conventional backdoors that maintain open listening ports, socket filter implants remain completely dormant—consuming negligible CPU, maintaining no active connections, and appearing nowhere in netstat or ss output—until a specially crafted packet matching the filter criteria arrives on the monitored interface. Implementation uses either libpcap's pcap_setfilter() function or the POSIX setsockopt() system call with SO_ATTACH_FILTER (cBPF, optname 26) or SO_ATTACH_BPF (eBPF, optname 50). The technique requires CAP_NET_RAW or CAP_NET_ADMIN on Linux, or Administrator rights on Windows with WinPcap/Npcap installed. Confirmed real-world malware families include BPFDoor (attaches BPF filters monitoring ICMP, UDP, and TCP traffic on ports 22/80/443, triggered by a "magic" byte sequence in incoming packets to spawn a reverse shell), Penquin/Turla (installs TCP and UDP filters on the eth0 interface for C2 activation), CASTLETAP (listens for specialized ICMP packets on compromised Fortinet devices), and PITSTOP (evaluates commands on a domain socket at /data/runtime/cockpit/wd.fd using a predefined magic byte sequence). Detection is exceptionally difficult due to the passive nature of the implant: no open ports, minimal CPU overhead, and limited enterprise visibility into raw socket API usage.

MITRE ATT&CK

Tactic
Defense Evasion Persistence Command and Control
Technique
T1205 Traffic Signaling
Sub-technique
T1205.002 Socket Filters
Canonical reference
https://attack.mitre.org/techniques/T1205/002/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// T1205.002 — Socket Filters / BPF Passive Backdoor Detection
// REQUIREMENT: Linux auditd with syslog forwarding to Microsoft Sentinel.
// Deploy these auditd rules on monitored Linux hosts:
//   -a always,exit -F arch=b64 -S socket -k bpf_socket_filter
//   -a always,exit -F arch=b64 -S setsockopt -k bpf_socket_filter
//   -a always,exit -F arch=b64 -S execve -k bpf_socket_filter
// Signal 1 (highest fidelity) is specific to setsockopt SO_ATTACH_FILTER.
// Signal 3 requires MDE Linux agent and does not need auditd.
let LegitimateCaptureBinaries = dynamic([
    "/usr/sbin/tcpdump", "/usr/bin/tcpdump",
    "/usr/bin/tshark", "/usr/bin/dumpcap",
    "/usr/sbin/dhclient", "/sbin/dhclient", "/usr/bin/dhclient",
    "/usr/sbin/arping", "/usr/bin/ping", "/bin/ping",
    "/usr/bin/nmap", "/usr/sbin/nmap",
    "/usr/bin/hping3", "/usr/sbin/hping3",
    "/usr/bin/scapy"
]);
// Signal 1: BPF filter attachment via setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, ...)
// x86-64 Linux: syscall=54 (setsockopt), a1=1 (SOL_SOCKET=1), a2=1a (SO_ATTACH_FILTER=26=0x1a)
// This is the exact syscall BPFDoor and libpcap use to install packet filters.
let BPFFilterAttach = Syslog
| where TimeGenerated > ago(24h)
| where SyslogMessage contains "type=SYSCALL"
    and SyslogMessage contains "syscall=54"
    and SyslogMessage contains "a1=1"
    and SyslogMessage contains "a2=1a"
| extend ProcessExe = extract(@"exe=\"([^\"]+)\"", 1, SyslogMessage)
| extend ProcessComm = extract(@"comm=\"([^\"]+)\"", 1, SyslogMessage)
| extend AuditUID = extract(@"\bauid=(\S+)", 1, SyslogMessage)
| extend HostPID = extract(@"\bpid=(\d+)", 1, SyslogMessage)
| extend HostPPID = extract(@"ppid=(\d+)", 1, SyslogMessage)
| where not(ProcessExe in~ (LegitimateCaptureBinaries))
| project TimeGenerated, HostName = Computer,
    ProcessExe, ProcessComm, AuditUID, HostPID, HostPPID,
    SignalType = "BPF_FILTER_SETSOCKOPT", ThreatLevel = "High";
// Signal 2: Raw packet socket creation by non-standard process
// AF_PACKET family = 17 = 0x11 (a0=11), or AF_INET+SOCK_RAW (a0=2 a1=3)
// x86-64 Linux: syscall=41 (socket())
let RawSocketCreate = Syslog
| where TimeGenerated > ago(24h)
| where SyslogMessage contains "type=SYSCALL"
    and SyslogMessage contains "syscall=41"
    and (
        SyslogMessage contains " a0=11 "   // AF_PACKET = 0x11
        or (SyslogMessage contains " a0=2 " and SyslogMessage contains " a1=3 ")  // AF_INET + SOCK_RAW
    )
| extend ProcessExe = extract(@"exe=\"([^\"]+)\"", 1, SyslogMessage)
| extend ProcessComm = extract(@"comm=\"([^\"]+)\"", 1, SyslogMessage)
| extend AuditUID = extract(@"\bauid=(\S+)", 1, SyslogMessage)
| extend HostPID = extract(@"\bpid=(\d+)", 1, SyslogMessage)
| extend HostPPID = extract(@"ppid=(\d+)", 1, SyslogMessage)
| where not(ProcessExe in~ (LegitimateCaptureBinaries))
| project TimeGenerated, HostName = Computer,
    ProcessExe, ProcessComm, AuditUID, HostPID, HostPPID,
    SignalType = "RAW_SOCKET_AF_PACKET", ThreatLevel = "Medium";
// Signal 3: MDE on Linux — process execution from world-writable staging paths
// BPFDoor copies itself to /tmp or /dev/shm before attaching filters and deleting original
let BPFDoorStagingExec = DeviceProcessEvents
| where TimeGenerated > ago(24h)
| where OSPlatform has "Linux"
| where FolderPath startswith "/tmp/"
    or FolderPath startswith "/dev/shm/"
    or FolderPath startswith "/var/tmp/"
    or FolderPath startswith "/run/shm/"
    or FolderPath == "/var/run/initd.lock"
| where InitiatingProcessFileName !in~ (
    "bash", "sh", "zsh", "dash", "ksh",
    "apt", "apt-get", "dpkg", "yum", "dnf", "rpm",
    "pip", "pip3", "make", "gcc", "cc", "g++", "cargo", "go"
  )
| project TimeGenerated, HostName = DeviceName,
    ProcessExe = FolderPath, ProcessComm = FileName,
    AuditUID = AccountSid,
    HostPID = tostring(ProcessId), HostPPID = tostring(InitiatingProcessId),
    SignalType = "BPFDOOR_STAGING_PATH_EXEC", ThreatLevel = "High";
union BPFFilterAttach, RawSocketCreate, BPFDoorStagingExec
| sort by TimeGenerated desc
high severity medium confidence

Multi-signal detection for BPF/libpcap-based passive socket filter backdoors on Linux endpoints. Signal 1 targets the exact setsockopt(SOL_SOCKET, SO_ATTACH_FILTER) syscall (syscall=54, a1=1, a2=0x1a) used by BPFDoor, Penquin/Turla, and any libpcap-based implant to install packet capture filters — this is the highest-fidelity indicator and does not fire for tcpdump/tshark since those use the same underlying mechanism, requiring careful allowlisting of legitimate capture binaries. Signal 2 detects raw socket creation (AF_PACKET or AF_INET+SOCK_RAW) by non-standard processes. Signal 3 uses MDE Linux telemetry to identify process execution from world-writable staging directories characteristic of BPFDoor's deployment pattern. All three signals use allowlists to reduce false positives from legitimate network utilities. Auditd rules for syscalls 41 and 54 must be deployed on Linux hosts for Signals 1 and 2; Signal 3 requires MDE Linux agent.

Data Sources

Linux: Audit Daemon (auditd) via syslog forwarding to SentinelMicrosoft Defender for Endpoint — Linux agentProcess: Process CreationNetwork: Network Connection Creation

Required Tables

SyslogDeviceProcessEvents

False Positives & Tuning

  • Network performance monitoring agents (Datadog, New Relic, Dynatrace, Elastic Agent) that use libpcap for packet-level sampling on Linux servers — these internally call setsockopt(SO_ATTACH_FILTER) and will trigger Signal 1
  • Container networking plugins in Kubernetes environments (Cilium in eBPF mode, Calico eBPF, Weave Net) that attach BPF programs to network interfaces as part of normal CNI pod networking — generates high volumes of BPF-related syscalls
  • Active network security tools such as Zeek (Bro), Suricata, Snort, or Falco running in packet capture mode on network sensors — all use AF_PACKET raw sockets
  • System daemons that open raw sockets for legitimate protocol handling: dhclient (DHCP), radvd (IPv6 RA), and keepalived (VRRP) use AF_INET raw sockets
  • Developer environments where engineers interactively run Scapy, Python socket experiments, or custom pcap-based tooling from /tmp or home directories
  • Kubernetes kube-proxy in iptables or ipvs mode and various CNI implementations executing scripts from temporary directories during pod network setup
Download portable Sigma rule (.yml)

Other platforms for T1205.002


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1AF_PACKET Raw Socket Creation (BPFDoor Initial Socket Setup)

    Expected signal: auditd SYSCALL record: type=SYSCALL arch=c000003e syscall=41 success=yes a0=11 a1=3 a2=3 comm="python3" exe="/usr/bin/python3" key="bpf_socket_filter". The a0=11 value (hex for AF_PACKET=17) is the primary indicator. MDE on Linux may generate a DeviceProcessEvents record for the python3 process with the command line containing the socket creation code.

  2. Test 2BPF Filter Attachment via setsockopt(SO_ATTACH_FILTER)

    Expected signal: Two auditd SYSCALL records will be generated: (1) socket() — syscall=41, a0=11, a1=3 with key=bpf_socket_filter; (2) setsockopt() — syscall=54, a1=1 (SOL_SOCKET), a2=1a (SO_ATTACH_FILTER=26=0x1a) with success=yes. Both records will have comm="python3" and exe="/usr/bin/python3". This is the highest-fidelity test of the primary detection signal.

  3. Test 3BPFDoor Binary Staging from Temporary Directory

    Expected signal: auditd SYSCALL record for execve (syscall=59) where exe=/dev/shm/.<random_name>. MDE Linux DeviceProcessEvents record with FolderPath='/dev/shm/' and FileName matching the random name. The random filename pattern (8 hex characters) mimics BPFDoor's naming convention. After deletion, a subsequent ls of /dev/shm would not show the file, but /proc/<pid>/exe would show '<path> (deleted)' if the process were still running.

  4. Test 4Magic Packet Trigger Simulation via ICMP with Specific Payload

    Expected signal: auditd SYSCALL records for socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) and sendto(). Network-level: ICMP packet visible in /proc/net/icmp or packet captures. If a network sensor (Zeek, Suricata) is monitoring the interface, the unusual ICMP payload bytes (0xDEADBEEF pattern) will appear in ICMP logs. MDE Network Events may capture the raw socket creation for the sending process.

Unlock Pro Content

Get the full detection package for T1205.002 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections