Skip to content

This tool is not affiliated with, endorsed by or sponsored by Microsoft Corporation. Azure, Microsoft Azure and Microsoft Defender for Cloud are trademarks of the Microsoft group of companies. Other names are trademarks of their respective owners.

NSG and VNet flow logs analysis for exfiltration

NSG and VNet flow logs analysis for incident response: tuple formats, bytes and flow states, spotting exfiltration, mining and attacker IPs, blind spots.

Published on 6 min read

TL;DR. Flow logs are Layer-4 records of every flow through your NSGs (NSG flow logs) or VNets (VNet flow logs), written to storage every minute as tuples: timestamp, source, destination, ports, protocol, direction, decision or state, and — for NSG v2 and VNet flow logs — packets and bytes each way. For incident response they answer three questions: did a compromised VM talk to the attacker's IP, did a lot of data leave to one address, and is anything reaching mining pools or management ports. NSG flow logs retire on September 30, 2027; VNet flow logs replace them. Flow logs cannot see Internet clients downloading straight from a storage account.

Flow logs are the least glamorous Azure log and often the one that closes the case. The Activity Log says "Run Command at 02:19"; the flow log says "at 02:20 the VM fetched 46 KB from the attacker's IP on port 80". That is the difference between suspicion and confirmation.

Two formats, one idea

NSG flow logsVNet flow logs
ScopeOne network security groupA whole virtual network (subnets, NICs)
StatusRetiring 2027-09-30; no new ones can be createdCurrent
Storage containerinsights-logs-networksecuritygroupfloweventinsights-logs-flowlogflowevent
Record categoryNetworkSecurityGroupFlowEventFlowLogFlowEvent
Timestamp in tupleUnix secondsUnix milliseconds
ProtocolT / UIANA number (6 = TCP, 17 = UDP)
DecisionSeparate field A / DFlow state D for denied
Bytes / packetsVersion 2 onlyYes, plus encryption state

Both are written at one-minute intervals (NSG flow logs, VNet flow logs). A version 2 NSG tuple:

1542110379,10.5.16.4,203.0.113.117,59932,443,T,O,A,E,1,66,1,66

reads: time, source IP, destination IP, source port, destination port, TCP, outbound, allowed, flow ended, 1 packet / 66 bytes sent, 1 packet / 66 bytes received. A VNet tuple:

1663146003606,10.0.0.6,192.0.2.180,23956,443,6,O,E,NX,3,767,2,1580

adds the encryption status (NX = not encrypted) and uses milliseconds and IANA protocol numbers.

Counting bytes correctly

Flow states are Begin (no counters), Continuing (counters every five minutes for long flows) and End (final counters); VNet flow logs add Deny. Microsoft specifies that C and E counters are "aggregate counts from the time of the previous flow's tuple record" — so the conversation total is the sum of all C and E tuples, not the last one. Double-counting and under-counting both happen when this is ignored.

Two further traps from Microsoft's documentation:

  • For NSG flow logs, flows hitting non-default inbound TCP rules are handled statelessly and byte and packet counts are not recorded; VNet flow logs support bytes and packets for stateless flows.
  • VMs without a public IP can still show inbound tuples from Internet addresses on SNAT ports; the attempt is logged although Azure does not deliver it.

What to look for

PatternWhy it mattersAnalyzer rule
Any flow between a VM and an IP already seen in other findings (the IP that ran Run Command, read the vault…)Links the control-plane attacker to on-VM activity: second-stage download, C2, exfiltrationAZ-NET-004, high
More than 500 MB outbound from the network to one public IPExfiltration candidate (T1048)AZ-NET-003, medium
Outbound to ports typical of mining pools (3333, 4444, 5555, 7777, 14433, 14444, 45560, 45700)Crypto-mining (T1496)AZ-NET-002, high
Allowed inbound from public IPs to 22, 3389, 5985, 5986Management ports exposed (T1133)AZ-NET-001, medium
Denied inbound scansBackground noise on any public IP— (context only)

AZ-NET-004 is the most valuable because it needs no threshold: once the analyzer has an attacker IP from the Activity Log, Key Vault or storage logs, every flow to or from that IP is evidence. The ports list for mining is a heuristic; services legitimately using those ports will match.

How the analyzer handles volume

A busy subnet writes millions of tuples per day. The Azure Forensics analyzer never keeps them one by one: it aggregates per conversation (source, destination, destination port, protocol, direction, decision) with first and last seen, tuple count and summed packets and bytes. The Entities tab then shows, for each IP, flow totals sent and received — the fastest way to find "the one address that received 40 GB".

Still, be selective when exporting: download only the incident hours and the affected VNets or NSGs. The export guide has the paths.

What flow logs cannot see

  • Direct access to PaaS endpoints from outside. An attacker downloading blobs over the Internet with a SAS never touches your VNet. Use the storage logs.
  • Payloads. Flow logs are metadata only: no URLs, no TLS server names, no content.
  • Traffic at the private endpoint itself. Microsoft notes it can only be captured at the source VM.
  • Unsupported services. Microsoft lists services without flow log support, including App Service, Azure Functions, Logic Apps and Container Instances.
  • Anything before flow logs were enabled, and anything after the storage account's retention deleted it.

A worked example

In the site's fictional sample, a Run Command starts on vm-app-01 at 02:19:40 UTC. The VNet flow log shows the VM (10.10.1.4) opening a connection to the attacker's IP on port 80 at 02:20:05 — 812 bytes sent, 46,338 received, the size of a small script — and on port 443 four seconds later. Neither flow would raise an eyebrow alone; both become high-severity findings because the IP already appears in the Run Command event. The walkthrough shows the full chain.

FAQ

Are NSG flow logs being retired?

Yes. Microsoft states that NSG flow logs retire on September 30, 2027 and that creating new NSG flow logs is no longer supported. Virtual network flow logs are the replacement.

Do flow logs show how much data left a VM?

NSG flow logs version 2 and VNet flow logs carry packets and bytes in each direction on continuation (C) and end (E) tuples. Summing them per conversation gives the volume. Version 1 NSG flow logs have no byte counts.

Can flow logs show downloads from a storage account by an outside attacker?

No. Flow logs record traffic of network interfaces in your virtual networks. An attacker downloading blobs directly from the storage endpoint over the Internet never crosses your VNet; use the storage resource logs for that.

Related articles

Investigate Azure Storage data exfiltration: listAccountSas and listKeys in the Activity Log, GetBlob bursts in blob logs, SAS token hashes, what to rotate.
How attackers abuse Azure service principals and managed identities: leaked secrets, IMDS token theft, federated credentials, runbooks, and the log signals.
Deleted diagnostic settings, removed Activity Log export, Defender plans set to Free, locks and NSG rules: spotting Azure defense evasion, and what survives.

This tool is not affiliated with, endorsed by or sponsored by Microsoft Corporation. Azure, Microsoft Azure and Microsoft Defender for Cloud are trademarks of the Microsoft group of companies. Other names are trademarks of their respective owners.