[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MiniUPnPd Information Disclosure (CVE-2013-2600)

Hi list,
I am writing to inform you of an information disclosure vulnerability I noticed in MiniUPnPd a few months back.  Specifically, MiniUPnPd versions 1.8 and earlier are prone to an information disclosure vulnerability due to improper use of snprintf() while preparing SSDP responses. An attacker can exploit this vulnerability by sending a crafted request with a long ST header. If the header is long enough, the SSDP response buffer will be truncated by snprintf() and the subsequent sendto() call will read off the end of the buffer thereby disclosing the contents of adjacent memory. This response can reveal details of internal network topology as well as other activity on the target network.

This issue was addressed on April 26, 2013 as noted in the changelog: http://miniupnp.free.fr/files/changelog.php?file=miniupnpd-1.8.20130607.tar.gz

  Correctly handle truncated snprintf() in SSDP code

The problem is illustrated in the following code snippet:
203 static void SendSSDPAnnounce2(int s, struct sockaddr_in sockname,
204                               const char * st, int st_len,
205                               const char * host, unsigned short port)
206 {
207     int l, n;
208     char buf[512];
209     /* TODO :
210      * follow guideline from document "UPnP Device Architecture 1.0"
211      * put in uppercase.
212      * DATE: is recommended
213      * SERVER: OS/ver UPnP/1.0 miniupnpd/1.0
214      * */
215     l = snprintf(buf, sizeof(buf), "HTTP/1.1 200 OK\r\n"
216         "Cache-Control: max-age=120\r\n"
217         "ST: %.*s\r\n"
218         "USN: %s::%.*s\r\n"
219         "EXT:\r\n"
220         "Server: " MINIUPNPD_SERVER_STRING "\r\n"
221         "Location: http://%s:%u"; ROOTDESC_PATH "\r\n"
222         "\r\n",
223         st_len, st,
224         uuidvalue, st_len, st,
225         host, (unsigned int)port);
226     n = sendto(s, buf, l, 0,
227                (struct sockaddr *)&sockname, sizeof(struct sockaddr_in) );
228 #if 0 //JM: Don't fill up syslog, even in error condition
229     if(n<0)
230     {
231         syslog(LOG_ERR, "sendto: %m");
232     }
233 #endif
234 }

Notice that the sendto on line 226 is using the snprintf return value, l, from line 215 without considering whether l > sizeof(buf) as is the case when the buffer is truncated.  It is important to remember that snprintf() does not return the number of bytes written into the buffer but rather the number of bytes requested to be written into the buffer.

Kind Regards,
Craig Young