COMMAND
Flash
SYSTEMS AFFECTED
Olivier Debon's Flash
PROBLEM
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.