xorl %eax, %eax

CVE-2008-4309: Net-SNMP Integer Overflow

with one comment

Net-SNMP is probably the most widely deployed SNMP implementation. This issue was reported by Oscar Mira-Sanchez and finally patched by Magnus Fromreide on 31 October 2008. The vulnerable versions are up to 5.4.2 for the 5.4 branch, 5.3.2.2 for 5.3 and 5.2.5 for 5.2 branch. Here, I’ll be using the 5.4.2 to demonstrate the vulnerability. The buggy code can be found at agent/snmp_agent.c:

2132 int
2133 netsnmp_create_subtree_cache(netsnmp_agent_session *asp)
2134 {
2135     netsnmp_subtree *tp;
2136     netsnmp_variable_list *varbind_ptr, *vbsave, *vbptr, **prevNext;
2137     int             view;
2138     int             vbcount = 0;
2139     int             bulkcount = 0, bulkrep = 0;
2140     int             i = 0, n = 0, r = 0;
2141     netsnmp_request_info *request;
     ...
2152     if (asp->pdu->command == SNMP_MSG_GETBULK) {
     ...
2172         } else {
2173             int numresponses;
2174             int           maxbulk =
2175                 netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
2176                                    NETSNMP_DS_AGENT_MAX_GETBULKREPEATS);
2177             int maxresponses =
2178                 netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
2179                                    NETSNMP_DS_AGENT_MAX_GETBULKRESPONSES);
2180
2181             if (maxresponses == 0)
2182                 maxresponses = 100;   /* more than reasonable default */
2183
2184             if (maxbulk == 0)
2185                 maxbulk = -1;
2186
2187             /* limit getbulk number of repeats to a configured size */
2188             if (asp->pdu->errindex > maxbulk && maxbulk != -1) {
2189                 asp->pdu->errindex = maxbulk;
2190             }
2191
2192             numresponses = asp->pdu->errindex * r;
2193
2194             /* limit getbulk number of getbulk responses to a configured size */
2195             if (maxresponses != -1 && numresponses > maxresponses) {
     ...
2202             asp->bulkcache =
2203                 (netsnmp_variable_list **) malloc(numresponses *
2204                                                   sizeof(struct
2205                                                          varbind_list *));
2206             if (!asp->bulkcache) {
2207                 DEBUGMSGTL(("snmp_agent", "Bulkcache malloc failed\n"));
2208                 return SNMP_ERR_GENERR;
2209             }
2210         }
2211         DEBUGMSGTL(("snmp_agent", "GETBULK N = %d, M = %d, R = %d\n",
2212                     n, asp->pdu->errindex, r));
2213     }
     ...
2328     return SNMPERR_SUCCESS;
2329 }


This is an extremely easy to spot integer overflow. It is at variable numresponses which is declared as a signed integer at line 2173 and it is later (line 2192) being manipulated on user controlled data and finally it attempts to allocate space on the heap (lines 2203-2204) which if we can make numresponses wrap around and contain a negative integer will surely fail. Of course, this is a crappy way to perform a remote DoS.
The patch to this bug was to completely remove this integer like this:

             asp->bulkcache = NULL;
         } else {
-            int numresponses;
             int           maxbulk =

and perform a check if the requested size can be allocated before reaching the malloc() library call:

-            if (maxbulk == 0)
-                maxbulk = -1;
+            /* ensure that the total number of responses fits in a mallocable
+             * result vector
+             */
+            if (maxresponses < 0 ||
+                maxresponses > INT_MAX / sizeof(struct varbind_list *))
+                maxresponses = INT_MAX / sizeof(struct varbind_list *);
+
+            /* ensure that the maximum number of repetitions will fit in the
+             * result vector
+             */
+            if (maxbulk <= 0 || maxbulk > maxresponses / r)
+                maxbulk = maxresponses / r;


Also, the getbulk limit was changed since negative values of maxbulk where checked earlier and now it’s this:

             /* limit getbulk number of repeats to a configured size */
-            if (asp->pdu->errindex > maxbulk && maxbulk != -1) {
+            if (asp->pdu->errindex > maxbulk) {
                 asp->pdu->errindex = maxbulk;
-            }
-
-            numresponses = asp->pdu->errindex * r;
-
-            /* limit getbulk number of getbulk responses to a configured size */
-            if (maxresponses != -1 && numresponses > maxresponses) {
-                /* attempt to truncate this */
-                asp->pdu->errindex = maxresponses/r;
-                numresponses = asp->pdu->errindex * r;
-                DEBUGMSGTL(("snmp_agent", "truncating number of getbulk repeats to %d\n", asp->pdu->errindex));
+                DEBUGMSGTL(("snmp_agent",
+                            "truncating number of getbulk repeats to %d\n",
+                            asp->pdu->errindex));
             }


At last, some heap allocation does not longer use numresponces for the size argument, but instead uses the asp->pdu->errindex multiplied by the responses:

asp->bulkcache =
-                (netsnmp_variable_list **) malloc(numresponses *
-                                                  sizeof(struct
-                                                         varbind_list *));
+                (netsnmp_variable_list **) malloc(
+                    asp->pdu->errindex * r * sizeof(struct varbind_list *));
if (!asp->bulkcache) {
               DEBUGMSGTL(("snmp_agent", "Bulkcache malloc failed\n"));
               return SNMP_ERR_GENERR;
+

There is no need to describe anything regarding its exploitation since its an old bug and there is also a PoC written by Hugo Oliveira Dias in Perl for this bug.

Written by xorl

April 1, 2009 at 16:13

Posted in bugs

One Response

Subscribe to comments with RSS.

  1. great blog u have !
    nice job.

    MFox

    April 2, 2009 at 05:16


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s