JFrog公开了一个流行的多媒体库PJSIP中的5个内存损坏漏洞

5 PJSIP内存破坏漏洞

更新03/03/22-增加了关于脆弱的应用程序

JFrog的安全研究团队不断在流行的开源项目中寻找新的和以前未知的安全漏洞,以帮助改善他们的安全状况。作为这项工作的一部分,我们最近发现了5个安全漏洞PJSIP,一个广泛使用的开源多媒体通信库Teluu

通过触发这些新发现的漏洞,攻击者可以导致在使用PJSIP库的应用程序中执行任意代码。

JFrog Security负责任地披露了这些漏洞,并与PJSIP的维护者合作,验证了这些报告的安全漏洞的修复。

PJSIP库用于什么?

PJSIP提供了一个可以被IP电话应用程序(如VoIP电话和会议应用程序)使用的API。今天,WhatsApp和BlueJeans等世界上最流行的通讯应用程序都在使用它。PJSIP也被星号例如,无处不在的开源PBX(私有分支交换机)实现。

公开的PJSIP安全漏洞

CVE ID 描述 影响 JFrog CVSS
cve - 2021 - 43299 调用PJSUA API时堆栈溢出pjsua_player_create 代码执行 8.1
cve - 2021 - 43300 调用PJSUA API时堆栈溢出pjsua_recorder_create 代码执行 8.1
cve - 2021 - 43301 调用PJSUA API时堆栈溢出pjsua_playlist_create 代码执行 8.1
cve - 2021 - 43302 在调用PJSUA API时读取越界pjsua_recorder_create 拒绝服务 5.9
cve - 2021 - 43303 调用PJSUA API时缓冲区溢出pjsua_call_dump 拒绝服务 5.9

谁会受到PJSIP漏洞的影响?

任何在2.12版本之前使用PJSIP库并通过的项目attacker-controlled以下任何api的参数都是脆弱的:

  • pjsua_player_create- - - - - -文件名参数必须由攻击者控制
  • pjsua_recorder_create- - - - - -文件名参数必须由攻击者控制
  • pjsua_playlist_create- - - - - -file_names参数必须(部分地)由攻击者控制
  • pjsua_call_dump- - - - - -缓冲参数容量必须小于128字节

要澄清的是——这意味着利用依赖于上下文——应用程序必须以特定的方式使用PJSIP库才能受到攻击,即调用上述api并将外部输入传递给来自这些api的特定参数。
JFrog的安全研究团队已经披露了库本身的漏洞,并没有声称任何特定的应用程序是脆弱的(因为我们没有研究特定的应用程序)-这包括前一节中提到的应用程序,这些应用程序没有研究(WhatsApp, BlueJeans和Asterisk)。

技术故障

PJSIP提供了一个名为PJSUA为SIP应用程序提供API。基本的PJSUA api也由面向对象的api包装。PJSUA提供了丰富的媒体操作API,我们发现了以下漏洞:

cve - 2021 - 43299发现于pjsua_player_create(OO包装器-AudioMediaPlayer: createPlayer),它会创建一个文件播放器,并自动将该播放器添加到会议桥。

此函数包含堆栈溢出漏洞:

PJ_DEF(pj_status_t) pjsua_player_create(const pj_str_t *filename, unsigned options, pjsua_player_id *p_id) {unsigned slot, file_id;char路径(PJ_MAXPATH);...Pj_memcpy(路径,文件名->ptr,文件名->slen);路径[filename->slen] = '\0';...}

文件名- > ptr正在被复制到路径没有验证文件名- > slen(文件名大小)的最大值路径的分配大小,即PJ_MAXPATH < c /赋>(260)。因此,传递文件名超过260个字符将导致堆栈溢出。

cve - 2021 - 43300而且cve - 2021 - 43302被发现在pjsua_recorder_create ()(OO包装器-AudioMediaRecorder: createrecord),它会创建一个文件记录器,并自动将该记录器连接到会议网桥。

此函数包含堆栈溢出漏洞:

PJ_DEF(pj_status_t) pjsua_recorder_create(const pj_str_t *filename, unsigned enc_type, void *enc_param, pj_ssize_t max_size, unsigned options, pjsua_recorder_id *p_id){…char路径(PJ_MAXPATH);pj_str_t ext;.../*确定文件格式*/ ext.ptr = filename->ptr + filename->slen - 4;Ext.slen = 4;if (pj_stricmp2(&ext, ".wav") == 0) file_format = FMT_WAV;else if (pj_stricmp2(&ext, ".mp3") == 0) file_format = FMT_MP3;Else{…}…… pj_memcpy(path, filename->ptr, filename->slen); path[filename->slen] = '\0'; ... }

ext.ptr设置为文件名->ptr +文件名->slen - 4而且ext.slen设置为4,后来pj_stricmp2ext为了比较文件的扩展名“wav”“mp3”

披露的问题为cve - 2021 - 43302是,pjsua_recorder_create不检查长度文件名至少是4。如果文件名短于4pj_stricmp2在比较字符串时将导致读取越界。

cve - 2021 - 43300类似于cve - 2021 - 43299文件名- > ptr正在被复制memcpy路径没有检查堆栈变量文件名- > slen最多是路径分配的大小为PJ_MAXPATH(260)。

cve - 2021 - 43301中是否发现了另一个类似的堆栈溢出漏洞pjsua_playlist_create(OO包装器-AudioMediaPlayer: createPlaylist),它会创建一个文件播放列表媒体端口,并自动将该端口添加到会议桥接。
pjsua_playlist_create调用pjmedia_wav_playlist_createfile_names参数映射为file_list

PJ_DEF(pj_status_t) pjmedia_wav_playlist_create(pj_pool_t *pool, const pj_str_t *port_label, const pj_str_t file_list[], int file_count, unsigned ptime, unsigned options, pj_ssize_t buff_size, pjmedia_port **p_port){…字符的文件名(PJ_MAXPATH);/*打开操作的文件名。* /…/*确保所有文件都存在*/ for (index=0;指数< file_count;index++) {PJ_ASSERT_RETURN(file_list[index].)slen < PJ_MAXPATH, PJ_ENAMETOOLONG);Pj_memcpy(文件名,file_list[index].ptr, file_list[index].slen);文件名(file_list(指数)。Slen] = '\0';/*检查文件是否存在。 */ if (!pj_file_exists(filename)) { PJ_LOG(4,(THIS_FILE, "WAV playlist error: file '%s' not found", filename)); return PJ_ENOTFOUND; } } ... /* ok run this for all files to be sure all are good for playback. */ for (index=file_count-1; index>=0; index--) { pjmedia_wave_hdr wavehdr; pj_ssize_t size_to_read, size_read; /* we end with the last one so we are good to go if still in function*/ pj_memcpy(filename, file_list[index].ptr, file_list[index].slen); filename[file_list[index].slen] = '\0'; ... } ... }

该函数从file_list文件名没有检查它的长度是否最大PJ_MAXPATH(260)。如果文件名长度较长-副本将溢出文件名变量并触发堆栈溢出。

cve - 2021 - 43303是否存在缓冲区溢出漏洞pjsua_call_dump将调用统计数据转储到给定缓冲区的函数:

PJ_DEF(pj_status_t) pjsua_call_dump(pjsua_call_id call_id, pj_bool_t with_media, char *buffer, unsigned maxlen, const char *indent){…char tmp [128];.../* TMP被填充在这里*/…(int)pj_ansi_strlen(tmp);pj_ansi_strcpy(缓冲区,tmp);...}

函数使用tmp以便暂时存储统计数据,然后将其复制到输出参数缓冲没有验证maxlen最多是len(最高可达128)。

这可能导致缓冲区溢出,如果给定的容量缓冲参数小于len

修复漏洞

为了完全修复这些漏洞,我们建议将PJSIP升级到2.12版本。

确认

我们要感谢PJSIP维护者快速验证报告的漏洞并修复它们。

寻找易受攻击的版本与JFrog x射线

除了曝光新安全漏洞JFrog为开发人员和安全团队提供了方便地访问其软件的最新相关信息-包括使用PJSIP开源库版本和相关的cve -通过自动安全扫描JFrog x射线SCA工具