[Pkg-voip-commits] r6969 - in /asterisk/branches/etch/debian: changelog patches/00list patches/AST-2009-003.dpatch

tzafrir-guest at alioth.debian.org tzafrir-guest at alioth.debian.org
Sat Apr 4 15:38:01 UTC 2009


Author: tzafrir-guest
Date: Sat Apr  4 15:38:00 2009
New Revision: 6969

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=6969
Log:
Fix for AST-2009-003 (CVE-2008-3903) - SIP responses expose valid 
usernames (Closes: #522528).

Added:
    asterisk/branches/etch/debian/patches/AST-2009-003.dpatch   (with props)
Modified:
    asterisk/branches/etch/debian/changelog
    asterisk/branches/etch/debian/patches/00list

Modified: asterisk/branches/etch/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/etch/debian/changelog?rev=6969&op=diff
==============================================================================
--- asterisk/branches/etch/debian/changelog (original)
+++ asterisk/branches/etch/debian/changelog Sat Apr  4 15:38:00 2009
@@ -9,8 +9,10 @@
   * To re-enable it set "allowfwdownload = yes" in iaxprov.conf
   * Fix for AST-2009-001 (CVE-2009-0041) - Information leak in IAX2 
     authentication (Closes: #513413).
-
- -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Sat, 21 Feb 2009 15:56:30 +0200
+  * Fix for AST-2009-003 (CVE-2008-3903) - SIP responses expose valid 
+    usernames (Closes: #522528).
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Sat, 04 Apr 2009 18:35:37 +0300
 
 asterisk (1:1.2.13~dfsg-2etch5) stable-security; urgency=high
 

Modified: asterisk/branches/etch/debian/patches/00list
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/etch/debian/patches/00list?rev=6969&op=diff
==============================================================================
--- asterisk/branches/etch/debian/patches/00list (original)
+++ asterisk/branches/etch/debian/patches/00list Sat Apr  4 15:38:00 2009
@@ -18,6 +18,7 @@
 AST-2008-011.dpatch
 AST-2008-012.dpatch
 AST-2009-001.dpatch
+AST-2009-003.dpatch
 # ukcid probably conflicts with bristuff
 ukcid
 option_detach

Added: asterisk/branches/etch/debian/patches/AST-2009-003.dpatch
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/etch/debian/patches/AST-2009-003.dpatch?rev=6969&op=file
==============================================================================
--- asterisk/branches/etch/debian/patches/AST-2009-003.dpatch (added)
+++ asterisk/branches/etch/debian/patches/AST-2009-003.dpatch Sat Apr  4 15:38:00 2009
@@ -1,0 +1,162 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## AST-2009-003.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+##
+## DP: SIP responses expose valid usernames
+## DP: 
+## DP: See http://downloads.digium.com/pub/security/AST-2009-003.html
+## DP: Source: http://downloads.digium.com/pub/asa/AST-2009-003-1.2.diff.txt
+## DP: CVE: CVE-2008-3903
+
+ at DPATCH@
+Index: channels/chan_sip.c
+===================================================================
+--- a/channels/chan_sip.c	(revision 183480)
++++ b/channels/chan_sip.c	(working copy)
+@@ -6611,10 +6611,81 @@
+ /*! \brief Send a fake 401 Unauthorized response when the administrator
+   wants to hide the names of local users/peers from fishers
+ */
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, char *randdata, int randlen, int reliable)
++static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, char *randdata, int randlen, int reliable, int ignore)
+ {
+-	snprintf(randdata, randlen, "%08x", thread_safe_rand());
+-	transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0);
++	/* We have to emulate EXACTLY what we'd get with a good peer
++	 * and a bad password, or else we leak information. */
++	char *response = "407 Proxy Authentication Required";
++	char *reqheader = "Proxy-Authorization";
++	char *respheader = "Proxy-Authenticate";
++	const char *authtoken;
++
++	if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
++		response = "401 Unauthorized";
++		reqheader = "Authorization";
++		respheader = "WWW-Authenticate";
++	}
++
++	authtoken = get_header(req, reqheader);
++	if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
++		/* This is a retransmitted invite/register/etc, don't reconstruct authentication
++		 * information */
++		if (!reliable) {
++			/* Resend message if this was NOT a reliable delivery.   Otherwise the
++			   retransmission should get it */
++			transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
++			/* Schedule auto destroy in 15 seconds */
++			sip_scheddestroy(p, 15000);
++		}
++	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
++		/* We have no auth, so issue challenge and request authentication */
++		snprintf(p->randdata, sizeof(p->randdata), "%08x", thread_safe_rand());
++		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++		sip_scheddestroy(p, 15000);
++	} else {
++		char tmp[256], *c = tmp, *z, *nonce = "";
++
++		/* Find their response among the mess that we'r sent for comparison */
++		ast_copy_string(tmp, authtoken, sizeof(tmp));
++
++		while (c) {
++			c = ast_skip_blanks(c);
++			if (!*c) {
++				break;
++			}
++			if (!strncasecmp(c, "nonce=", strlen("nonce="))) {
++				c += strlen("nonce=");
++				if ((*c == '\"')) {
++					nonce = ++c;
++					if ((c = strchr(c,'\"'))) {
++						*c = '\0';
++					}
++				} else {
++					nonce = c;
++					if ((c = strchr(c,','))) {
++						*c = '\0';
++					}
++				}
++				/* Don't need anything beyond the nonce sent. */
++				break;
++			} else if ((z = strchr(c, ' ')) || (z = strchr(c, ','))) {
++				c = z;
++			}
++			if (c) {
++				c++;
++			}
++		}
++		/* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
++		if (strncasecmp(randdata, nonce, randlen)) {
++			snprintf(randdata, randlen, "%08x", thread_safe_rand());
++			transmit_response_with_auth(p, response, req, randdata, reliable, respheader, 0);
++
++			/* Schedule auto destroy in 15 seconds */
++			sip_scheddestroy(p, 15000);
++		} else {
++			transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++		}
++	}
+ }
+ 
+ /*! \brief  register_verify: Verify registration of user */
+@@ -6736,6 +6807,14 @@
+ 			}
+ 		}
+ 	}
++	if (!peer && global_alwaysauthreject) {
++		/* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
++		 * trying to avoid leaking information, we MUST also transmit the same
++		 * response when we DON'T find a peer. */
++		transmit_response(p, "100 Trying", req);
++		/* Insert a fake delay between the 100 and the subsequent failure. */
++		sched_yield();
++	}
+ 	if (!res) {
+ 		ast_device_state_changed("SIP/%s", peer->name);
+ 	}
+@@ -6756,7 +6835,7 @@
+ 		case -4:	/* ACL error */
+ 		case -5:	/* Peer is not supposed to register with us at all */
+ 			if (global_alwaysauthreject) {
+-				transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1);
++				transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, p->randdata, sizeof(p->randdata), 1, ignore);
+ 			} else {
+ 				/* URI not found */
+ 				if (res == -5)
+@@ -10699,7 +10778,7 @@
+ 		if (res < 0) {
+ 			if (res == -4) {
+ 				ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-				transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
++				transmit_fake_auth_response(p, SIP_INVITE, req, p->randdata, sizeof(p->randdata), 1, ignore);
+ 			} else {
+ 				ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
+ 				transmit_response_reliable(p, "403 Forbidden", req, 1);
+@@ -11105,7 +11184,7 @@
+ 		if (res < 0) {
+ 			if (res == -4) {
+ 				ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+-				transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
++				transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, p->randdata, sizeof(p->randdata), 1, ignore);
+ 			} else {
+ 				ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ 				if (ignore)
+Index: configs/sip.conf.sample
+===================================================================
+--- a/configs/sip.conf.sample	(revision 183480)
++++ b/configs/sip.conf.sample	(working copy)
+@@ -108,10 +108,12 @@
+ 				; Useful to limit subscriptions to local extensions
+ 				; Settable per peer/user also
+ ;notifyringing = yes		; Notify subscriptions on RINGING state
+-;alwaysauthreject = yes		; When an incoming INVITE or REGISTER is to be rejected,
+-		    		; for any reason, always reject with '401 Unauthorized'
+-				; instead of letting the requester know whether there was
+-				; a matching user or peer for their request
++;alwaysauthreject = yes          ; When an incoming INVITE or REGISTER is to be rejected,
++                                 ; for any reason, always reject with an identical response
++                                 ; equivalent to valid username and invalid password/hash
++                                 ; instead of letting the requester know whether there was
++                                 ; a matching user or peer for their request.  This reduces
++                                 ; the ability of an attacker to scan for valid SIP usernames.
+ ;
+ ; If regcontext is specified, Asterisk will dynamically create and destroy a
+ ; NoOp priority 1 extension for a given peer who registers or unregisters with

Propchange: asterisk/branches/etch/debian/patches/AST-2009-003.dpatch
------------------------------------------------------------------------------
    svn:executable = *




More information about the Pkg-voip-commits mailing list