|
Vulnerability Flash Affected Olivier Debon's Flash Description Neal K. found following. There are two primary sources for Flash plugins: - Macromedia provides the official version. They are NOT affected by this latest defect. - Olivier Debon provides an unofficial version that has been ported to all operating systems not supported by Macromedia (and some that are supported by Macromedia). Systems affected include: Linux (those viewing Flash without the Macromedia plugin), FreeBSD, HP-UX, BeOS, Amiga, Solaris 2.5-2.8. - The port to Windows CE by Conduit Technologies is not affected. To determine which one you are using, use the URL "about:plugins" under Netscape. If you see Olivier Debon's name, then you are vulnerable. Even if you compiled it with the "NOSOUND" flag, you are still vulnerable. Location of the defect: DefineSound The format of this tag: tag_14 length_of_tag sound_id flags samples data Sound_id is two bytes giving the sound object a reference ID. Flags is one byte that determine things like sampling rate and stereo. "Samples" are four bytes telling the number of samples in the recording (ID + Flags + Samples = 5 bytes). The remaining data contains the actual sound (Flags + Samples + Data = length of tag). The defect: File "script.cc", in function "ParseDefineSound()". void CInputScript::ParseDefineSound() { Sound *sound; U32 tagid = (U32) GetWord(); long nbSamples; long flags; char *buffer; sound = new Sound(tagid); flags = GetByte(); sound->setSoundFlags(flags); addCharacter(sound); nbSamples = GetDWord(); buffer = sound->setNbSamples(nbSamples); if (flags & soundIsADPCMCompressed) { Adpcm *adpcm; adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo ); adpcm->Decompress((short *)buffer, nbSamples); delete adpcm; } else { memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5); } } The last memcpy/Decompress call causes a write-overflow when the number of samples is less than the remaining amount of data in the file. "buffer" is allocated in sound.cc: char * Sound::setNbSamples(long n) { long size; nbSamples = n; size = nbSamples * (stereo ? 2 : 1) * sampleSize; samples = new char[ size ]; memset((char *)samples,0, size); return samples; } The "sampleSize" is either 1 or 2 (depends on the flags used). The size of "buffer" is allocated to be "number of samples * sampleSize * 1 or 2 for stereo". The memcpy in ParseDefineSound() copies all of the data into the allocated buffer. So the defect: - we can define nbSamples (number of samples). - we define it to be much less than the number of data bytes. Should be: ID + Flags + Samples = length of tag - Data. Overflow when: ID + Flags + Samples < length of tag - Data This is a write-overflow. This is capable of running arbitrary code. There is example posted at: http://www.verinet.com/~nealk/Flash_and_Crash/ Solution Nothing yet.