MiniUPnPd Information Disclosure (CVE-2013-2600)

2013-07-12 Thread cyoung
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(n0)
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


Re: MiniUPnPd Information Disclosure (CVE-2013-2600)

2013-07-12 Thread Jeffrey Walton
On Fri, Jul 12, 2013 at 2:16 PM,  cyo...@tripwire.com wrote:
 ...

 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(n0)
 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.
Truncation occurs at l = sizeof(buf) since because of the terminating NULL.

Jeff