diff --git a/windows_kext/driver/src/packet_callouts.rs b/windows_kext/driver/src/packet_callouts.rs index fb3ee90b8..4609aad0f 100644 --- a/windows_kext/driver/src/packet_callouts.rs +++ b/windows_kext/driver/src/packet_callouts.rs @@ -110,6 +110,13 @@ fn ip_packet_layer( interface_index: u32, sub_interface_index: u32, ) { + // Block all fragment data. No easy way to keep track of the origin and they are rarely used. + if data.is_fragment_data() { + data.action_block(); + crate::err!("blocked fragment packet"); + return; + } + let Some(device) = crate::entry::get_device() else { return; }; diff --git a/windows_kext/wdk/src/filter_engine/callout_data.rs b/windows_kext/wdk/src/filter_engine/callout_data.rs index bb861f84f..abb5e318c 100644 --- a/windows_kext/wdk/src/filter_engine/callout_data.rs +++ b/windows_kext/wdk/src/filter_engine/callout_data.rs @@ -133,6 +133,10 @@ impl<'a> CalloutData<'a> { } } + pub fn is_fragment_data(&self) -> bool { + unsafe { (*self.metadata).is_fragment_data() } + } + pub fn pend_operation( &mut self, packet_list: Option, diff --git a/windows_kext/wdk/src/filter_engine/metadata.rs b/windows_kext/wdk/src/filter_engine/metadata.rs index 632830fab..55b3b7de8 100644 --- a/windows_kext/wdk/src/filter_engine/metadata.rs +++ b/windows_kext/wdk/src/filter_engine/metadata.rs @@ -7,9 +7,9 @@ use windows_sys::Win32::{ NetworkManagement::{ IpHelper::IP_ADDRESS_PREFIX, WindowsFilteringPlatform::{ - FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_PROCESS_ID, - FWPS_METADATA_FIELD_PROCESS_PATH, FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, - FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, + FWPS_METADATA_FIELD_COMPLETION_HANDLE, FWPS_METADATA_FIELD_FRAGMENT_DATA, + FWPS_METADATA_FIELD_PROCESS_ID, FWPS_METADATA_FIELD_PROCESS_PATH, + FWPS_METADATA_FIELD_REMOTE_SCOPE_ID, FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA, FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE, FWP_BYTE_BLOB, FWP_DIRECTION, }, }, @@ -137,6 +137,14 @@ impl FwpsIncomingMetadataValues { None } + pub(crate) fn is_fragment_data(&self) -> bool { + if self.has_field(FWPS_METADATA_FIELD_FRAGMENT_DATA) { + return self.fragment_metadata.fragment_offset != 0; + } + + false + } + pub(crate) unsafe fn get_control_data(&self) -> Option> { if self.has_field(FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA) { if self.control_data.is_null() || self.control_data_length == 0 {