SNMP
SNMP is a network-device monitoring protocol. Versions 1 and 2c authenticate with a plaintext “community string” - basically a shared password - that’s often left at the default public. When SNMPv1/v2c is exposed with a guessable community string, you get a read-out of the entire device’s state: installed packages, running processes, network config, user accounts, sometimes more.
# 1. UDP scan (SNMP is UDP, won't show on TCP scans)sudo nmap -sU -p161 <target>
# 2. Brute-force community stringonesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt <target>
# 3. Walk the entire OID tree with the discovered communitysnmpwalk -v2c -c public <target>
# 4. Faster brute-force walkbraa public@<target>:.1.3.6.*
# 5. Specific high-value OIDssnmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.4.2.1.2 # running processessnmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.6.3.1.2 # installed softwaresnmpwalk -v2c -c public <target> 1.3.6.1.4.1.77.1.2.25 # Windows usersSuccess indicator: snmpwalk returns OID/value pairs from the target (anything past the device basic-info OIDs). Common community string public is the highest-incidence finding.
Protocol overview
Section titled “Protocol overview”SNMP queries devices for management information. It supports both reads (“what’s the CPU temperature?”) and writes (“set this configuration value”), plus an unsolicited “trap” channel for the device to push events to a manager.
| Port | Purpose | Transport |
|---|---|---|
| UDP 161 | Manager → agent queries (most operator work happens here) | UDP |
| UDP 162 | Agent → manager unsolicited traps | UDP |
UDP-based: the protocol is connectionless, you fire requests at the device and it responds (or doesn’t). Won’t show on TCP port scans - must explicitly -sU to see it.
Version differences
Section titled “Version differences”| Version | Year | Auth | Encryption | State |
|---|---|---|---|---|
| SNMPv1 | 1988 | Community string (plaintext) | None | Still in deprecated deployments, primary target for guessable-community attacks |
| SNMPv2c | 1996 | Community string (plaintext) | None | Most common version actually deployed |
| SNMPv3 | 1998 | Username + password (HMAC) | Optional (DES/AES) | Best-practice modern deployment |
For operator purposes: v1 and v2c are functionally equivalent - both use community strings, both transmit them in cleartext. v3 is a different beast with proper authentication and optional encryption. This page focuses on v1/v2c because they’re far more common and far more vulnerable.
MIB and OIDs
Section titled “MIB and OIDs”| Term | What it means |
|---|---|
| MIB (Management Information Base) | A text file describing the queryable objects on a device, in a tree structure |
| OID (Object Identifier) | A specific node in the MIB tree, addressed by a dot-separated string of integers: 1.3.6.1.2.1.1.1.0 |
| ASN.1 | The notation MIBs are written in |
The OID tree is hierarchical:
1 iso1.3 identified-organization1.3.6 dod1.3.6.1 internet1.3.6.1.2 mgmt1.3.6.1.2.1 mib-21.3.6.1.2.1.1 system1.3.6.1.2.1.1.1.0 sysDescr (system description, full)1.3.6.1.2.1.1.4.0 sysContact (admin contact email)1.3.6.1.2.1.1.5.0 sysName (hostname)You don’t need to memorize the tree. snmpwalk walks it for you; the OID registry is a searchable index.
High-value OID subtrees:
| OID | Contents |
|---|---|
1.3.6.1.2.1.1 | System info - hostname, OS description, contact, location, uptime |
1.3.6.1.2.1.2.2 | Network interfaces |
1.3.6.1.2.1.4.20 | IP addresses |
1.3.6.1.2.1.6.13 | TCP connection table |
1.3.6.1.2.1.25.1 | Host resources - uptime, RAM, mounted filesystems |
1.3.6.1.2.1.25.4.2.1 | Running processes |
1.3.6.1.2.1.25.6.3.1.2 | Installed software packages |
1.3.6.1.4.1.77.1.2.25 | (Windows) local user accounts |
1.3.6.1.4.1.77.1.4.1 | (Windows) primary domain |
1.3.6.1.4.1.77.1.2.27 | (Windows) shared printers |
Default configuration - Net-SNMP
Section titled “Default configuration - Net-SNMP”The Linux Net-SNMP daemon’s config is at /etc/snmp/snmpd.conf. Filtered to non-comments:
sysLocation Sitting on the Dock of the BaysysContact Me <[email protected]>sysServices 72master agentxagentaddress 127.0.0.1,[::1]view systemonly included .1.3.6.1.2.1.1view systemonly included .1.3.6.1.2.1.25.1rocommunity public default -V systemonlyrocommunity6 public default -V systemonlyrouser authPrivUser authpriv -V systemonlySettings to recognize:
agentaddress- which interface SNMP listens on (127.0.0.1= localhost only,0.0.0.0= all interfaces)viewdefinitions - subsets of the OID tree exposed to specific communitiesrocommunity <string>- read-only access for the named communityrwcommunity <string>- read+write access for the named communityrouser/rwuser- SNMPv3 equivalents, named user instead of community
By default, Net-SNMP exposes only a narrow systemonly view (basic system info + host resources) over the public community to localhost only. Real deployments often deviate to expose more, sometimes carelessly.
Dangerous settings
Section titled “Dangerous settings”| Setting | Why it’s bad |
|---|---|
agentaddress 0.0.0.0 (or udp:161 without bind-IP) | Listening on all interfaces - accessible from external networks |
rocommunity public (or any weak string) on a publicly accessible interface | Anyone who guesses public reads the whole tree |
rwcommunity <weak> <wide-source> | Read+write access from a wide IP range - attacker can change device config |
view full included .1 | Wide-open view definition - the community has access to everything, not just systemonly |
Multiple rocommunity lines | Multiple community strings, each a potential weak point |
rwuser noauth | SNMPv3 user with no authentication required |
rocommunity public 0.0.0.0/0 | The classic - public accessible from anywhere |
A misconfigured snmpd typically looks like this in the wild:
agentaddress 0.0.0.0rocommunity publicview all included .1That’s: listen on all interfaces, accept public, expose the entire OID tree. Walking it yields the entire device state.
Footprinting commands
Section titled “Footprinting commands”Port discovery
Section titled “Port discovery”sudo nmap -sU -p161 10.129.14.128PORT STATE SERVICE161/udp open|filtered snmpUDP port states are tricky:
open|filtered- nmap can’t tell. Could be open with a silent service, could be filtered. Almost always means “try snmpwalk and see if you get a response.”open- nmap got a positive UDP response back, confirming an SNMP service.filtered- ICMP “port unreachable” returned, meaning a firewall is dropping.closed- TCP-RST equivalent for UDP, very rare.
The --script snmp-info NSE script can probe further:
sudo nmap -sU -p161 --script snmp-info <target>Community string brute-force
Section titled “Community string brute-force”onesixtyone is purpose-built for this - fast, asynchronous, designed for sweeping many IPs with many community-string candidates:
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt 10.129.14.128Scanning 1 hosts, 3220 communities10.129.14.128 [public] Linux htb 5.11.0-37-generic #41~20.04.2-Ubuntu SMP ... x86_64The [public] brackets mean that’s the community string that worked, followed by the sysDescr (default OID 1.3.6.1.2.1.1.1.0) - the device’s self-description.
The default wordlist (snmp.txt in SecLists) covers thousands of common community strings. For broader coverage, build a custom wordlist from the target’s hostname patterns. Companies often name community strings after the hostname, the location, or the device role:
publicprivatecommunitymanageradmin<companyname><companyname>-snmp<companyname>-ro<companyname>-rw<location>-<role> # e.g., dc1-routerTools like crunch can generate permutation-heavy lists, but most real-world community strings are short and memorable - admins picked them by hand.
Full OID tree walk
Section titled “Full OID tree walk”Once you have a working community string:
snmpwalk -v2c -c public 10.129.14.128Output is verbose. Example excerpts:
iso.3.6.1.2.1.1.1.0 = STRING: "Linux htb 5.11.0-34-generic #36~20.04.1-Ubuntu SMP Fri Aug 27 ... x86_64"iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10iso.3.6.1.2.1.1.3.0 = Timeticks: (5134) 0:00:51.34iso.3.6.1.2.1.1.4.0 = STRING: "[email protected]"iso.3.6.1.2.1.1.5.0 = STRING: "htb"iso.3.6.1.2.1.1.6.0 = STRING: "Sitting on the Dock of the Bay"iso.3.6.1.2.1.25.1.4.0 = STRING: "BOOT_IMAGE=/boot/vmlinuz-5.11.0-34-generic root=UUID=9a6a5c52-... ro quiet splash"What this leaks:
- Exact kernel version (
5.11.0-34-generic) and distribution (Ubuntu 20.04) - Admin contact email (
[email protected]) - Hostname (
htb) - Boot command line, including UUID of the root filesystem
- Patch level - match the kernel to known privilege-escalation exploits
Further down the walk:
iso.3.6.1.2.1.25.6.3.1.2.1232 = STRING: "printer-driver-sag-gdi_0.1-7_all"iso.3.6.1.2.1.25.6.3.1.2.1235 = STRING: "proftpd-basic_1.3.6c-2_amd64"iso.3.6.1.2.1.25.6.3.1.2.1239 = STRING: "pulseaudio_1:13.99.1-1ubuntu3.12_amd64"iso.3.6.1.2.1.25.6.3.1.2.1243 = STRING: "python3_3.8.2-0ubuntu2_amd64"That’s the full installed-package list with versions. Cross-reference against vulnerability databases for known CVEs in any package.
Walking specific OIDs
Section titled “Walking specific OIDs”To narrow the walk to interesting subtrees:
# System infosnmpwalk -v2c -c public <target> 1.3.6.1.2.1.1
# Network interfacessnmpwalk -v2c -c public <target> 1.3.6.1.2.1.2
# IP addresses bound to this hostsnmpwalk -v2c -c public <target> 1.3.6.1.2.1.4.20
# Running processessnmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.4.2
# Installed softwaresnmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.6.3.1.2
# Active TCP connectionssnmpwalk -v2c -c public <target> 1.3.6.1.2.1.6.13
# Windows: local userssnmpwalk -v2c -c public <target> 1.3.6.1.4.1.77.1.2.25
# Windows: primary domainsnmpwalk -v2c -c public <target> 1.3.6.1.4.1.77.1.4.1
# Cisco: running config (if accessible)snmpwalk -v2c -c public <target> 1.3.6.1.4.1.9.9.96.1.1.1.1.2Faster: braa
Section titled “Faster: braa”snmpwalk queries one OID at a time, walking sequentially. braa is asynchronous - fires many SNMP requests in parallel - and is dramatically faster for full-tree dumps.
10.129.14.128:20ms:.1.3.6.1.2.1.1.1.0:Linux htb 5.11.0-34-generic ... x86_6410.129.14.128:20ms:.1.3.6.1.2.1.1.2.0:.1.3.6.1.4.1.8072.3.2.1010.129.14.128:20ms:.1.3.6.1.2.1.1.3.0:54810.129.14.128:20ms:.1.3.6.1.2.1.1.4.0:[email protected]10.129.14.128:20ms:.1.3.6.1.2.1.1.5.0:htb...Output is one-line-per-result, easy to grep:
Verifying writability - if rw is enabled
Section titled “Verifying writability - if rw is enabled”When rwcommunity is set, you can change device values via snmpset. This is mostly relevant for network devices (routers, switches) where SNMP-SET can:
- Change the running config
- Reboot the device
- Modify routing tables
- Disable interfaces
snmpset -v2c -c private <target> 1.3.6.1.2.1.1.5.0 s "owned"This sets the hostname (sysName) to “owned” - a benign test that confirms write access without breaking anything. Do not run write operations against production gear without explicit permission; one wrong OID can take down a router.
SNMPv3 enumeration
Section titled “SNMPv3 enumeration”If you find SNMPv3, brute-force is much slower (HMAC verification) but possible:
# Identify v3 users (engine ID enumeration is sometimes possible)snmpwalk -v3 -u testuser -l noAuthNoPriv <target>Most v3 deployments require both auth and priv (encryption). Without valid credentials, you don’t get further than the engine-ID response. Brute-forcing v3 with hydra is possible but slow and noisy.
Common chained workflows
Section titled “Common chained workflows”Community string → installed packages → kernel exploit:
onesixtyonefindspublicsnmpwalkreveals kernel version and patch level- Cross-reference for unpatched kernel exploits
- After gaining a foothold elsewhere, the kernel exploit gets root
Community string → user list → password spray:
- Walk the user-accounts OID subtree (Windows targets especially)
- Extracted user list goes into a password-spray against RDP/SMB
- Hits give shell
Community string → running processes → finger services to target:
- Process list shows what’s actually running
- Compare against open TCP ports - sometimes processes listen on internal-only interfaces
- Use SSRF or other paths to reach those internal services
Read community → write community guess:
- Once you’ve guessed
public(read), tryprivate(write) - many admins set both, just changing one letter - Verify write access non-destructively
- Now you can modify device config - for routers/switches, that’s a serious finding
Quick reference
Section titled “Quick reference”| Task | Command |
|---|---|
| UDP scan | sudo nmap -sU -p161 <target> |
| Community brute | onesixtyone -c snmp.txt <target> |
| Full walk | snmpwalk -v2c -c public <target> |
| Specific OID | snmpwalk -v2c -c public <target> 1.3.6.1.2.1.25 |
| Fast walk | braa public@<target>:.1.3.6.* |
| Get one OID | snmpget -v2c -c public <target> 1.3.6.1.2.1.1.5.0 |
| Set one OID (rw) | snmpset -v2c -c private <target> <OID> s "value" |
| System info | OID 1.3.6.1.2.1.1 |
| Running processes | OID 1.3.6.1.2.1.25.4.2 |
| Installed software | OID 1.3.6.1.2.1.25.6.3.1.2 |
| Windows users | OID 1.3.6.1.4.1.77.1.2.25 |