####################################################################### Luigi Auriemma Applicazione: Cube engine http://www.cubeengine.com Versioni: <= 2005_08_29 Piattaforme: Windows, *nix, *BSD e MacOS Bugs: A] sgetstr() buffer-overflow B] accesso invalido alla memoria C] crash dei clients tramite mappa invalida Exploitation: remoto, contro server e clients Data: 06 Mar 2006 Autore: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduzione 2) Bugs 3) The Code 4) Fix ####################################################################### =============== 1) Introduzione =============== Cube e' un interessante gioco e motore open source sviluppato da Wouter van Oortmerssen (http://strlen.com). Supporta il multiplayer sia in LAN che Internet. ####################################################################### ======= 2) Bugs ======= ---------------------------- A] sgetstr() buffer-overflow ---------------------------- Il gioco utilizza una funzione priva di controlli per la lettura delle stringhe dai dati in ingresso. La funzione e' sgetstr() che si trova in cube.h: #define sgetstr() { char *t = text; do { *t = getint(p); } while(*t++); } Il problema, che affligge sia server che clients, e' che questo codice copia i dati in input oltre il text buffer di dimensione MAXTRANS (5000 bytes) permettendo la possibile esecuzione di codice malevolo. -------------------------------- B] accesso invalido alla memoria -------------------------------- Sia sgetstr(), getint() e le istruzioni che le chiamano non effettuano alcun controllo sulla corretta lunghezza dei dati in input. In breve e' possibile forzare il server od il client a leggere oltre i dati ricevuti raggiungendo zone della memoria non allocate e quindi crashando immediatamente. L'esempio migliore nel Cube engine riguarda il tag SV_EXT usato nel server dove viene letto un numero a 32 bits dai dati in ingresso e poi viene effettuato un loop in lettura: for(int n = getint(p); n; n--) getint(p); ------------------------------------------- C] crash dei clients tramite mappa invalida ------------------------------------------- Nel Cube engine i giocatori hanno la possibilita' di scegliere una mappa specifica su cui giocare, se nel server c'e' solo un giocatore la mappa verra' cambiata istantaneamente altrimenti si andra' alle votazioni. Quando un client prova a leggere una mappa non valida esso esce riportando il messaggio di errore "while reading map: header malformatted". Quando la mappa viene scelta tutti i clients aggiungono l'estensione .ogz al nome mappa e caricano il file. La grandezza massima del nome della mappa e' di 260 bytes e la funzione che carica il file utilizza uno sprintf() sicuro che tronca la stringa (compreso il .ogz) se viene raggiunto il limite. Dopodiche' il caricamente della mappa non e' controllato per evitare possibili attacchi di directory traversal quindi se un attacker (un giocatore) specifica un nome mappa di circa 260 bytes puo' forzare qualsiasi client che entrera' nel server (a causa del problema del voto spiegato precedentemente che limita la sfruttabilita' di questo bug) a caricare qualsiasi file che non sia una mappa valida e quindi usciranno immediatamente. Come gia' detto l'azione dell'exploit avviene con qualsiasi client che entrera' nel server in quanto il nuovo nome mappa sara' attivo nel server fino al successivo match. ####################################################################### =========== 3) The Code =========== http://aluigi.org/poc/evilcube.zip ####################################################################### ====== 4) Fix ====== No fix. L'autore dice che il motore non e' piu' supportato. #######################################################################