Back to posts

DutchOven

This research introduces DutchOven, a bounded Windows Filtering Platform primitive for measuring how applications behave during repeatable, application-scoped network brownouts.

13 min read

Abstract

This research presents DutchOven, a native Windows fault-injection primitive designed to create bounded, application-scoped network brownouts. Rather than stopping a service or installing persistent firewall policy, DutchOven uses Windows Filtering Platform (WFP) application identities, dynamic sessions, and transactional filter changes to alternate selected executable paths between blocked and permitted outbound connection authorization. The result is a repeatable experiment for measuring retry behavior, buffering, health-state transitions, delayed delivery, and recovery. This article explains the implementation, defines its actual traffic semantics, documents the validation model, and provides detection and resilience guidance for defenders.

1. Introduction

Security agents, observability collectors, deployment clients, and other distributed applications are frequently evaluated as though network connectivity were binary: available during normal operation and absent during an outage. Real environments are less orderly. Connections fail briefly, routes converge, upstream services throttle requests, and local processes remain alive while their control plane becomes intermittently unreachable.

Those partial failures are difficult to reproduce with service termination or permanent firewall rules. Stopping a process changes its local state, while persistent policy creates cleanup risk and often tests only a complete outage. DutchOven was created to produce a narrower condition: a deterministic block/pass duty cycle scoped to explicit executable paths and bounded by a fixed runtime.

The objective is not to claim that temporary network isolation disables every local security capability. It is to provide a controlled method for answering measurable questions: Does the application retry? Does it buffer? Does its backend record a gap? Does it recover without intervention? What evidence remains on the endpoint?

2. Background

2.1 Application Layer Enforcement

Windows Filtering Platform exposes filtering layers throughout the Windows network stack. DutchOven operates at the Application Layer Enforcement (ALE) authorization layers, where policy can be conditioned on the normalized identity of the executable that owns a flow.

FWPM_LAYER_ALE_AUTH_CONNECT_V4 and FWPM_LAYER_ALE_AUTH_CONNECT_V6 authorize outbound-initiated activity. They cover TCP connect() calls, the first UDP packet sent to a unique remote address and port tuple, and the first relevant outbound ICMP message. This is connection authorization rather than per-packet shaping: DutchOven does not introduce latency, limit bandwidth, or randomly discard a percentage of traffic.

An important distinction is that ALE flow direction is based on how the flow was initiated, not the direction of every packet it later carries. An outbound-established TLS connection contains both outbound requests and inbound responses while remaining an outbound-initiated ALE flow.

2.2 Dynamic WFP Sessions

WFP policy objects may be static, persistent, or dynamic. Persistent filters survive beyond the creating process and require deliberate removal. Dynamic objects instead belong to the engine session that created them and are deleted when that session closes or when the owning process terminates.

DutchOven opens its engine with FWPM_SESSION_FLAG_DYNAMIC:

c
1FWPM_SESSION0 session;
2memset(&session, 0, sizeof(session));
3session.displayData.name = L"DutchOven dynamic session";
4session.flags = FWPM_SESSION_FLAG_DYNAMIC;
5session.txnWaitTimeoutInMSec = 3000U;
6
7result = FwpmEngineOpen0(
8    NULL,
9    RPC_C_AUTHN_WINNT,
10    NULL,
11    &session,
12    &gate->engine
13);

The dynamic lifetime is the final cleanup boundary. DutchOven still removes active filters explicitly so that normal operation produces an observable transition back to the pass state, but session teardown remains authoritative if explicit deletion fails.

2.3 From Persistent Isolation to Bounded Brownouts

Prior work such as EDRSilencer demonstrated that persistent, application-conditioned WFP filters could prevent selected endpoint processes from establishing outbound communications. That research established the viability of the primitive, but persistent filters and product-oriented process enumeration produce a different operational model.

DutchOven makes three deliberate changes:

  1. Explicit Scope: Operators provide local absolute executable paths; the tool does not discover products or guess process ownership.
  2. Bounded Scheduling: Every invocation has a validated period, block duration, total duration, and optional warmup.
  3. Dynamic Ownership: The generated sublayer and filters exist only for the lifetime of the WFP session.

3. Methodology

3.1 Configuration and Safety Bounds

The standalone executable accepts up to 16 targets. Periods are limited to 100–60,000 milliseconds, scheduled operation is capped at 15 minutes, and warmup is capped at one minute. The block duration must be greater than zero and cannot exceed the period.

Named profiles provide common duty cycles, while explicit timing flags override those presets regardless of argument order. A full-period block is treated as a bounded blackout and avoids unnecessary remove/add churn.

3.2 Canonical Application Identity

WFP matches an application identity derived from its normalized image path, not an arbitrary process ID. DutchOven therefore enters through wmain, converts Windows UTF-16 arguments to UTF-8 for the portable parser, and converts each selected target back to UTF-16 for native path handling.

Before deriving the WFP application ID, the live Windows path is resolved with GetFullPathNameW, converted to its long form with GetLongPathNameW, and checked as an existing non-directory file. Long-path canonicalization matters because an 8.3 alias and the image's long-form path can otherwise produce identities that do not match.

This also defines the scope of the experiment: every process executing from a matched image path is affected. DutchOven does not target a single PID, user, destination, or port.

3.3 Atomic Filter Changes

For each target, DutchOven creates one IPv4 and one IPv6 filter. The only match condition is FWPM_CONDITION_ALE_APP_ID, and the action is a hard block:

c
1condition.fieldKey = FWPM_CONDITION_ALE_APP_ID;
2condition.matchType = FWP_MATCH_EQUAL;
3condition.conditionValue.type = FWP_BYTE_BLOB_TYPE;
4condition.conditionValue.byteBlob = app_id;
5
6filter.layerKey = *layer_key;
7filter.subLayerKey = gate->sublayer_key;
8filter.action.type = FWP_ACTION_BLOCK;
9filter.flags = FWPM_FILTER_FLAG_CLEAR_ACTION_RIGHT;

All filters for all targets are added within one WFP transaction. The pass transition similarly deletes every committed filter ID within one transaction. A failure aborts the operation rather than exposing only one address family or a partial target set.

The generated sublayer uses the top of the WFP sublayer weight range, and each filter uses the maximum FWP_UINT8 filter weight. Combined with FWPM_FILTER_FLAG_CLEAR_ACTION_RIGHT, this makes the block decision difficult for lower-priority permit policy to override.

3.4 Monotonic Scheduling

Wall-clock time is useful for correlating host, packet, and backend evidence, but it is unsafe as a scheduler because clock corrections can move it forward or backward. DutchOven schedules against GetTickCount64 and emits wall time separately.

Each cycle derives absolute deadlines from the original run start:

c
1ULONGLONG cycle_start =
2    run_start + ((ULONGLONG)cycle * (ULONGLONG)config->period_ms);
3ULONGLONG block_end = cycle_start + (ULONGLONG)config->block_ms;
4ULONGLONG cycle_end = cycle_start + (ULONGLONG)config->period_ms;

Absolute deadlines prevent small amounts of logging and WFP overhead from accumulating as schedule drift. Waits are divided into intervals of at most 50 milliseconds so that console interruption remains responsive.

3.5 Cleanup and Evidence

The console handler performs no WFP work. It sets an atomic stop flag and allows the main control path to remove filters and close the engine safely.

Text output is intended for an operator, while JSON Lines support evidence collection. A block event is emitted only after the add transaction commits. A pass event follows successful deletion, and the final cleanup record reports the remaining filter count, session-close status, cycle count, wall time, and monotonic elapsed time.

The configuration record appears before privilege checks and live target preparation, so it must not be interpreted as proof that WFP policy was installed.

3.6 Standalone and Beacon Modes

The standalone executable implements multi-target, multi-cycle scheduling. The x64 Beacon Object File intentionally implements a smaller operation: one explicit path, one synchronous pulse, and a maximum duration of five seconds. It uses Dynamic Function Resolution and contains no C runtime imports.

The BOF runs inline, which keeps its behavior compact but temporarily occupies Beacon. It refuses to target the executable hosting the BOF when that path can be resolved, installs the IPv4 and IPv6 filters transactionally, sleeps for the selected pulse, deletes both filters, and closes the dynamic session before returning.

4. Results and Analysis

4.1 Operation Profiles

ProfileBlockPassPeriodDurationIntended Measurement
light0.5 s4.5 s5 s60 sLow-impact retry behavior
brownout1.5 s3.5 s5 s60 sBalanced degradation and recovery
heavy3.5 s1.5 s5 s60 sQueue and recovery pressure
blackout5 s0 s5 s30 sShort, bounded full interruption

These profiles describe policy timing, not an assurance that an application will observe an identical outage. Transaction latency, connection reuse, proxy ownership, retry cadence, and backend behavior all affect the measured result.

4.2 Validation Model

A successful FwpmFilterAdd0 call proves only that WFP accepted the policy object. It does not prove that the intended application owned the tested flow, attempted a connection during the block, or produced a backend-visible gap.

The validation workflow therefore uses two copies of a harmless routed TCP canary:

  1. Establish baseline connectivity for the target and control.
  2. Install filters for the target canary only.
  3. Confirm a fresh target connection is rejected during the block.
  4. Confirm the control still connects.
  5. Confirm recovery after normal cleanup.
  6. Force-terminate DutchOven during a block and confirm dynamic-session cleanup.
  7. Dump WFP state and verify that no named session, sublayer, or filter remains.

The repository's documented DutchOven 0.4.1 validation on Windows Server 2022 with Elastic Defend 9.4.2 used three explicit application paths, producing six live filters across IPv4 and IPv6. After fresh connections were forced, the selected backend connections fell to zero while an unrelated control continued to reach the same network. The services remained running, no DutchOven WFP objects remained after exit, and agent health later recovered. This is one measured configuration, not a universal EDR result.

4.3 Operational Advantages

  1. Narrow Scope: Only explicit application identities are selected.
  2. Repeatability: Profiles and timing overrides make experiments reproducible.
  3. Atomicity: Applications and address families enter each state together.
  4. Bounded Impact: Parser limits constrain both duration and target count.
  5. Cleanup Resilience: Explicit deletion and dynamic-session teardown provide separate cleanup paths.
  6. Observable State: Transition events can be correlated with packets and backend telemetry.

4.4 Limitations

  1. Reauthorization: Adding or removing ALE policy can reauthorize an existing outbound flow. A matching hard block may terminate that flow when its next packet is classified; removal does not resurrect a terminated TCP connection.
  2. Connection Ownership: A helper, proxy, service host, or kernel component may own traffic attributed operationally to another product.
  3. Outbound-Initiated Scope: The standalone tool installs ALE_AUTH_CONNECT filters, not inbound ALE_AUTH_RECV_ACCEPT filters.
  4. No Packet Shaping: The tool blocks authorization; it does not simulate latency, jitter, reordering, or probabilistic loss.
  5. Deadline Pressure: Very short periods can be dominated by WFP transaction time, particularly with many targets.
  6. Dry-Run Scope: The portable dry-run validates configuration syntax and timing but does not prove that a Windows target exists or maps to the intended live flow.
  7. Local Capability: Network isolation does not stop local collection, prevention, buffering, or service execution.

5. Detection and Mitigation

5.1 WFP Policy Auditing

Dynamic WFP activity is represented by runtime policy events rather than persistent-filter events. When the relevant audit subcategory is enabled, defenders should investigate:

  • Event ID 5447: Runtime filter added or removed
  • Event ID 5450: Runtime sublayer added or removed
  • Event ID 5157: WFP blocked a connection
  • Event ID 5152: WFP blocked a packet
powershell
1Get-WinEvent -FilterHashtable @{
2    LogName = 'Security'
3    Id      = 5447, 5450
4} | Where-Object {
5    $_.Message -match 'DutchOven'
6}

The absence of these events is not proof of absence. Audit policy controls whether they are recorded, and high-volume environments may require additional collection and filtering design.

5.2 WFP State Monitoring

Active WFP state can be captured independently:

cmd
1netsh.exe wfp show state file=wfp-state.xml

DutchOven labels its session, sublayer, and filters. Defenders can correlate those names or runtime filter IDs with the creating process, complete command line, integrity level, and nearby connection-block events.

5.3 Behavioral Correlation

The strongest detection is not a single event ID. Useful correlations include:

  • A short-lived elevated process opening the local WFP engine
  • Runtime filter and sublayer creation by an unexpected executable
  • Repeated connection failures aligned with a regular duty cycle
  • Security telemetry buffering locally while backend delivery pauses
  • Runtime WFP objects disappearing when the creating process exits

5.4 Resilience Recommendations

Security and platform teams should test how critical applications behave when connectivity is intermittent rather than assuming a permanent outage model. Useful controls include bounded local queues, explicit degraded-health states, jittered retry with backoff, durable delivery identifiers, alternate telemetry paths where appropriate, and alerts when expected cloud communication disappears while the local service remains healthy.

6. Ethical Considerations

DutchOven changes live network policy and requires elevated access. It should be used only on systems and tenants for which the operator has explicit authorization. Experiments should begin with harmless canaries, include an unaffected control, capture independent evidence, and define stop conditions before targeting production-adjacent software.

The research value is defensive: understanding how endpoint and distributed systems degrade, what evidence remains, and whether cleanup and recovery behave as designed. Product-specific conclusions should not be published without reproducible measurements and appropriate coordination.

7. Conclusion

DutchOven turns an application-conditioned WFP block into a bounded fault-injection experiment. Its core contribution is not a new Windows filtering primitive, but an operational model built around explicit scope, dynamic ownership, transactional state changes, monotonic scheduling, and independent validation.

The resulting brownout can expose retry behavior, buffering, health transitions, and backend recovery without stopping the selected process. Its results remain dependent on ALE reauthorization, actual flow ownership, application retry logic, and the quality of the evidence collected around the experiment.

8. Future Work

Several areas warrant further investigation:

  1. Established-Flow Measurement: Characterize TCP and UDP reauthorization across supported Windows versions.
  2. IPv6 and UDP Validation: Extend the routed harness beyond short-lived IPv4 TCP connections.
  3. Deadline Telemetry: Emit explicit schedule-lateness and missed-cycle events.
  4. Live Pass Verification: Confirm recovery during each pass interval rather than only after process exit.
  5. Artifact Reproducibility: Pin the Windows and BOF toolchains for repeatable release hashes.
  6. Detection Validation: Publish tested audit policies and example 5447/5450 event records from representative systems.

Acknowledgments

DutchOven builds upon public Windows Filtering Platform research, including @netero_1010's EDRSilencer work. That research demonstrated the practical value of application-conditioned WFP filters and provided a foundation for examining safer, bounded, and independently measurable network-failure experiments.

References


Disclaimer: This research is provided for authorized educational and defensive security testing. Readers are responsible for complying with applicable laws, policies, and engagement boundaries. The author assumes no liability for misuse.