CVE-2025-65102
Executive Summary
CVE-2025-65102 is a memory corruption vulnerability in the PJSIP multimedia communication library, specifically within the Opus audio codec's Packet Loss Concealment (PLC) functionality. The flaw arises when the Opus PLC zero-fills an input frame based on the decoder ptime, while the actual input frame length, derived from the stream ptime, may be smaller. This mismatch can lead to a buffer overflow, causing unexpected application termination or potentially arbitrary code execution. The vulnerability affects all PJSIP versions prior to 2.16 and is triggered when receiving Opus-encoded audio streams. No public proof-of-concept or exploit code is currently available, and the EPSS score is 0.0%, indicating low exploitation activity. The vendor has released a patch in version 2.16.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
PJSIP is a widely used open-source library integrated into numerous VoIP and multimedia applications. Organizations using PJSIP as a dependency in their software supply chain are at risk. The vulnerability is introduced through the library's source code and affects any application that uses the Opus codec in receiving mode. Supply chain risk is elevated because the flaw is in a core audio processing component, and patching requires updating the library to version 2.16 or later. Developers should verify their dependency manifests (e.g., configure.ac, Makefile, or package manager files) to ensure they are not using an affected version.
CVSS Breakdown & Threat Level
CVSS Score: 7.5 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Attack Vector (AV): Network – The vulnerability can be exploited remotely by sending a crafted Opus audio stream.
- Attack Complexity (AC): Low – No special conditions are required; the attacker only needs to send a malicious stream.
- Privileges Required (PR): None – No authentication is needed.
- User Interaction (UI): None – The victim does not need to perform any action beyond receiving the stream.
- Scope (S): Unchanged – The exploit does not affect other components.
- Confidentiality (C): None – No data is exposed.
- Integrity (I): None – No data is modified.
- Availability (A): High – The vulnerability can cause a denial of service via application crash or memory corruption.
Threat Level: High. Although no active exploitation has been observed, the vulnerability is remotely triggerable and can lead to a denial of service. In worst-case scenarios, memory corruption could be leveraged for code execution.
Deep Dive & Mechanics
The vulnerability resides in the Opus PLC implementation within PJSIP. The Opus codec uses two different ptime (packet time) values: the stream ptime (the duration of the actual audio frame in the RTP packet) and the decoder ptime (the duration the decoder expects for PLC operations). When packet loss occurs, the PLC function attempts to conceal the loss by generating a replacement frame. The flawed code zero-fills a buffer using the decoder ptime as the size, but the actual input frame length is based on the stream ptime. If the stream ptime is smaller than the decoder ptime, the zero-fill operation writes beyond the allocated buffer, causing a heap-based buffer overflow.
Root Cause: The PLC function does not validate that the input frame length (stream ptime) is at least as large as the decoder ptime before performing the zero-fill. This allows an attacker to craft a stream with a small ptime, triggering the overflow.
Attack Scenario: An attacker sends a series of RTP packets containing Opus frames with a manipulated stream ptime. When packet loss is simulated or naturally occurs, the PLC function is invoked, and the buffer overflow occurs, potentially crashing the application or allowing memory corruption.
Vulnerable vs. Patched Code
Vulnerable Code (PJSIP < 2.16):
// In opus.c or similar PLC implementation
static void opus_plc(pjmedia_codec *codec, pjmedia_frame *frame)
{
// Vulnerable: zero-fills based on decoder ptime without checking frame length
pj_bzero(frame->buf, decoder_ptime * sample_rate * channels);
// ... rest of PLC logic
}
Patched Code (PJSIP 2.16):
// In opus.c
static void opus_plc(pjmedia_codec *codec, pjmedia_frame *frame)
{
// Patched: validate frame length against decoder ptime
pj_size_t expected_len = decoder_ptime * sample_rate * channels;
if (frame->size < expected_len) {
// Handle error or adjust PLC behavior
return;
}
pj_bzero(frame->buf, expected_len);
// ... rest of PLC logic
}
The patch adds a length check before the zero-fill operation, ensuring that the buffer is large enough to accommodate the decoder ptime. If the frame is too small, the PLC function returns early or handles the error gracefully.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A target application using PJSIP with Opus codec (e.g., a SIP client or media server).
- Ability to send RTP packets to the target.
Exploitation Steps:
- Craft Malicious RTP Stream: Create an RTP stream with Opus frames where the stream ptime is set to a small value (e.g., 2.5 ms) while the decoder ptime is larger (e.g., 20 ms). This can be done using tools like
scapyor custom Python scripts. - Trigger Packet Loss: Simulate packet loss by dropping some RTP packets or sending a sequence that forces the PLC to activate.
- Send Stream: Transmit the crafted stream to the target's RTP port.
- Observe Crash: The target application may crash due to the buffer overflow. In a controlled lab, use a debugger to confirm memory corruption.
Example Python Script (Conceptual):
from scapy.all import *
import struct
# Craft an RTP packet with small stream ptime
def craft_opus_rtp(seq_num, timestamp, ssrc, payload):
rtp = IP(dst="192.168.1.100")/UDP(sport=5004, dport=5004)/RTP(seq=seq_num, timestamp=timestamp, ssrc=ssrc)
# Opus payload with manipulated ptime (e.g., 2.5 ms)
opus_payload = struct.pack('!H', 0xFC01) + payload # Example Opus header
return rtp/opus_payload
# Send multiple packets with small ptime
for i in range(10):
pkt = craft_opus_rtp(i, i*160, 12345, b'\x00'*40) # Small frame
send(pkt, verbose=0)
Blue Team (Defensive)
Detection:
- Monitor for unusual RTP streams with abnormally small ptime values.
- Use network intrusion detection systems (NIDS) to flag Opus streams where the stream ptime is less than the decoder ptime.
- Enable application-level logging for PJSIP to capture PLC errors or crashes.
Mitigation:
- Immediately update PJSIP to version 2.16 or later.
- If patching is not possible, disable Opus codec support in the application configuration.
- Implement network segmentation to limit exposure of vulnerable services.
- Use a Web Application Firewall (WAF) or SIP-aware firewall to inspect RTP streams.
Indicators of Compromise (IOCs)
- Network IOCs:
- RTP packets with Opus payloads where the stream ptime is less than 10 ms (typical decoder ptime is 20 ms).
- Repeated RTP packets with sequence numbers indicating packet loss followed by application crashes.
- Host IOCs:
- Application crash logs referencing
opus_plcor memory corruption in PJSIP. - Core dumps showing heap overflow in the Opus codec module.
- Application crash logs referencing
- File IOCs:
- Modified PJSIP library files (e.g.,
libpjmedia-codec.so) if an attacker attempts to patch the vulnerability.
- Modified PJSIP library files (e.g.,
Detection Engineering
YARA Rule
rule CVE_2025_65102_Opus_PLC_Overflow {
meta:
description = "Detects PJSIP Opus PLC buffer overflow vulnerability"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-65102"
strings:
$s1 = "opus_plc" ascii wide nocase
$s2 = "pj_bzero" ascii wide nocase
$s3 = "decoder_ptime" ascii wide nocase
condition:
all of ($s*) and filesize < 10MB
}
Sigma Rule
title: CVE-2025-65102 PJSIP Opus PLC Buffer Overflow
id: 8a9b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects exploitation attempts of CVE-2025-65102 via abnormal RTP ptime values
author: Valters IT
logsource:
category: network
product: suricata
detection:
selection:
app_proto: 'rtp'
payload|contains: 'opus'
rtp.ptime: < 10
condition: selection
falsepositives:
- Legitimate low-latency Opus streams (rare)
level: high
Suricata Rule
alert udp any any -> any 5004 (msg:"CVE-2025-65102 PJSIP Opus PLC Buffer Overflow Attempt"; content:"|FC|"; depth:2; offset:12; pcre:"/RTP\/Opus.*ptime\s*=\s*[0-9]{1,2}/"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Patch: Upgrade PJSIP to version 2.16 or later. The patch is available from the official PJSIP repository.
- Workaround: If patching is delayed, disable the Opus codec in the application configuration (e.g., set
PJMEDIA_CODEC_OPUS_DISABLED=1). - Network Controls: Deploy SIP-aware firewalls to inspect RTP streams and block those with abnormal ptime values.
- Monitoring: Enable detailed logging for PJSIP and monitor for crashes or memory errors.
- Vendor Communication: If using a commercial product that bundles PJSIP, contact the vendor for a patched version.
Valters IT
This report is generated for educational and defensive purposes. Always follow responsible disclosure practices.