This project demonstrates the design and deployment of a cloud-based honeynet in Microsoft Azure, integrated with Microsoft Sentinel for real-time attack detection, threat intelligence enrichment, and global telemetry visualization.
A publicly exposed Windows VM was intentionally configured with weakened firewall and network security controls to attract real adversary activity from the internet. Logs were collected using the Azure Monitoring Agent and correlated within Sentinel for threat hunting, mapping attacker geolocation, and building security analytics.
Published on November 20, 2025 by Ewan Oleghe.
This hands-on security project focuses on building a realistic Security Operations Center (SOC) home lab using Azure services.
The goal was to:
The lab simulates real-world SOC workflows such as threat detection, log analysis, alerting, correlation, and visualization, allowing practical blue-team experience with Azure-native tools.
The local container that groups everything related to one project (e.g., VM, VNet, NIC, Public IP).

The VNets a private, customizable network allows us to connect and secures resources. Our Virtual Machine will be placed inside the Virtual Network
In Microsoft Azure, a VM is a cloud-hosted computer - This is what will be exposed to the Internet/attackers.

The NSG acts as a virtual firewall to control inbound and outbound traffic to the VM. We will create rules to allow specific traffic to the honeypot VM.





From your local machine. Use CMD or PowerShell to ping the VM. We have to make sure its accessible on the internet.
ping -n 6 20.64.238.22
Pings the VM and a total of 6 packets sent and received

By default the VM keeps all the Security Events in 'Event Viewer' - Windows Logs - Security.

Each ID corresponds to a security events and an ID search can be used to filter logs (e.g. For failed logs search (Ctrl + F or 'Filter current log..') for '4625')
Configure a Log Repository
To collect and analyze these logs in Microsoft Sentinel, we need to set up a Log Analytics Workspace and enable Microsoft Sentinel (SIEM).
Create Microsoft Sentinel Instance
Configure the Connection between VM and Log Analytics

Manage Windows Security Events via Azure Monitoring Agent (AMA)



// Failed RDP Log-in Attempts (Event ID: 4625)
SecurityEvent
| where EventID == 4625
| summarize Count = count() by Account, IpAddress, bin(TimeGenerated, 1h)
| order by Count desc
// All RDP Log-in Attempts (Successful and Failed)
SecurityEvent
| where EventID in (4624, 4625)
// Targeted Specific Account e.g. "administrator "
SecurityEvent
| where Account == "\\administrator"
// Top Targeted Accounts by Failed Log-ins
SecurityEvent
| where EventID == 4625
| summarize FailedAttempts = count() by Account
| order by FailedAttempts desc
// Successful RDP Log-in Attempts (Event ID: 4624)
SecurityEvent
| where EventID == 4624
| summarize Count = count() by Account, IpAddress, bin(TimeGenerated, 1h)
| order by Count desc
// Top Source IPs by Failed Log-ins
SecurityEvent
| where EventID == 4625
| summarize FailedAttempts = count() by IpAddress
| order by FailedAttempts desc
| take 10
// Brute-force Attack Patterns
SecurityEvent
| where EventID == 4625
| summarize Attempts = count() by IpAddress, bin(TimeGenerated, 10m)
| where Attempts > 5
| order by Attempts desc
// Geo-location of Attackers
SecurityEvent
| where EventID == 4625
| extend GeoInfo = iplocation(IpAddress)
| summarize Count = count() by GeoInfo.CountryOrRegion
| order by Count desc
Geo-location of Attackers
Download: geoip-summarized.csv
_GetWatchlist("geoip")
See where the attacks are coming from
let GeoIPDB_FULL = _GetWatchlist("geoip");
let WindowsEvents = SecurityEvent
| where IpAddress == <attacker IP address> // Replace Ip address "147.91.111.100"
| where EventID == 4625
| order by TimeGenerated desc
| evaluate ipv4_lookup(GeoIPDB_FULL, IpAddress, network);
WindowsEvents
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "let GeoIPDB_FULL = _GetWatchlist(\"geoip\");\nlet WindowsEvents = SecurityEvent;\nWindowsEvents | where EventID == 4625\n| order by TimeGenerated desc\n| evaluate ipv4_lookup(GeoIPDB_FULL, IpAddress, network)\n| summarize FailureCount = count() by IpAddress, latitude, longitude, cityname, countryname\n| project FailureCount, AttackerIp = IpAddress, latitude, longitude, city = cityname, country = countryname,\nfriendly_location = strcat(cityname, \" (\", countryname, \")\");",
"size": 3,
"timeContext": {
"durationMs": 2592000000
},
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
"visualization": "map",
"mapSettings": {
"locInfo": "LatLong",
"locInfoColumn": "countryname",
"latitude": "latitude",
"longitude": "longitude",
"sizeSettings": "FailureCount",
"sizeAggregation": "Sum",
"opacity": 0.8,
"labelSettings": "friendly_location",
"legendMetric": "FailureCount",
"legendAggregation": "Sum",
"itemColorSettings": {
"nodeColorField": "FailureCount",
"colorAggregation": "Sum",
"type": "heatmap",
"heatmapPalette": "greenRed"
}
}
},
"name": "query - 0"
}
Paste the json code inside the query window
Save the Map generated
