netsh and the Windows Firewall

netsh advfirewall is the command-line control plane for Windows Defender Firewall — rule enumeration, rule creation, profile state. (The older netsh firewall context is deprecated; everything modern lives under advfirewall.) On an assessment it answers two questions fast: what does this host expose, and can I quietly change that.

Reconnaissance

netsh advfirewall show currentprofile
netsh advfirewall firewall show rule dir=in name=all
netsh advfirewall firewall show rule dir=out name=all

Reading the rule dump with an attacker’s eye:

  • Built-in rules are application-bound. Microsoft’s shipped rules typically scope to a specific binary (program=...), so an open port doesn’t mean your listener can use it.
  • Custom rules usually aren’t. Administrators writing their own rules seldom bind them to explicit applications — a custom “allow 80/443 inbound” rule is a free channel for any binary that can bind the port. There’s no reliable flag for “custom rule” in the CLI, but naming conventions (anything that isn’t a canned Microsoft group name) give them away.

Punching a hole

netsh advfirewall firewall add rule name=tunnel_in dir=in action=allow protocol=TCP localport="80,443,4444"
netsh advfirewall firewall add rule name=tunnel_out dir=out action=allow protocol=TCP localport="80,443,4444"

Notes from the tradecraft side:

  • Adding a rule beats disabling the firewall. Turning the profile off (netsh advfirewall set allprofiles state off) pops a security notification for every logged-on user — loud. A single narrow allow-rule generates no UI at all.
  • Riding existing rules is quieter still. If a custom application-unbound rule already permits the port, just bind it — no new artifacts.
  • Cleanup is symmetric: netsh advfirewall firewall delete rule name=tunnel_in.

Defense and detection

  • New rules appear in the Windows Firewall with Advanced Security operational log (EID 4946/4947/4948 for rule add/change/delete) — forward these; an unexpected tunnel_in-shaped rule is unambiguous.
  • PowerShell equivalents (New-NetFirewallRule, Get-NetFirewallRule) go through the same store and raise the same events, so monitoring the events catches both interfaces.
  • Rule-to-program binding audits close the “custom rule, any binary” gap described above — and netsh ... show rule ... verbose exposes which rules lack a program= scope.

Sources

  • netsh-portproxynetsh interface portproxy, the built-in TCP relay half of the same tool
  • netstat — correlating firewall exposure with actual listeners and connections
  • powershell-port-scanning — testing reachability through the rules you just read
  • icacls — the other built-in for auditing a different control plane (filesystem DACLs)
  • ssh — SSH remote forwards on a Windows pivot need an inbound rule here before other hosts can reach the forwarded port