VideoLAN VLC Media Player <= 2.2.5 'EphemeralCockroach' Heap Overflow

2018.03.03
pl SivertPL (PL) pl
Risk: High
Local: No
Remote: Yes
CWE: CWE-199


CVSS Base Score: 6.8/10
Impact Subscore: 6.4/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

================================================== 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) [kroppoloe@protonmail.ch] Vulnerability discovery: Yannay Livneh from CheckPoint Security (yannayl) [yannayl@checkpoint.com] 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 kroppoloe@protonmail.ch, 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. =======


Vote for this issue:
100%
0%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top