
[ Home | Liste | F.A.Q. |
Risorse | Cerca... ]
Archivio: Settembre 2004 ml@sikurezza.org Soggetto: [ml] FreeBSD Kernel buffer overflow Mittente: gerarra Data: Fri, 17 Sep 2004 00:02:56 +0200 (CEST)
Traduzione dell'email che ho spedito a bugtraq
Versioni: tutte le versioni di FreeBSD (4.x, 5.x/6.0)
Arch: x86
Data: 16/09/2004
N.B: il codice e la discussione si riferiscono alla CURRENT-6.0, quindi
(soprattutto per quanto
concerne 4.x) il codice potrebbe cambiare (ma comunque il bug e' presente
in tutte le
versioni). Essendo coinvolti nella discussione meccanismi delle architetture
i386, alcune
parti saranno ridotte all'osso per non appesantire la trattazione.
E' stato trovato un buffer overflow nella funzione syscall() -> i386/i386/trap.c
del source
tree ufficiale di freebsd.
Per gestire il meccanismo di chiamata a syscall, viene fornito un particolare
interrupt
software (MI), esattamente l'interrupt 128 (0x80). L'interrupt handler associato
(da un trap
gate) si trova in i386/i386/exception.s, precisamente la funzione int0x80_syscall(),
alla
fine della quale la funzione syscall() e' richiamata.
Fra le altre cose, syscall() scrive gli argomenti passati alla syscall in
un chunk di memoria
a che si trova a kernel space.
Il codice incaricato di fare questo e' il seguente:
void
syscall(frame)
struct trapframe frame;
{
caddr_t params;
struct sysent *callp;
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_eflags;
u_int sticks;
int error;
int narg;
int args[8];
u_int code;
...
narg = callp->sy_narg & SYF_ARGMASK; (<- unico check)
if (params != NULL && narg != 0)
error = copyin(params, (caddr_t)args,
(u_int)(narg * sizeof(int)));
else
error = 0;
...
e:
> grep SYF_ARGMASK /usr/src/sys/sys/sysent.h
#define SYF_ARGMASK 0x0000FFFF
E' abbastanza ovvio che l'ammontare massimo di memoria selezionabile sia
di molto piu' grande
rispetto i miseri (8* sizeof(int)) bytes messi a disposizione per il chunk,
quindi e' possibile
un saved eip overwriting (syscall() e' chiamata tramite la call) o un interessante
pointer
corruptuin del puntatore struct proc *p;
E' exploitable, ma l'unico modo che ho trovato e' stato quello di linkare
una nuova syscall
al kernel e per fare questo bisogna gia' essere root; Essendo che non ho
molto tempo per
lavorare sulla vulnerabilita' spero che qualcun altro possa trovare un vero
modo di exploitare
il bug (che pertanto rimane di bassissimo impatto, riguardo codice maligno).
Non e' da
sottovalutare pero il lecito pericolo di crash al kernel.
Una patch potenziale potrebbe essere allocare memoria dinamicamente per
il puntatore args,
ma questa soluzione non favorisce la performance; un'altra potrebbe essere
di creare un check
piu' forte, ma non si scorgono modi per favorire la flessibilita' (in questo
modo).
Potete scaricare il proof of concept (per tutte le versioni di freebsd)
su http://www.gufi.org/~rookie/poc.tar.gz
saluti
rookie
P.S: per testare il bug, dopo aver creato e linkato il kld, lanciate 'make
test' dopodiche' l'eseguibile ./poc sara' pronto
[ Home | Liste | F.A.Q. |
Risorse | Cerca... ]
www.sikurezza.org - Italian Security Mailing List
(c) 1999-2005