Detect SNMP (MIB Dump) in Microsoft Sentinel
Adversaries may target the Management Information Base (MIB) to collect and mine valuable information from networks managed via Simple Network Management Protocol (SNMP). The MIB stores configuration variables accessible via object identifiers (OIDs), including system descriptions, hardware inventories, running configurations, routing tables, ARP caches, and interface details. Adversaries exploit SNMPv1/v2c's weak community-string authentication—using default strings such as 'public' and 'private'—to conduct bulk MIB walks against routers, switches, firewalls, and other managed devices, building detailed network maps that facilitate subsequent targeted exploitation. This technique was prominently documented in US-CERT alert TA18-106A describing APT actors targeting legacy Cisco infrastructure via SNMP to extract device configurations and network topology prior to destructive operations.
MITRE ATT&CK
- Tactic
- Collection
- Technique
- T1602 Data from Configuration Repository
- Sub-technique
- T1602.001 SNMP (MIB Dump)
- Canonical reference
- https://attack.mitre.org/techniques/T1602/001/
KQL Detection Query
let TimeWindow = 24h;
let SNMPTools = dynamic(["snmpwalk.exe", "snmpget.exe", "snmpbulkwalk.exe", "snmptable.exe", "snmpset.exe", "snmpgetnext.exe", "snmpdf.exe", "snmpnetstat.exe"]);
let WeakCommunities = dynamic(["-c public", "-c private", "-c cisco", "-c monitor", "-c manager", "-c secret", "-c admin", "community public", "community private"]);
// Detection Path 1: SNMP enumeration tools executed on Windows/Linux endpoints
let EndpointSNMPTools = DeviceProcessEvents
| where Timestamp > ago(TimeWindow)
| where FileName in~ (SNMPTools)
or (ProcessCommandLine has "snmp"
and (ProcessCommandLine has ".1.3.6"
or ProcessCommandLine has_any (WeakCommunities)
or ProcessCommandLine has "-v1"
or ProcessCommandLine has "-v2c"
or ProcessCommandLine has "-OXsq"))
| extend AlertType = "SNMP_Tool_Execution"
| extend UsingDefaultCommunity = ProcessCommandLine has_any (WeakCommunities)
| extend MIBWalkDetected = ProcessCommandLine has ".1.3.6"
| extend BulkWalk = FileName has_any ("snmpbulk", "snmpwalk")
| extend RiskScore = case(
UsingDefaultCommunity and MIBWalkDetected, 95,
UsingDefaultCommunity, 85,
MIBWalkDetected, 75,
70)
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine,
AlertType, UsingDefaultCommunity, MIBWalkDetected, BulkWalk, RiskScore;
// Detection Path 2: High-volume outbound SNMP UDP/161 traffic indicating automated MIB walk
let SNMPTrafficBurst = DeviceNetworkEvents
| where Timestamp > ago(TimeWindow)
| where RemotePort == 161
| summarize
SNMPRequests = count(),
UniqueTargets = dcount(RemoteIP),
TargetIPs = make_set(RemoteIP, 25),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine,
AccountName = InitiatingProcessAccountName,
bin(Timestamp, 10m)
| where SNMPRequests > 20 or UniqueTargets > 3
| extend AlertType = "High_Volume_SNMP_Scan"
| extend RiskScore = case(
UniqueTargets > 20, 95,
UniqueTargets > 10, 85,
SNMPRequests > 100, 80,
65)
| project Timestamp, DeviceName, AccountName,
FileName = InitiatingProcessFileName,
ProcessCommandLine = InitiatingProcessCommandLine,
AlertType, SNMPRequests, UniqueTargets, TargetIPs, RiskScore;
// Detection Path 3: SNMP authentication failures on network devices (Syslog)
let SNMPAuthFailures = Syslog
| where TimeGenerated > ago(TimeWindow)
| where SyslogMessage has_any ("SNMP", "snmp")
| where SyslogMessage has_any (
"Authentication failure", "authentication failure", "authenticationFailure",
"Unknown community", "wrong community", "No Such Name",
"invalid community", "Community name mismatch", "community string")
| summarize
FailureCount = count(),
SampleMessages = make_set(SyslogMessage, 3),
UniqueSourceIPs = dcount(extract(@"from\s+(\d+\.\d+\.\d+\.\d+)", 1, SyslogMessage))
by HostName, bin(TimeGenerated, 1h)
| where FailureCount >= 5
| extend AlertType = "SNMP_Auth_Failures_Network_Device"
| extend RiskScore = case(FailureCount > 50, 92, FailureCount > 20, 78, 62)
| project Timestamp = TimeGenerated, DeviceName = HostName,
AccountName = "NetworkDevice",
FileName = "snmpd",
ProcessCommandLine = strcat("Failures: ", tostring(FailureCount), " UniqueSourceIPs: ", tostring(UniqueSourceIPs), " Sample: ", tostring(SampleMessages)),
AlertType, FailureCount, UniqueSourceIPs, RiskScore;
// Combined output across all detection paths
EndpointSNMPTools
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, AlertType, RiskScore
| union (SNMPTrafficBurst
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, AlertType, RiskScore)
| union (SNMPAuthFailures
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, AlertType, RiskScore)
| sort by Timestamp desc Three-path detection for SNMP MIB enumeration targeting network infrastructure: (1) DeviceProcessEvents identifies SNMP enumeration tools (snmpwalk, snmpget, snmpbulkwalk, etc.) or commands containing MIB OID prefixes (.1.3.6) or weak default community strings ('public'/'private') — risk scores 70-95 based on indicator combination; (2) DeviceNetworkEvents identifies high-volume SNMP UDP/161 traffic indicating automated MIB walks, triggering on more than 20 requests in 10 minutes or more than 3 unique target devices; (3) Syslog captures SNMP authentication failures on network devices indicating community string guessing, triggering on 5+ failures per hour. All paths converge into a single output sorted by timestamp for analyst triage.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate network management platforms (SolarWinds Orion, PRTG, Nagios, Zabbix, LibreNMS) polling network devices via SNMP on UDP/161 for availability and performance monitoring — these generate high-volume, regular-interval SNMP traffic from known management server IPs
- Network engineers manually running snmpwalk or snmpget to troubleshoot device configurations, verify SNMP community string setup, or validate OID responses during maintenance windows
- Automated asset discovery tools (Nmap with snmp-info scripts, OpenNMS, Netdisco) performing scheduled network inventory scans that enumerate SNMP-capable devices
- Authorized security assessments and vulnerability scans using SNMP enumeration modules (Metasploit auxiliary/scanner/snmp/snmp_enum, Nessus SNMP scanner, Qualys) during penetration testing engagements
- IT operations runbooks where admins use snmpbulkwalk to baseline device configurations before and after maintenance changes
Other platforms for T1602.001
Testing Methodology
Validate this detection against 5 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1MIB-II Walk Using snmpwalk with Default Community String
Expected signal: Linux: /proc/[pid]/cmdline contains 'snmpwalk' with '-c public' and the target IP — visible in auditd execve events if auditd is configured, or in bash history at ~/.bash_history. Network device syslog will NOT log a successful community string match but WILL log if the string is wrong. Outbound UDP/161 packets visible in network capture or NetFlow records. Process execution visible in Sysmon Event ID 1 if run from a Windows host via WSL.
- Test 2Cisco Running Configuration Retrieval via SNMP
Expected signal: Process execution of snmpwalk with OID .1.3.6.1.4.1.9.2.1 visible in bash history and process monitoring. File creation of /tmp/cisco_mib_output.txt with MIB content. Cisco device syslog: no authentication log on success with correct community string, but 'SNMP-3-AUTHFAIL' if community string is wrong. Network NetFlow shows UDP/161 with large response payload (multi-KB) indicating successful data return.
- Test 3Python pysnmp Automated MIB Enumeration Script
Expected signal: Process creation for python3 with -c flag containing 'pysnmp', 'CommunityData', and 'public' — visible in Sysmon Event ID 1 CommandLine. Network connection on UDP/161 to TARGET_IP. No standard SNMP binary is invoked so binary-name-based detections miss this; detection relies on CommandLine content inspection or network traffic analysis.
- Test 4SNMP Community String Brute Force with onesixtyone
Expected signal: onesixtyone process creation with -c flag and target IP visible in Sysmon/auditd. File creation of /tmp/snmp_communities.txt containing community string wordlist. Network device generates '%SNMP-3-AUTHFAIL: Authentication failure for SNMP req from <source_ip>' for each failed community string attempt. Multiple rapid UDP/161 packets to the device visible in network capture.
- Test 5SNMP ARP and Routing Table Extraction
Expected signal: Three sequential snmpwalk processes with distinct OID arguments visible in process creation logs. Process command lines contain '.1.3.6.1.2.1.3.1' (atTable), '.1.3.6.1.2.1.4.24.4' (ipCidrRouteTable), and '.1.3.6.1.2.1.2.2' (ifTable). Three bursts of UDP/161 traffic to TARGET_IP visible in network telemetry. Response traffic (device -> attacker) will contain IP addresses, MAC addresses, and network prefixes.
References (8)
- https://attack.mitre.org/techniques/T1602/001/
- https://www.us-cert.gov/ncas/alerts/TA18-106A
- https://community.cisco.com/t5/security-blogs/attackers-continue-to-target-legacy-devices/ba-p/4169954
- https://tools.cisco.com/security/center/content/CiscoAppliedMitigationBulletin/cisco-amb-20080610-SNMPv3
- https://www.sans.org/reading-room/whitepapers/networkdevs/securing-snmp-net-snmp-snmpv3-1051
- https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/snmp/configuration/xe-16/snmp-xe-16-book/nm-snmp-cfg-snmp-support.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1602.001/T1602.001.md
- https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml
Unlock Pro Content
Get the full detection package for T1602.001 including response playbook, investigation guide, and atomic red team tests.