[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

2013/04/26:
  Correctly handle truncated snprintf() in SSDP code

The problem is illustrated in the following code snippet:
Minissdp.c:
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
@CraigTweets