
PoC per CVE-2018-20343
Questa è una PoC per CVE-2018-20343, una vulnerabilità nel Build Engine di Ken Silverman. Il file .map generato innesca un buffer overflow e sovrascrive lo stack come mostrato di seguito:
Open Watcom sotto DosBox 0.74-2: l'analista controlla lo stack
Sotto FreeDos 1.2: l'analista controlla EIP
Il codice vulnerabile si trova in ENGINE.C:
1935 kread(fil,&numsectors,2);
1936 kread(fil,§or[0],sizeof(sectortype)*numsectors);
La variabile sector ha una dimensione dichiarata di MAXSECTORS * sizeof(struct sectortype) = 1024 * 40 = 40960 byte. L'analista controlla numsectors (poiché viene letto dal file di mappa) e può quindi creare un file di mappa per inizializzare numsectors con un valore maggiore di 40960 per innescare l'overflow.
Ken Silverman ha sottolineato che il codice che si basa sulla funzione kread, come i seguenti frammenti di codice, potrebbe essere anch'esso vulnerabile:
In ENGINE.C:
1938 kread(fil,&numwalls,2);
1939 kread(fil,&wall[0],sizeof(walltype)*numwalls);
1940
1941 kread(fil,&numsprites,2);
1942 kread(fil,&sprite[0],sizeof(spritetype)*numsprites);
2033 kread(fil,palette,768);
2034 kread(fil,&numpalookups,2);
[...]
2046 kread(fil,palookup[globalpal],numpalookups<<8);
2047 kread(fil,transluc,65536);
2453 kread(fil,&artversion,4);
2454 if (artversion != 1) return(-1);
2455 kread(fil,&numtiles,4);
2456 kread(fil,&localtilestart,4);
2457 kread(fil,&localtileend,4);
2458 kread(fil,&tilesizx[localtilestart],(localtileend-localtilestart+1)<<1);
2459 kread(fil,&tilesizy[localtilestart],(localtileend-localtilestart+1)<<1);
2460 kread(fil,&picanm[localtilestart],(localtileend-localtilestart+1)<<2);
2520 kread(fil,&dasiz,4);
2521 //Must store filenames to use cacheing system :(
2522 voxlock[voxindex][i] = 200;
2523 allocache(&voxoff[voxindex][i],dasiz,&voxlock[voxindex][i]);
2524 ptr = (char *)voxoff[voxindex][i];
2525 kread(fil,ptr,dasiz);
In KDMENG.C:
1155 kread(fil,&dawaversionum,4);
1156 if (dawaversionum != 0) { kclose(fil); return; }
1157
1158 kread(fil,&numwaves,4);
1159 for(i=0;i<numwaves;i++)
1160 {
1161 kread(fil,&instname[i][0],16);
1162 kread(fil,&wavleng[i],4);
1163 kread(fil,&repstart[i],4);
1164 kread(fil,&repleng[i],4);
1165 kread(fil,&finetune[i],4);
1194 kread(fil,snd,totsndbytes);
1214 kread(fil,&kdmversionum,4);
1215 if (kdmversionum != 0) return(-2);
1216 kread(fil,&numnotes,4);
1217 kread(fil,&numtracks,4);
1218 kread(fil,trinst,numtracks);
1219 kread(fil,trquant,numtracks);
1220 kread(fil,trvol1,numtracks);
1221 kread(fil,trvol2,numtracks);
1222 kread(fil,nttime,numnotes<<2);
1223 kread(fil,nttrack,numnotes);
1224 kread(fil,ntfreq,numnotes);
1225 kread(fil,ntvol1,numnotes);
1226 kread(fil,ntvol2,numnotes);
1227 kread(fil,ntfrqeff,numnotes);
1228 kread(fil,ntvoleff,numnotes);
1229 kread(fil,ntpaneff,numnotes);
La PoC per questa vulnerabilità è stata testata utilizzando i seguenti ambienti:
Il Build engine è stato utilizzato in molti giochi. Di seguito è riportato un elenco di giochi basati sul Build engine che sono stati testati contro la PoC (che sovrascrive la variabile sector):
| Gioco | Data di rilascio | Versione | Stato |
|---|
| Duke Nukem 3D | 1996 | 1.5 | vulnerabile |
| Shadow Warrior | 1997 | 1.2 | vulnerabile |
| Redneck Rampage | 1997 | 1.01 | vulnerabile |
| Blood | 1997 | 1.0 | non vulnerabile |