
Enough SNMP to Be Dangerous Part 1
by Elizabeth Zwicky
Elizabeth is technical lead of the European Desktop Project at Silicon
Graphics. She was a founding member of SAGE and is currently on the
USENIX Board of Directors.
SNMP, the simple network management protocol, is one of those simple but powerful (and therefore brain-bendingly complicated) concepts. The simple part of SNMP is that it basically supports only two commands and a few variations on them. The commands are get, to get the value of a variable, and set, to set the value of a variable. The hard part is figuring out (1) what variable you want and (2) what the value means. Because it doesn't require vast intelligence to speak SNMP, all sorts of things speak it. Among the devices with SNMP running on my local-area network, where we weren't using SNMP and therefore hadn't done anything special to turn it on, are almost every UNIX box, every router or switch with an IP address, every printer with an IP address, every NT machine or NT-variant machine, a significant number of machines running Windows 95, and the voicemail system. This means that a person armed with some freely available tools, some basic SNMP knowledge, and some interest in poking at network devices with blunt sticks, can come up with all sorts of interesting and occasionally even useful information. Freely Available Tools The first thing you need, of course, is the tools. The pre-eminent tool suite for SNMP is from the University of California at Davis, and is available from <http://www.ece.ucdavis.edu/ucd-snmp>. On top of that, you will probably want a Perl library; I use G. S. Marzot's. (I have to admit, I didn't do a comprehensive survey, I just picked the first one I ran across that worked): <ftp://ftp.wellfleet.com/netman/snmp/perl5/SNMP.tar.gz>. Basic SNMP Knowledge One of the not-so-simple things about SNMP is that it has its own terminology. This is not entirely unreasonable as a way of keeping you from making assumptions, but it can be daunting. At base, SNMP has two parts. One of them is a server that sits on the device; this is usually called an "agent." The other one is a client that asks questions; this is usually called a "manager." The main reason these things are not just called clients and servers is that the server half may be capable of initiating messages itself (called "traps"), in which case something that's normally a client needs to be sitting around listening for them. In this situation, the client-server paradigm is bent rather badly. The objects that the agent and the manager exchange are defined by something called a MIB (Management Information Base). A MIB specifies a mapping between long dotted numbers, human readable names, and pieces of information. For instance, .1.3.6.1.2.1.1.1.0 is more familiarly known as system.sysDescr.0, and it contains a description of the system. This is what the MIB that says this looks like: RFC1213-MIB DEFINITIONS ::= BEGIN IMPORTS
mgmt, NetworkAddress, IpAddress, Counter, Gauge,
TimeTicks mib-2 OBJECT IDENTIFIER ::= { mgmt 1 } system OBJECT IDENTIFIER ::= { mib-2 1 }
sysDescr OBJECT-TYPE ::= { system 1 } Most agents implement at least two MIBs, a standard base MIB and one specific to the device. Many of them implement more than that. A manager that talks to many different agents will quickly end up using dozens of different MIBs. That's okay, because the manager software we're using is easygoing in several ways. First, it doesn't really care if it has a MIB or not; if you're willing to use numbers or "get next" to get unparsed information, the software will gladly forgo the work of translating things into names. Second, it will read text form MIBs. Fancier management software generally wants to compile MIBs into more efficient forms; with the UCD package, you can just FTP over text files and shove them into its directory. I'll talk about how to find MIBs later; UCD provides the most basic MIBs along with the software. The final term you need to understand is "community string." The community string is a token passed from the manager to the agent; you might want to think of it as a remarkably weak password (it is passed around in cleartext). The device you're talking to will use the community name you give it to decide what data you should have access to. The default community is "public," which should theoretically give access only to "safe" information. In practice, vendors have an unfortunate tendency to allow all SNMP to the community "public"; this may include the ability to get information you might not want given out to anybody in the universe, like the names of all the accounts on your machine, or worse yet it may include the ability to do sets on arbitrary variables. Since SNMP is used for device management, and it has only two commands, set does a number of things that you might not expect; if you're thinking "What harm can setting a variable do?" consider the possibility that it's the "Reboot now" variable, and has just been set to "true." Obviously, this sort of approach provides the ability to do all sorts of truly moronic SNMP tricks, most of which will not be discussed here. Poking at Network Devices with Blunt Sticks Once you have installed the UCD tools, pick a host that you're reasonably certain is running SNMP, and try this: snmpget hostname public system.sysDescr.0 which will return something like system.sysDescr.0 = Silicon Graphics Challenge/1 running IRIX 6.3 if it works, and something like No Response from hostname if it doesn't. Obviously, the first parameter to snmpget is the name of the host you want to talk to. The second is the community string. If you, or your network managers, already know about SNMP, "public" may not be an appropriate community string, or may give you only tame information suitable for the sort of tricks I intend to talk about. If you get "No Response" from a device that you are sure should be speaking SNMP, try asking somebody if you need to use another community string. The second parameter, system.sysDescr.0, is the variable name that you want the value of. system.sysDescr.0 happens to be the first value defined by the absolutely most common MIB for SNMP devices to implement, which is usually called MIB-II, is defined in RFC1213, and is provided with the UCD SNMP libraries. sysDescr also happens to be both human-comprehensible and relatively amusing. For a first stupid SNMP trick, try asking all your local systems for system.sysDescr.0 and see how many of them return something that complies to the RFC definition above. Here's a sample of my results (nonprintable characters have been converted to ASCII equivalents). Fails the mandatory requirement to be printable: NX-500 ,2.0.6E^@
CyberSWITCH-100 (ISDN v5.2) v2.0^M (What are they copyrighting here? Is it legal for me to publish this?) Entirely printable, but missing either hardware or software. Note that Cisco manages to list software only on one machine, and hardware only on another.
Linux version 2.0.32 (root@linux95.corp.sgi.com) (gcc version
Microsoft Corp. Chicago Beta Cisco Systems Catalyst 1900
Cisco Internetwork Operating System Software Not interpretable by nonexperts: X8523L-3.4.7
ES/1 ATX
And just to prove that it can be done, a variety of vendors with their own eccentric formatting, but the right information (note that I'm willing to live without the network version, which only some of them include -- a more draconian reading of the spec would pass only the last three).
Hardware: x86 Family 6 Model 1 Stepping 9 AT/AT COMPATIBLE -
Software: Windows NT Version 3.51 (Build Number: 179 SGICOR - OCTEL OVERTURE 300 Voice Mail System, Id: 302164 Rev 2.0.1 Silicon Graphics Challenge/4 running IRIX64 6.2 SunOS cambio 5.5.1 Generic sun4m Tektronix, Inc., Phaser 360, PhaserShare Series B Network Interface, (5.44/1.62/9.16) Model; LANplex 2500, h/w rev; 06-0D, s/w rev; 04-03-00-07
80486 DOS 6.20
IBM RISC System/6000 HP3000 SERIES 948, MPE XL version B.40.00 NS Transport version B.05.00 I also ran into one machine that was running SNMP but did not have system.sysDescr; this is probably a symptom of gross misconfiguration. Finally, here's the world's stupidest Web-based SNMP tool. It consists of a Web page with a form:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
And its accompanying processor: #!/usr/bin/perl5
use SNMP;
print header;
$hostname = param('hostname');
if ($sess = new SNMP::Session(DestHost=>$hostname)){ print end_html; No points will be awarded for finding any of the obvious shortcomings of this little system -- except the sudden appearance of something called an "instance." At this point, we're still dealing with things that are one to a device; each device has exactly one system description, for example. That means that so far I've been able to get away with throwing around system.sysDescr and system.sysDescr.0 without ever quite mentioning where the trailing .0 comes from. However, SNMP also deals with things that come in multiples. For example, later on we'll probably be interested in interfaces.ifTable.ifEntry.ifDescr, which describes a network interface. Most network devices of interest have multiple network interfaces, and so there are multiple instances of interfaces.ifTable.ifEntry.ifDescr, one for each interface. I could have just left this hard-coded at 0 for now, but then I would have had to reprint a slightly modified program when we got to multiple-instance variables, and that would be annoying. Next time: We move on to more interesting parts of MIB II, and branch out into more interesting programming.
|
|
1st February 1999 jr Last changed: 1st February 1999 jr |
|