~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* Product: cdp - console cd player Versions: All Bug: Buffer overflow Impact: Attackers can execute arbitrary code Risk: Medium/High Date: March 31, 2004 Author: Shaun Colley Email: shaunige yahoo co uk WWW: http://www.nettwerked.co.uk ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* Introduction ############# cdp is... "cdp is a program that plays CDs at the linux console. It has a full-screen ncurses mode, and a command-line mode suitable for scripts that wish to play audio CDs. I consider cdp to be the CD equivalent of mpg123." - Taken from project page: <http://cdp.sourceforge.net/>. Despite cdp's usual robustness (and all credit to the authors), cdp is vulnerable to a stack-based buffer overflow vulnerability which may allow a potential attacker to craft a malicious audio CD, social engineer a user into playing the CD with 'cdp', triggering a buffer overflow. Details ######## The buffer overflow occurs in the routine which displays the information for each track, printTOC(). This function prints the track number, track name, and track time information to the screen when a user plays a CD with cdp. Due to lack of bounds checking when preparing and printing this information, a track with a songname which exceeds 200 bytes in length will trigger a buffer overflow. Below is the offending code: --- from cdp.c --- [...] char buffer[ 200 ], ch; [...] printf( "Track Num Start Time Length Name \n" ); for ( ind = 0; ind < cdStatus.thiscd.ntracks; ind++ ) { trk = &cdStatus.thiscd.trk[ ind ]; if ( trk->songname != NULL ) { sprintf( buffer, "%s", trk->songname ); } else buffer[ 0 ] = 0; [...] --- end of snippet --- As can be seen above, an sprintf call is made, copying trk->songname, if a songname exists, into a buffer which is only 200 bytes long. cdp gets the songname (name of the track) when a call to load() is made, which calls search_db() during it's execution flow. In this function, a songname possibly as long as 502 bytes is copied into a cdinfo type struct pointer (safely), which is later used by printTOC() (the vulnerable function) to be copied into 'buffer', which has only 200 bytes allocated, as seen and explained above, thus presenting the possibility of a stack-based buffer overflow, as 'buffer' can often be overflowed by up to 302 bytes. An attacker could create a specially crafted audio CD, and give it to a user, presenting an opportunity for exploitation of the issue, as very few people check the authenticity of audio CDs given to them. Exploitation ############# Exploitation of this issue would require that an attacker create a CD which has a track name (songname) exceeding 200 bytes, specially crafted to overwrite the instruction pointer (EIP) to redirect the execution flow elsewhere, causing execution of arbitrary code. Once a working exploit audio CD had been created, an attacker needs to simply pass the CD to a privileged user, and social engineer them into believing that the CD contains good music. I have not developed a proof-of-concept for this issue, but arbitrary code execution is most definately possible. Solution ######### I contacted the author around 5 days ago, but I haven't heard any response. This could be because the cdp project isn't maintained much anymore. The latest release was in January 2000. I have produced a patch to fix the issue, since the vendor hasn't contacted me back. The patch implements an snprintf() call rather than an sprintf() invokation, which fixes the vulnerability because bounds checks are performed. --- songname.patch --- --- cdp.c 2004-03-31 15:48:55.000000000 +0100 +++ cdp.1.c 2004-03-31 15:44:35.000000000 +0100 @@ -154,7 +154,7 @@ for ( ind = 0; ind < cdStatus.thiscd.ntracks; ind++ ) { trk = &cdStatus.thiscd.trk[ ind ]; if ( trk->songname != NULL ) { - sprintf( buffer, "%s", trk->songname ); + snprintf( buffer, strlen(buffer), "%s", trk->songname ); } else buffer[ 0 ] = 0; --- eof --- The patch can also be obtained from <http://www.nettwerked.co.uk/code/songname.patch>. The following steps can be taken to fix the problem: 1) Create a file containing the above patch 2) Apply the patch bash# patch cdp.c songname.patch 3) Rebuild 'cdp' bash# make && make install The issue should now be fixed. No proper workarounds exist, except for running an application which guards against stack-based overflows, such as StackGuard. Credit ####### This issue was discovered and researched by Shaun Colley - <shaunige yahoo co uk>. Thank you for your time. Shaun. ___________________________________________________________ WIN FREE WORLDWIDE FLIGHTS - nominate a cafe in the Yahoo! Mail Internet Cafe Awards www.yahoo.co.uk/internetcafes