Lucene search
K

VideoLAN VLC Media Player 2.2.5 EphemeralCockroach Heap Overflow Exploit

🗓️ 04 Mar 2018 00:00:00Reported by SivertPLType 
zdt
 zdt
🔗 0day.today👁 74 Views

VideoLAN VLC Media Player EphemeralCockroach Heap Overflo

Related
Code
==================================================
Date: 02/28/2018
Title: VideoLAN VLC Media Player <= 2.2.5 'EphemeralCockroach' Heap Overflow
CVE: CVE-2017-8311
Exploit and Writeup: Patrick Z. (SivertPL) [[email protected]]
Vulnerability discovery: Yannay Livneh from CheckPoint Security (yannayl) [[email protected]]
Download VLC: https://www.videolan.org/vlc/releases/2.2.4.html (for example, any lower or equal to 2.2.5 will do)
CWE: CWE-199 (Heap-Based Buffer Overflow)
==================================================


This is the infamous EphemeralCockroach subtitle vulnerability in VLC Media Player which gained notoriety in mid-2017.
There were no public exploits / writeups on this one so I decided it was worth trying.

Media:
https://threatpost.com/subtitle-hack-leaves-200-million-vulnerable-to-remote-code-execution/125868/
http://www.bbc.com/news/technology-40058175

======

Writeup and details on the vulnerability

======

There is a heap buffer overflow in ParseJSS in modules/demux/subtitle.c.
This function is used in a loop for parsing JacoSUB subtitle format files.

This is a combined heap-overflow condition. Due to double-incrementing of psz_text pointer, the null-byte is skipped thus the program fails to stop the loop
which results in IMMEDIATE overflow of the heap buffer into psz_orig heap chunk.

======

VULNERABLE CODE SNIPPET FROM PATCH DIFF IN 2.2.5.1:

Function ParseJSS in modules/demux/subtitle.c.
This is just a snippet but you can find the vulnerable code near the end of the ParseJSS function.

======
/* All variables in the following code are named using the hungarian notation (type_name, ex. i_size stands for INT size, psz_text stands for a null-terminated string) */


for( ; *psz_text != '\0' && *psz_text != '\n' && *psz_text != '\r'; ) // If psz_text is not null byte, newline or carriage return then this loop will keep going (IMPORTANT, but keep reading)
{
    switch( *psz_text )
    {
    case '{':
        p_sys->jss.i_comment++;
        break;
    case '}':
        if( p_sys->jss.i_comment )
        {
            p_sys->jss.i_comment = 0;
            if( (*(psz_text + 1 ) ) == ' ' ) psz_text++;
        }
        break;
    case '~':
        if( !p_sys->jss.i_comment )
        {
            *psz_text2 = ' ';
            psz_text2++;
        }
        break;
    case ' ':
    case '\t':
        if( (*(psz_text + 1 ) ) == ' ' || (*(psz_text + 1 ) ) == '\t' )
            break;
        if( !p_sys->jss.i_comment )
        {
            *psz_text2 = ' ';
            psz_text2++;
        }
        break;
    case '\\':
        if( (*(psz_text + 1 ) ) == 'n' )
        {
            *psz_text2 = '\n';
            psz_text++;
            psz_text2++;
            break;
        }
        if( ( toupper((unsigned char)*(psz_text + 1 ) ) == 'C' ) ||
                ( toupper((unsigned char)*(psz_text + 1 ) ) == 'F' ) )
        {
            psz_text++;
            break;
        }
        if( (*(psz_text + 1 ) ) == 'B' || (*(psz_text + 1 ) ) == 'b' ||
            (*(psz_text + 1 ) ) == 'I' || (*(psz_text + 1 ) ) == 'i' ||
            (*(psz_text + 1 ) ) == 'U' || (*(psz_text + 1 ) ) == 'u' ||
            (*(psz_text + 1 ) ) == 'D' || (*(psz_text + 1 ) ) == 'N' )
        {
            psz_text++;
            break;
        }

        /* VULNERABLE CODE BELOW */
        if( (*(psz_text + 1 ) ) == '~' || (*(psz_text + 1 ) ) == '{' ||
            (*(psz_text + 1 ) ) == '\\' )
            psz_text++;
        else if( *(psz_text + 1 ) == '\r' ||  *(psz_text + 1 ) == '\n' || // If it ends with \r or \n, that's OK because there's still \0 afterwards.
                 *(psz_text + 1 ) == '\0' ) // but not in this case...
        {
            // We assume *(psz_text + 1) == '\0' at the moment
            psz_text++;
            /*
            * After incrementing the ptr, *psz_text == '\0' at the moment.
            * We have reached the end of the string
            * RIGHT NOW the code lands on the arrow-marked section.
            * FROM: -->
            */
        }
        break;
    default:
        if( !p_sys->jss.i_comment )
        {
            *psz_text2 = *psz_text;
            psz_text2++;
        }
    }
    /*
    * TO: <--
    * It DOESN'T matter what has happened before, it's still going to land in this section.
    * We assume *psz_text == '\0' atm, so we have reached the end of the string (and thus the end of the buffer !!)
    */

    psz_text++;

    /*
    * BOOM!
    * *(psz_text + 1) = 1 byte overflow into psz_orig (the buffer right after psz_text, look at the original code of the patch)
    * BUT The most important aspect of this overflow, is that
    * Right now, the check in the loop at the beginning will PASS, because we've skipped the null terminator and the loop will KEEP GOING !!!
    */

}

========

PoC

========

Successful exploitation leading to RCE is difficult, nevertheless possible.
The vulnerability poses a challenge because of:
- All mitigations are enabled (ASLR, DEP etc) and need to be bypassed
- The format is SCRIPTLESS
- Multi threading is implemented

For creating a PoC you need to create a JacoSUB subtitle file and load it in VLC. The specification for this ancient format is below:
http://unicorn.us.com/jacosub/jscripts.html

You need to overflow at least 32 bytes into the psz_orig buffer to crash the player.

======

About me

=======


My name is Patrick and I'm a 17 year old Polish-American wannabe hacker/security researcher.
I understand that I need a lot of patience and practice to master this field.

Therefore I'm looking for a security research team or someone EXPERIENCED in the field to help me out.
My dream is to join a good security-research / ethical hacker group with experienced people.

I've participated in NETGEAR Cash Rewards bug bounty at bugcrowd.com and submitted 8 valid vulnerabilities.

Some of my CVEs are:
- CVE-2017-6077
- CVE-2017-6334
- CVE-2017-6366
All of these are published on exploit-db and these are my first vulnerabilities EVER published (not including bug-bounty ones)

Contact me at [email protected], I really appreciate ANYONE who wishes to include me in their team!

Thank you, publishing my work on this website means A LOT to me.

=======



#  0day.today [2018-04-09]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation