Network Monitoring with Azure Watcher
Hunt real brute-force attackers using Azure Network Watcher and KQL queries.
Introduction
30 Second Summary
Every minute, automated bots scan the internet looking for open ports to exploit. If you've ever wondered how security teams detect and investigate these attacks in real time, this project gives you that experience firsthand.
In this project, you will deploy an Azure VM with its remote access port deliberately exposed to the internet as a honeypot. You'll then use Azure Network Watcher to capture, analyze, and hunt for the real brute-force attackers that target it within minutes.
What You'll Build
A network monitoring and threat hunting system that detects live brute-force attacks against an exposed VM using Azure-native diagnostics and threat intelligence.
By the end of this project, you'll have:
- A running Azure VM acting as a honeypot with RDP exposed to the internet, monitored by Network Watcher with VNet flow logs capturing all inbound brute-force attempts.
- A working Traffic Analytics dashboard showing malicious IPs, geographic attack origins, and threat classifications from Microsoft threat intelligence feeds.
- Hands-on threat hunting experience using KQL queries in Log Analytics to identify brute-force RDP attackers by IP, country, and volume.
- Secret Mission: Set up Windows Security Event collection and create a precision alert that fires when an attacker successfully signs in via RDP.
Are there any prerequisites?
You'll need an Azure account to complete this project. A free Azure account with $200 credit works perfectly and covers all resources used here.
Set Up Your Azure Environment
Before you can catch attackers in the act, you need a monitoring environment with the right foundation. Your system needs a dedicated container for all its resources and a place to store the network flow data you will collect.
In this step, you will sign into the Azure Portal, confirm your subscription is active, and create the resource group and storage account that support the rest of the project.
In this step, get ready to:
- Sign in to the Azure Portal and confirm your subscription is active.
- Verify Network Watcher is enabled in your region.
- Create a resource group and storage account to hold your monitoring data.
Sign in to the Azure Portal and verify your subscription
Everything in this project lives inside the Azure Portal. You need an active subscription to create resources.
- Open your browser and navigate to portal.azure.com.
- Sign in with your Azure account credentials.
- On the Azure Portal home page, click the menu icon (three horizontal lines) in the top-left corner.
- Select Subscriptions from the left menu.
- Confirm you see at least one subscription with an Active status.
What is a subscription?
A subscription is Azure's billing boundary. All the resources you create belong to a subscription, and that subscription determines who pays for them. Free accounts come with a $200 credit for the first 30 days.
- Now verify that Network Watcher is available. Type Network Watcher in the portal search bar at the top and select Network Watcher from the results.
- Check whether your target region (East US) appears in the list with a status of Enabled.
What is Network Watcher?
Network Watcher is Azure's built-in network monitoring suite. It auto-enables in a region when a virtual network is created or updated in that region. If you do not see it enabled yet for East US, that is fine. It will activate automatically when you create your virtual network in the next step.
Don't see any active subscriptions?
If your subscription shows as Disabled or you do not see one listed, your free trial may have expired. You can upgrade to a pay-as-you-go subscription from the Subscriptions page.
help me figure out why my Azure subscription is not active
Create a resource group
A resource group is a container that holds all the related Azure resources for a project. Placing everything in one group makes cleanup simple at the end.
- In the portal search bar, type Resource groups and select Resource groups from the results.
- Click Create.
- Select your Azure subscription from the Subscription dropdown.
- In the Resource group field, enter rg-network-monitoring.
- Set the Region to East US.
- Click Review + create.
- Click Create.
After a few seconds, you should see a notification confirming the resource group was created. Click Go to resource group in the notification to verify it exists.
Why East US?
East US is a widely available region with full support for Network Watcher, Traffic Analytics, and all the VM sizes used in this project. Keeping all resources in the same region minimizes latency and simplifies networking.
Seeing a permissions error?
You need at least the Contributor or Owner role on your subscription to create resource groups. Ask your account administrator to assign the role if you are on a shared subscription.
help me fix a permissions error when creating an Azure resource group
Create a storage account
The VNet flow logs you enable later need somewhere to land. A storage account provides that destination, holding the raw flow data for analysis.
- In the portal search bar, type Storage accounts and select Storage accounts from the results.
- Click Create.
- On the Basics tab, select your subscription.
- In the Resource group dropdown, select rg-network-monitoring.
- In the Storage account name field, enter a unique name like stnetmonitor followed by 4 random characters (for example, stnetmonitor7k2q). The name must be 3-24 characters, lowercase letters and numbers only.
- Set Region to East US.
- Set Performance to Standard.
- Set Redundancy to Locally-redundant storage (LRS).
- Click Review + create.
- Once validation passes, click Create.
Deployment takes about 30 seconds. When you see the Deployment succeeded message, click Go to resource to confirm the storage account exists.
Why LRS and Standard?
Locally-redundant storage keeps three copies of your data within a single data center. For short-lived monitoring data in a learning project, this gives you the lowest cost without sacrificing durability for your use case. Standard performance uses traditional hard disks, which is more than sufficient for storing flow logs.
Storage account name already taken?
Storage account names must be globally unique across all of Azure. If you see a validation error about the name being taken, try a different combination of random characters at the end of stnetmonitor.
help me pick a unique Azure storage account name
✔️ Awesome, I've got everything!
Great. Make sure you can see both rg-network-monitoring in your Resource groups list and your storage account inside it.
ⓧ I'd like to double check what I should have
At this point you should have the following resources in the Azure Portal:
- A resource group named rg-network-monitoring in the East US region.
- A storage account (named something like stnetmonitorXXXX) inside that resource group, set to general-purpose v2, Standard performance, and Locally-redundant storage (LRS).
To verify, navigate to Resource groups in the portal, open rg-network-monitoring, and confirm your storage account is listed inside it.
Your environment is ready. Next up, you will deploy a virtual machine with its RDP port deliberately exposed to the internet, turning it into a honeypot that attracts real attackers.
Deploy a Honeypot VM with RDP Exposed
Your resource group and storage account are ready. Now it's time to deploy the actual target that attackers will probe.
In this step, you'll create a virtual network, deploy a Windows Server VM with RDP (port 3389) deliberately exposed to the internet, and register a required resource provider. The open RDP port acts as a honeypot, attracting real brute-force bots that Network Watcher will monitor in later steps.
In this step, get ready to:
- Create a Virtual Network to establish your monitoring boundary.
- Deploy a Windows Server VM with RDP exposed to the internet.
- Register the Microsoft.Insights resource provider and verify your VM's public IP.
Create a Virtual Network
A Virtual Network (VNet) is a private network inside Azure that your resources communicate through. Network Watcher monitors traffic at the VNet level, so you need one in place before deploying the VM.
- In the Azure Portal search bar at the top, type Virtual network and select Virtual networks from the results.
- Click + Create.
- On the Basics tab, select your subscription.
- For Resource group, select rg-network-monitoring from the dropdown.
- For Name, enter myVNet.
- For Region, select East US.
- Click Next to proceed to the Security tab.
- Click Next again to proceed to the IP Addresses tab.
- In the address space box, confirm the address space is set to 10.0.0.0/16. If a different value is shown, update it.
- Under Subnets, click on the default subnet to edit it.
- Confirm the subnet name is default, the starting address is 10.0.0.0, and the subnet size is /24 (256 addresses).
- Click Save.
- Click Review + create at the bottom of the page.
- Once validation passes, click Create.
What is a Virtual Network?
A VNet is the fundamental building block for private networks in Azure. It lets your resources (like VMs) communicate securely with each other, the internet, and on-premises networks.
Network Watcher monitors traffic at the VNet level using VNet flow logs. Creating the VNet first gives you a clear network boundary to monitor when you enable flow logs in a later step.
Wait for the deployment to complete. You should see a Your deployment is complete message.
Deployment failed?
Make sure the VNet name myVNet is unique in your resource group. Also confirm you selected East US as the region. The VNet must be in the same region as the rest of your resources.
Help me troubleshoot
Create the Virtual Machine with a public IP
This VM acts as your honeypot. You will deliberately leave RDP open so that internet-facing brute-force bots can find and probe it. You do NOT need to connect to this VM yourself.
- In the Azure Portal search bar, type Virtual machines and select Virtual machines from the results.
- Click + Create and select Azure virtual machine from the dropdown.
- On the Basics tab, select your subscription.
- For Resource group, select rg-network-monitoring.
- For Virtual machine name, enter myVM.
- For Region, select East US.
- For Image, select a Windows Server image (such as Windows Server 2022 Datacenter).
- For Size, click See all sizes and search for Standard_B1s. Select it and click Select.
- Under Administrator account, enter a username (for example, azureuser).
- Enter a strong, unique password that is at least 16 characters long, mixing uppercase, lowercase, numbers, and symbols.
- Under Inbound port rules, set Public inbound ports to Allow selected ports.
- In the Select inbound ports dropdown, select RDP (3389).
Use a strong password
Real attackers WILL attempt to brute-force this password within minutes of the VM going live. Use at least 16 characters with a mix of uppercase, lowercase, numbers, and symbols. Write it down somewhere safe. Do NOT use a simple or commonly-used password.
- Click the Networking tab at the top of the page.
- For Virtual network, select myVNet (the VNet you just created).
- For Subnet, confirm default (10.0.0.0/24) is selected.
- For Public IP, confirm a new public IP will be created. Leave the default settings.
- Click Review + create.
- Once validation passes, click Create.
What is a Network Security Group?
When you allow RDP (port 3389) during VM creation, Azure automatically creates a Network Security Group (NSG) with an inbound rule permitting TCP traffic on port 3389 from any source. This is what exposes your VM to the internet.
In production, you would restrict this to specific IP addresses. For this project, you intentionally leave it open to attract attackers for monitoring purposes.
The deployment takes a few minutes. Wait until you see the Your deployment is complete message before continuing.
VM deployment failed?
The most common cause is that the Standard_B1s size is not available in your selected region. Try selecting a different Windows Server image or check that your subscription has not exceeded its vCPU quota for the East US region.
Also confirm your password meets Azure's complexity requirements: at least 12 characters with uppercase, lowercase, numbers, and a special character.
Help me troubleshoot my VM deployment
Register the Microsoft.Insights resource provider and verify RDP exposure
Flow logging requires the Microsoft.Insights resource provider to be registered on your subscription. Without it, you won't be able to create VNet flow logs in the next step.
- In the Azure Portal search bar, type Subscriptions and select Subscriptions.
- Click on your subscription name.
- In the left menu, scroll down to Settings and click Resource providers.
- In the search box, type Microsoft.Insights.
- If the status shows NotRegistered, select Microsoft.Insights and click Register at the top.
- Wait for the status to change to Registered. This may take a minute. You can click Refresh to check.
Why register Microsoft.Insights?
Azure resource providers control which services your subscription can use. The Microsoft.Insights provider enables monitoring and diagnostics features, including the flow logging that Network Watcher needs to capture traffic data.
Now verify that your VM has a public IP and RDP is exposed to the internet.
- In the Azure Portal search bar, type Virtual machines and select Virtual machines.
- Click on myVM.
- On the Overview page, look for the Public IP address field. You should see an IP address displayed (something like 20.x.x.x).
Why don't I need to connect via RDP?
The goal of this project is NOT to use the VM yourself. You only need the VM to be running with RDP open so that internet-facing bots discover and probe port 3389. Network Watcher will capture all of those inbound connection attempts for analysis.
Within 5 to 15 minutes of this VM being live, brute-force bots will typically discover and start probing it.
Don't see a public IP address?
Go back to myVM and check the Networking section. Confirm that a public IP resource is associated with the VM's network interface. If no public IP was created during deployment, you can create and attach one from the VM's Networking settings.
Help me fix my missing public IP
Your honeypot is live. With RDP exposed to the internet, brute-force bots will start discovering your VM within minutes. Next up, you'll enable VNet flow logs and Traffic Analytics to capture and visualize all of that attack traffic.
Enable VNet Flow Logs and Traffic Analytics
Your honeypot VM is live and RDP is exposed to the internet. Attackers will start probing port 3389 within minutes.
The problem is that right now, you have zero visibility into who is connecting. You need a way to log every single inbound connection attempt and surface the malicious ones. That is exactly what VNet flow logs and Traffic Analytics do.
In this step, get ready to:
- Create a VNet flow log that captures all inbound traffic to your virtual network.
- Enable Traffic Analytics with accelerated processing to detect threats quickly.
- Let real-world attackers discover your exposed VM while you move to diagnostic tools.
Create the flow log
VNet flow logs record metadata about every network flow entering or leaving your virtual network. They capture source IPs, destination ports, protocols, and whether traffic was allowed or denied.
- In the Azure Portal search bar, type Network Watcher and select it from the results.
- In the left menu under Monitoring, click Flow logs.
- Click + Create at the top of the Flow logs page.
Why VNet flow logs instead of NSG flow logs?
NSG flow logs are being retired on September 30, 2027. After June 30, 2025, you can no longer create new NSG flow logs. Microsoft recommends migrating to VNet flow logs, which operate at the virtual network level and cover all workloads within the VNet.
- On the Basics tab, select your subscription.
- For the target resource type, select Virtual network.
- Select myVNet as the target resource.
- Under Instance details, select the storage account you created earlier (stnetmonitorXXXX).
- Set the Retention (days) field to 10.
What does retention control?
The retention setting determines how many days of flow log data is kept in your storage account before automatic deletion. Ten days gives you plenty of time to analyze attack patterns without accumulating unnecessary storage costs.
Enable Traffic Analytics on the flow log
Traffic Analytics enriches raw flow log data with threat intelligence from Microsoft security feeds. It classifies known-bad IPs, maps geographic origins, and surfaces attack patterns you would otherwise miss in raw logs.
- On the same Create flow log page, click the Analytics tab.
- Check the Enable Traffic Analytics box.
- For the Traffic Analytics processing interval, select Every 10 mins.
Why choose the 10-minute interval?
Traffic Analytics offers two processing intervals. The standard 60-minute interval costs $2.30 per GB processed. The accelerated 10-minute interval costs $3.50 per GB processed but gives you threat visibility six times faster.
For a short observation window like this project, total data processed will be well under 1 GB. The small cost difference is worth the faster feedback.
- Under Log Analytics Workspace, click Create New.
- Enter law-network-monitoring as the workspace name.
- Select the rg-network-monitoring resource group.
- Select East US as the region.
- Click OK to create the workspace.
What is a Log Analytics Workspace?
A Log Analytics Workspace is Azure's central repository for log data. Traffic Analytics sends its processed flow data here, and you will query it later using KQL to hunt for brute-force attackers.
- Click Review + create at the bottom of the page.
- Review your settings, then click Create.
You should see a notification confirming that the flow log was created successfully. The flow log is now active and recording all traffic in myVNet.
Flow log creation failed?
If you see an error about the Microsoft.Insights provider, go back to your subscription's Resource providers page and confirm that Microsoft.Insights shows a status of Registered. Registration can take a minute to propagate.
If the storage account is not selectable, confirm it is in the same region (East US) as your virtual network. Flow logs require the storage account to be in the same region as the target resource.
Help me troubleshoot my VNet flow log creation error in Azure Network Watcher
Wait for attack traffic to accumulate
With RDP exposed to the internet, brute-force bots will typically discover your VM within 5-15 minutes. Automated scanners constantly sweep the internet for open ports like 3389.
Traffic Analytics will begin processing and displaying data after 10-30 minutes with accelerated processing enabled. You do not need to wait here.
- Proceed to Step 4 to use Network Watcher's diagnostic tools while traffic accumulates in the background.
- You will return to Traffic Analytics in Step 5 once enough data has been processed.
Use the wait time productively
The diagnostic tools in Step 4 work immediately without waiting for flow log data. IP Flow Verify and Packet Capture operate in real-time, so you can confirm your honeypot's exposure and catch live attack packets while Traffic Analytics builds its threat picture.
Your flow logs are recording and Traffic Analytics is processing. Next up, you will use Network Watcher's diagnostic tools to verify your exposure and capture live attack packets.
Diagnose Inbound Attacks with Network Watcher Tools
In the previous step, you enabled VNet flow logs and Traffic Analytics to start collecting data about who is connecting to your VM.
While Traffic Analytics processes that data in the background, you can use Network Watcher's diagnostic tools to actively probe your VM's security posture right now. These tools let you confirm exactly which traffic your security rules allow, capture live attack packets, and verify how traffic flows through your network.
In this step, get ready to:
- Use IP Flow Verify to confirm inbound RDP traffic is allowed by your NSG.
- Run a Packet Capture to record live attack traffic hitting port 3389.
- Use Connection Troubleshoot to verify your VM's outbound connectivity and NSG rule evaluation.
Use IP Flow Verify to test RDP access
IP Flow Verify checks whether a specific packet would be allowed or denied by the NSG rules protecting your VM. You will simulate an inbound RDP connection to confirm your honeypot is truly open to attackers.
- In the Azure Portal search bar, type Network Watcher and select it from the results.
- In the left menu, expand **Network diagnostic tools** and select **IP flow verify**.
- Select your subscription from the dropdown.
- For **Resource group**, select rg-network-monitoring.
- For **Virtual machine**, select myVM.
- Set **Direction** to Inbound.
- Set **Protocol** to TCP.
- Enter 3389 in the **Local port** field.
- Enter 10.10.10.10 in the **Remote IP address** field.
- Enter 60000 in the **Remote port** field.
- Click **Check**.
The result should display Access allowed along with the name of the NSG rule permitting the traffic.
What does this result mean?
IP Flow Verify evaluated your NSG rules against a simulated inbound TCP packet on port 3389. The result confirms that your honeypot VM is genuinely open to RDP connections from any source IP.
This is exactly why attackers can reach your VM. In a real production environment, seeing "Access allowed" on RDP from the internet would be a critical finding requiring immediate remediation.
Seeing Access denied?
If the result says "Access denied", your NSG may not have the inbound RDP rule. Navigate to your VM's **Networking** settings and confirm there is a rule allowing inbound TCP on port 3389 from any source.
help me troubleshoot why IP Flow Verify shows Access denied for RDP on my Azure VM
Run a Packet Capture targeting RDP traffic
Packet Capture records the raw network packets hitting your VM in real time. By filtering to port 3389, you will capture only the RDP brute-force attempts from attackers.
- In Network Watcher's left menu, select **Packet capture** under **Network diagnostic tools**.
- Click **+ Add** to create a new packet capture.
- For **Target virtual machine**, select myVM.
- Enter a name for the capture (for example, rdp-capture).
- Set the **Time limit (seconds)** to 120.
- Under the filter section, click **Add filter**.
- Set **Protocol** to TCP.
- Set **Local port** to 3389.
- Click **Start packet capture**.
What happens when you start the capture?
Azure installs the Network Watcher agent extension (AzureNetworkWatcherExtension) on your VM if it is not already present. The capture then records all TCP packets arriving on port 3389 for 120 seconds.
Since brute-force bots are already probing your VM, the capture will contain real SYN packets from attacker IPs attempting to establish RDP connections.
Wait for the capture to complete (about 2 minutes). The status will change from Running to Completed.
- Once the status shows **Completed**, click the capture name to open its details.
- In the **Details** section, click the packet capture file link to navigate to the storage blob.
- Click **Download** to save the .cap file to your computer.
If you open the .cap file in a tool like Wireshark, you will see SYN packets from multiple IPs attempting to connect to port 3389. Each SYN packet represents a brute-force connection attempt from a different attacker.
Capture stuck or showing no packets?
If the capture stays in a "Running" state past 2 minutes, wait a bit longer. It will automatically stop at the 120-second time limit.
If the downloaded file is empty, confirm your VM's public IP is still assigned and that the NSG rule allowing port 3389 inbound is still active. Bots may not have discovered your VM yet if it was just deployed.
help me troubleshoot why my Azure Network Watcher packet capture shows no traffic
Use Connection Troubleshoot to verify your exposure
Connection Troubleshoot tests whether your VM can reach a destination and shows the full NSG rule evaluation path along the way. This helps you understand how traffic flows through your security rules in both directions.
- In Network Watcher's left menu, select **Connection troubleshoot** under **Network diagnostic tools**.
- For **Source type**, select Virtual machine.
- For **Virtual machine**, select myVM.
- For **Destination type**, select Specify manually.
- Enter 8.8.8.8 as the destination IP address.
- Enter 443 as the destination port.
- Click **Check**.
The result should show the connection status as Reachable, confirming your VM has outbound internet connectivity.
What does Connection Troubleshoot show you?
Beyond confirming connectivity, Connection Troubleshoot displays the NSG rules evaluated at each hop. This gives you visibility into the full rule evaluation path that traffic takes when leaving your VM.
In a real investigation, this helps you confirm that a compromised VM could exfiltrate data outbound, or that your outbound NSG rules are properly restricting egress traffic.
Connection showing as unreachable?
Verify that your VM is still running by checking its status on the VM overview page. A deallocated VM cannot send outbound traffic.
Also confirm that your NSG does not have a rule blocking outbound traffic on port 443. The default Azure NSG rules allow all outbound internet traffic.
help me troubleshoot why Connection Troubleshoot shows unreachable from my Azure VM
You have now used three Network Watcher diagnostic tools to actively probe your honeypot's security posture. IP Flow Verify confirmed attackers can reach port 3389, Packet Capture recorded their live connection attempts, and Connection Troubleshoot verified the full NSG evaluation path.
Next up, you will dive into Traffic Analytics and Log Analytics to hunt for the brute-force attackers using KQL queries.
Hunt for Brute-Force Attackers in Traffic Analytics
In the previous step you used diagnostic tools to confirm your honeypot is exposed and capturing traffic. Now it is time to analyze that traffic at scale.
Traffic Analytics aggregates your VNet flow log data into a Log Analytics workspace, enriches it with Microsoft threat intelligence, and surfaces malicious IPs automatically. In this step, you will explore the dashboard for flagged threats, then write KQL queries to identify the top brute-force attackers targeting your VM.
In this step, get ready to:
- Explore the Traffic Analytics dashboard and identify malicious IPs with threat classifications.
- Run a KQL query to surface the top 20 source IPs attacking port 3389.
- Enrich attacker IPs with threat intelligence data including location, threat type, and DNS domain.
Explore the Traffic Analytics dashboard for threats
Traffic Analytics processes your flow logs at the 10-minute accelerated interval you configured. After 10-30 minutes of data collection, the dashboard shows inbound traffic patterns, geographic origins, and any IPs that Microsoft threat intelligence has flagged as malicious.
- In the Azure Portal search bar, type Network Watcher and select it.
- In the left menu under Monitoring, click Traffic analytics.
- Wait for data to appear. If you see a message that data is not yet available, wait a few more minutes and refresh the page.
- Once data loads, look for the Malicious IPs section on the dashboard.
- Examine any entries flagged as MaliciousFlow. These are public IPs that Microsoft threat intelligence has classified as malicious.
- Review the geographic flow map to see where attacks originate. Malicious traffic is highlighted in red.
What is a MaliciousFlow?
Traffic Analytics classifies a flow as MaliciousFlow when one IP belongs to your Azure VNet and the other is a public IP reported as malicious in the security feeds that Traffic Analytics consumes.
Each malicious IP includes a ThreatType (such as Botnet, C2, Phishing, or DDoS), a ThreatDescription, and the geographic location. This enrichment comes from Microsoft internal threat intelligence systems including the Digital Crimes Unit and the Microsoft Security Response Center.
Data not showing up yet?
Traffic Analytics with 10-minute accelerated processing typically takes 10-30 minutes to begin showing results. If you configured it recently, give it time. You can proceed to the KQL queries in the next substep. Those queries will also show results once data has been processed.
You should see inbound traffic entries with threat types like Botnet or brute-force indicators. Note the countries and IP addresses appearing in the dashboard.
Hunt for RDP brute-force patterns in Log Analytics
The Traffic Analytics dashboard gives you a visual overview, but for precise threat hunting you need KQL queries. These let you filter, aggregate, and rank attacker data with surgical precision.
- Navigate to your Log Analytics workspace law-network-monitoring by searching for it in the Azure Portal search bar.
- Click Logs in the left menu to open the query editor.
- If a Queries dialog appears, close it to get to the blank query editor.
- Make sure you are in KQL mode (check the toggle in the top action bar).
- Identify the top 20 source IPs hitting your RDP port by pasting the following query into the editor:
NTANetAnalytics
| where TimeGenerated > ago(1h)
| where DestPort == 3389
| where FlowDirection == "I"
| summarize FlowCount = count(), TotalPackets = sum(PacketsSrcToDest) by SrcIp
| order by FlowCount desc
| take 20
- Click the Run button (or press Shift+Enter) to execute the query.
What does this query do?
- NTANetAnalytics is the table containing aggregated flow log data with enhanced network analytics from your VNet flow logs.
- where DestPort == 3389 filters to only RDP traffic targeting your VM.
- where FlowDirection == "I" limits results to inbound flows (traffic coming toward your VM from the internet).
- summarize groups the results by source IP and counts the number of flows and total packets from each attacker.
- take 20 returns only the top 20 most aggressive attackers, ranked by flow count.
You should see a table of IP addresses with their flow counts and packet totals. The top entries are the IPs most aggressively probing your RDP port.
Query returns no results?
- Traffic Analytics needs 10-30 minutes after enabling to process and publish data to the NTANetAnalytics table. If you enabled it recently, wait and try again.
- Try expanding the time range by changing ago(1h) to ago(3h) in case your flow data was processed more than an hour ago.
- Confirm that your VNet flow log shows a status of Succeeded under Network Watcher > Flow logs.
Still not seeing data?
Investigate malicious IPs and their origins
Now that you know which IPs are attacking, you can enrich them with threat intelligence. The NTAIpDetails table contains Microsoft's threat classifications for each malicious IP, including geographic location, DNS domains, and threat types.
- Clear the query editor and paste the following query to surface threat intelligence for flagged IPs:
NTAIpDetails
| where TimeGenerated > ago(1h)
| where FlowType == "MaliciousFlow"
| distinct IP, PublicIPDetails, Location, ThreatType, ThreatDescription, DNSDomain
- Click Run to execute the query.
What does this query do?
- NTAIpDetails contains IP-specific enrichment data published by Traffic Analytics.
- where FlowType == "MaliciousFlow" filters to only IPs classified as malicious by Microsoft threat intelligence.
- distinct removes duplicate rows so you see each unique malicious IP once with its details.
- The output columns show the IP address, WHOIS information (PublicIPDetails), 2-letter country code (Location), the threat classification (ThreatType), a description of the threat (ThreatDescription), and the DNS domain associated with the IP (DNSDomain).
You should see results showing IPs with threat types like Botnet, C2, or other classifications. The Location column shows the country of origin as a 2-letter ISO code.
Why might some IPs appear malicious but their traffic was allowed?
Your NSG currently allows all inbound RDP traffic. This means malicious IPs can reach port 3389 on your VM even though they are flagged by threat intelligence. The MaliciousFlow classification is an intelligence label, not a block action. In a production environment, you would use this intelligence to create deny rules in your NSG.
Seeing fewer malicious IPs than expected?
- Not all attacking IPs are in Microsoft's threat intelligence feeds. Only IPs reported as malicious in the security feeds get the MaliciousFlow label. Others appear as ExternalPublic even if they are probing your port.
- Try expanding the time range to ago(3h) to capture more processed intervals.
Help me understand why some attacking IPs are not flagged as MaliciousFlow.
- Take note of the top attacking IPs, their countries of origin, and their threat types. You will reference these findings in the next step.
You have now performed real threat hunting against live attacks. In the next step, you will lock down the RDP port and review the full attack timeline to document your findings.
Lock Down and Review Findings
You have identified the attackers targeting your VM using KQL queries and Traffic Analytics threat intelligence. Now it is time to shut the door on new attacks and document what you found.
In this step, you will close the exposed RDP port to stop new attack traffic, then run a time-based query to visualize how quickly bots escalated their brute-force attempts. Finally, you will summarize your threat hunting findings as you would in a real SOC incident report.
In this step, get ready to:
- Close the RDP port on your VM's Network Security Group.
- Run a time-based KQL query to visualize the attack ramp-up.
- Summarize your threat hunting findings as a SOC incident report.
Close the RDP port
Your honeypot has been collecting attack data. Leaving RDP exposed any longer than necessary is a security risk, even with a strong password. Closing the port stops new attack traffic immediately while preserving all existing flow log data for analysis.
- In the Azure Portal search bar, type Virtual machines and select Virtual machines from the results.
- Select myVM.
- In the left menu, expand Networking and select Network settings.
- Under Inbound port rules, find the rule that allows TCP port 3389 (RDP) from any source.
- Click on the rule to open it.
- Change the Action from Allow to Deny.
- Click Save.
Why Deny instead of Delete?
Both options work. Changing the action to Deny keeps the rule visible as documentation that port 3389 was previously open. Deleting the rule entirely also closes the port, because the default DenyAllInBound rule (priority 65500) blocks all inbound traffic that is not explicitly allowed.
Either approach stops new attack traffic immediately. Choose whichever you prefer.
After saving, you should see the rule's action now shows Deny in the inbound port rules list.
Rule still shows Allow?
NSG rule changes can take up to 30 seconds to apply. Refresh the page and verify the Action column shows Deny. If you cannot edit the rule, make sure you have the Network Contributor role or equivalent permissions on the subscription.
Help me troubleshoot why my NSG rule change is not saving.
Review the full attack timeline
Your flow log data captures the entire history of inbound connection attempts, even after you closed the port. A time-based query lets you see exactly how quickly bots discovered and escalated their brute-force attacks.
- Return to your Log Analytics Workspace (law-network-monitoring) by searching for it in the portal search bar.
- Select Logs in the left menu.
- Clear any existing query, then paste the following KQL query to visualize the attack ramp-up:
NTANetAnalytics
| where DestPort == 3389
| where FlowDirection == "I"
| summarize AttemptCount = count() by bin(TimeGenerated, 5m)
| order by TimeGenerated asc
| render timechart
- Click Run.
What does this query do?
- It filters the NTANetAnalytics table to only inbound flows targeting port 3389.
- It groups the results into 5-minute time bins using bin(TimeGenerated, 5m), counting connection attempts in each window.
- The render timechart operator produces a visual line chart showing how attack volume changed over time.
You should see a timechart showing the attack volume rising over time. Typically, you will see a low initial volume that ramps up as more bots discover your exposed port.
Timechart is empty or shows no results?
Traffic Analytics data takes 10-30 minutes to process with accelerated (10-minute) intervals. If you just enabled flow logs recently, wait a bit longer and re-run the query. Make sure you are querying the correct workspace (law-network-monitoring).
Help me figure out why my NTANetAnalytics timechart query returns no results.
Summarize your threat hunting findings
In a real Security Operations Center (SOC), analysts document their findings after an investigation. You now have all the data needed to write a summary of the brute-force attack activity against your honeypot.
- Review the KQL query results you ran in the previous step (Step 5) and in the timechart above.
- Answer the following questions based on your collected data:
- How many unique source IPs targeted your RDP port (port 3389)?
- Which countries generated the most attack traffic?
- Were any IPs flagged as MaliciousFlow by Microsoft threat intelligence?
- What threat types were identified (e.g., Botnet, C2, Phishing)?
- How quickly did attack volume ramp up based on your timechart?
What would a real SOC report include?
A SOC incident report typically includes: the detection method, a timeline of events, affected assets, source attribution (IPs, countries, threat classifications), impact assessment, and remediation actions taken.
Your findings demonstrate exactly this workflow. You detected threats via flow logs and Traffic Analytics, investigated them with KQL, and remediated by closing the port.
Run one more query for unique IP count
If you want an exact count of unique attacking IPs, run this quick query in Log Analytics:
NTANetAnalytics
| where DestPort == 3389
| where FlowDirection == "I"
| summarize UniqueAttackers = dcount(SrcIp)
The dcount(SrcIp) function returns the distinct count of source IPs that attempted connections to your RDP port.
Secret mission
Detect a Successful Non-System RDP Sign-In
Set up Windows Security Event collection on your VM and create an alert that fires only when a successful RDP logon occurs from a non-system account. This is the one alert that truly matters: it means an attacker cracked the password and got in.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Most resources in this project are covered by Azure free tier allowances, but Traffic Analytics processing and the VM (if you exceed 750 free hours) can incur small charges.
Cost warning
Your VM (Standard_B1s) is free for 750 hours per month on the Azure free account. However, Traffic Analytics charges $3.50 per GB processed at the accelerated 10-minute interval. With a short exposure window, expect less than $1 total.
If you are done with the project, deleting the resource group is recommended to guarantee zero ongoing costs and eliminate the exposed VM.
Resources you used:
- Azure VM (myVM) with public IP address.
- Virtual Network (myVNet).
- Storage Account (stnetmonitorXXXX) storing VNet flow log data.
- Log Analytics Workspace (law-network-monitoring) with Traffic Analytics data and Security Events.
- VNet Flow Logs on myVNet.
- Data Collection Rule (dcr-security-events) with Azure Monitor Agent on the VM.
- Alert Rule (Successful RDP Logon - Non-System Account).
- Resource Group (rg-network-monitoring) containing all of the above.
Keep everything running
No action needed. Choose this if you have closed port 3389 and want to continue exploring your flow log data or running additional KQL queries.
- Your RDP port is already closed from Step 6, so attackers can no longer reach port 3389.
- The B1s VM is free for 750 hours per month on the Azure free account. That covers running the VM continuously for a full month.
- VNet flow logs include 5 GB per month free. Log Analytics includes 5 GB per month of ingestion free.
- Traffic Analytics continues processing at $3.50 per GB if left enabled. To stop processing costs, disable Traffic Analytics on the flow log without deleting your stored data.
Pause - I'll come back to this later
Shut down the VM to stop compute charges while keeping your flow log data and Log Analytics workspace intact for future analysis.
- Navigate to Virtual machines in the Azure Portal.
- Select myVM and click Stop to deallocate the VM.
- Confirm the deallocation. This stops compute charges immediately.
- Flow logs will stop collecting new data since there is no traffic to the deallocated VM.
- Your Log Analytics workspace retains all previously collected data for future queries.
- To disable Traffic Analytics processing costs, navigate to Network Watcher > Flow logs, select your flow log, and uncheck Enable Traffic Analytics.
Delete - I don't want to use this again
Remove all project resources in one action by deleting the resource group. This guarantees zero ongoing costs.
- In the Azure Portal search bar, type Resource groups and select it.
- Click on rg-network-monitoring.
- Click Delete resource group at the top of the page.
- Type rg-network-monitoring in the confirmation field to confirm deletion.
- Click Delete.
- This removes the VM, VNet, storage account, Log Analytics workspace, flow logs, Data Collection Rule, alert rule, and all associated resources.
Why delete the whole resource group?
Deleting the resource group is the cleanest way to ensure nothing is left behind. All resources created in this project live inside rg-network-monitoring, so a single deletion removes everything and stops all charges.
Nice Work!
Nice Work!
Congratulations! You have built a network monitoring system and performed real threat hunting against live brute-force attacks targeting your Azure VM.
You've learned how to:
- Deployed an Azure VM as a honeypot with RDP exposed to the internet, then captured real attack traffic using VNet flow logs and Packet Capture.
- Set up Traffic Analytics with accelerated processing to detect and classify malicious IPs using Microsoft threat intelligence feeds.
- Hunted for brute-force attackers using KQL queries in Log Analytics, identifying top attacking IPs, geographic origins, threat types, and visualizing the full attack timeline.
- Set up Windows Security Event collection via a Data Collection Rule and built a precision alert that fires only when an attacker successfully signs in via RDP.
Ready to quiz yourself?