Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
VLC_CVE-2021-25804_Analysis — 对CVE-2021-25804(一个VLC AVI解析器漏洞)的深入技术分析。内容包括根本原因、补丁差异及面向安全研究人员的利用原语。 | Kitploit
工具/GitHubGitHub/dshankle/vlc_cve-2021-25804_analysis
漏洞分析代码分析漏洞利用二进制分析论文与研究学习与教育
GitHubdshankle/vlc_cve-2021-25804_analysis

VLC_CVE-2021-25804_Analysis

对CVE-2021-25804(一个VLC AVI解析器漏洞)的深入技术分析。内容包括根本原因、补丁差异及面向安全研究人员的利用原语。

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
34年前尚未审核
分享

一个AVI文件可以有多个轨道。例如,一个音频轨道和一个视频轨道。

为了解析任意数量的轨道,VLC必须首先确定一个给定的轨道是否已完成并可播放。为此设置有两个变量,都命名为 i_track。

在我们的上下文中,变量 p_sys 代表AVI文件。因此,“官方”的 i_track 变量(用于引用那些被确定为已完成并可播放的轨道)是 p_sys->i_track。它在此处通过一个宏进行初始化:

root@kitploit:~
```
TAB_INIT(p_sys->i_track, p_sys->track);
//#define TAB_INIT( count, tab ) do {(count) = 0; (tab) = NULL; } while(0)
```

同时,设置了第二个 i_track 变量用于计数所有轨道,无论它们是否已完成/可播放:

root@kitploit:~
```
i_track = AVI_ChunkCount( p_hdrl, AVIFOURCC_strl, true );
```

第二个 i_track 代表所有以 'strl' 开头的块。它控制着一个 'for' 循环,该循环仅在通过一系列检查后才设置 p_sys->i_track 变量:

root@kitploit:~
```
for( unsigned i = 0 ; i < i_track; i++ )
{
    ...

TAB_APPEND( p_sys->i_track, p_sys->track, tk );
//#define TAB_APPEND( count, tab, p ) {TAB_APPEND_CAST( , count, tab, p )}
//TAB_APPEND_CAST( ,p_sys->i_track, p_sys->track, tk)
        //if( (count) > 0 ) (tab) = cast realloc( tab, sizeof( *(tab) ) * ( (count) + 1 ) ); 
        //else  (tab) = cast malloc( sizeof( *(tab) ) );    
        //if( !(tab) ) abort();                       
        //(tab)[count] = (p);                         
        //(count)++; //p_sys->i_track 在此处递增
}
```

在随后的一个 'for' 循环中,p_sys->i_track 变量被用作 AVI_ChunkFind 调用的块编号,该函数返回匹配给定 FOURCC 块值的第 n 个块,本例中为 'strl':

root@kitploit:~
```
for( unsigned i = 0 ; i < p_sys->i_track; i++ )
{
    avi_track_t         *tk = p_sys->track[i];

    if( tk->fmt.i_cat != AUDIO_ES ||
        tk->idx.i_size < 1 ||
        tk->i_scale != 1 ||
        tk->i_samplesize != 0 )
        continue;
        
    //CVE-2021-25804
    avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i, true );
    //随后更改为:avi_chunk_list_t *p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, tk->fmt.i_id, true );

    avi_chunk_strf_t *p_strf = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0, false );
    if( !p_strf || p_strf->i_cat != AUDIO_ES )
        continue;

    const WAVEFORMATEX *p_wf = p_strf->u.p_wf;
```

尽管 p_sys->i_track 确实计数了正确数量的已完成轨道,但它没有记录这些轨道对应的块编号。这意味着如果在一个有效的 strl 块之前有一个无效的 strl 块,那么第一个块在设置轨道对象时会被正确忽略,但当调用 ChunkFind 时,它仍然会选择第一个无效的块。

在 CVE-2021-25804 被创建之后,该问题通过将 ChunkFind 的块编号变量从 i 改为 tk->fmt.i_id 进行了修补。tk->fmt.i_id 是在我们之前看到的 TAB_APPEND() 调用正上方首次设置的:

root@kitploit:~
```
tk->fmt.i_id = i;

if( p_strn && p_strn->p_str )
    tk->fmt.psz_description = FromACP( p_strn->p_str );
//参见 es_format_truncated.c 
tk->p_es = es_out_Add( p_demux->out, &tk->fmt );


TAB_APPEND( p_sys->i_track, p_sys->track, tk );
```

这似乎修复了问题,因为 tk->fmt.i_id 被设置为 i,因此完成的块应该是 ChunkFind() 所选择的块。然而,测试显示,实际上在调用有问题的 ChunkFind() 时,tk->fmt.i_id 的值被设置为 -1。这是在对 es_format_Init() 的调用期间设置的初始化值。

root@kitploit:~
```
void es_format_Init( es_format_t *fmt,
                 int i_cat, vlc_fourcc_t i_codec )
{
    memset(fmt, 0, sizeof (*fmt));
    fmt->i_cat                  = i_cat;
    fmt->i_codec                = i_codec;
    fmt->i_profile              = -1;
    fmt->i_level                = -1;
    fmt->i_id                   = -1;
    fmt->i_priority             = ES_PRIORITY_SELECTABLE_MIN;
    fmt->psz_language           = NULL;
    fmt->psz_description        = NULL;
    fmt->p_extra_languages      = NULL;

    if (fmt->i_cat == VIDEO_ES)
        video_format_Init(&fmt->video, 0);

    fmt->b_packetized           = true;
    fmt->p_extra                = NULL;
}

```

此初始化发生在与 fmt->i_id 被设置为 i 相同的 'for' 循环中。

root@kitploit:~
```
    for( unsigned i = 0 ; i < i_track; i++ )
{
    ...
     switch( p_strh->i_type )
    {
        case( AVIFOURCC_auds ):
        {
            es_format_Init( &tk->fmt, AUDIO_ES, 0 );
            ...
        }
            ...
    }
    tk->fmt.i_id = i;

    if( p_strn && p_strn->p_str )
        tk->fmt.psz_description = FromACP( p_strn->p_str );

    tk->p_es = es_out_Add( p_demux->out, &tk->fmt );

    TAB_APPEND( p_sys->i_track, p_sys->track, tk );
}

```
下载工具