Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
أدوات/GitHubGitHub/dshankle/vlc_cve-2021-25804_analysis
تحليل الثغرات الأمنيةتحليل الكودالاستغلالتحليل الملفات الثنائيةالأوراق والأبحاثالتعلم والتعليم
GitHubdshankle/vlc_cve-2021-25804_analysis

VLC_CVE-2021-25804_Analysis

تحليل فني متعمق لـ CVE-2021-25804، وهي ثغرة في محلل AVI الخاص بـ VLC. يتضمن السبب الجذري وفرق التصحيح والبدائيات الاستغلالية للباحثين الأمنيين.

عرض المستودع
3منذ 4 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

يمكن أن يحتوي ملف 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 incremented here
}
```

خلال حلقة 'for' لاحقة، يُستخدم متغير p_sys->i_track كرقم القطعة في استدعاء AVI_ChunkFind، الذي يعيد القطعة رقم n المطابقة لقيمة FOURCC معينة، في حالتنا '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 );
    //subsequently changed to: 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 );
//see 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(). ومع ذلك، يكشف الاختبار أن قيمة tk->fmt.i_id في الواقع تُضبط إلى -1 في وقت استدعاء ChunkFind() المخالف. هذه هي قيمة التهيئة التي يتم تعيينها أثناء استدعاء 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;
}

```

تحدث هذه التهيئة في نفس حلقة 'for' التي يتم فيها تعيين fmt->i_id إلى i.

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 );
}

```
تنزيل الأداة