Statick� anal�za spustiteln�ho k�du ELF – tutorial

Tento dokument je praktickou uk�zkou popsanou v �l�nku Reverse Engeneering spustiteln�ho k�du ELF v anal�ze napaden� (Hakin9 01/2005).

Analyzovan� objekt: netc. P�ed za��tkem anal�zy souboru je t�eba ho zkop�rovat do domovsk�ho adres��e.

P��prava

Samoz�ejm� Hakin9 Live obsahuje v�echny pot�ebn� n�stroje pro proveden� anal�zy. Pokud ho ale nevyu�ijeme, pot�ebujeme pro proveden� v�ech operac� syst�m Linux a n�sleduj�c� programy:

Programy z bal��ku binutils Skripty a programy z bal��ku fenris Dal�� n�stroje:

Po��te�n� rozpozn�n� objektu

[01] Za pomoci n�stroje file z�sk�me z�kladn� informace o analyzovan�m souboru

# file netc
netc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, statically linked, stripped

Jak je vid�t, analyzovan� soubor byl zkompilovan� staticky a pro�el procesem strippingu.

[02] Hled�me v souboru zaj�mav� �et�zce znak�

# strings -a netc > strings.out

P�i anal�ze obsahu souboru najdeme n�sleduj�c� informace, kter� n�m budou pot�ebn� p�i dal�� pr�ci:

Jin� zp�sob pro nalezen� zaj�mav�ch �et�zc� znak� m��e b�t prohled�n� obsahu vybran�ch sekc� analyzovan�ho souboru. Nap��klad informace o syst�mu a verzi kompil�toru, kter� byla po�ita pro kompilaci souboru, se standardn� zapisuje do sekce .comment.

Obsah t�to sekce souboru m��eme p�e��st pomoc� p��kazu:

# objdump -j .comment -s n�zev_programu > comment.out

lub

# objdump -h n�zev_programu > sections.out

a n�hled libovoln�m editorem nebo prohl��e�em obsahu soubor�, umo��uj�c� skok na dan� offset.

Pokusy otev�en� tabulky symbol�

[03] Vyhled�me a st�hneme z Internetu knihovny, kter� mohly b�t pou�it� b�hem kompilace

Z v�sledku p��kazu strings v kroku [02] v�me, �e soubor byl zkompilovan� v syst�mu Mandrake Linux 10.0 s pou�it�m kompil�toru GCC 3.3.2. V na�em p��pad� se omez�me pouze na vytvo�en� symbol� souvisej�c�ch s knihovnou libc, poch�zej�c� ze syst�mu Mandrake 10.0. S ohledem na ur�en� knihovny libc m��eme ji s velkou pravd�podobnost� ur�it za pou�itou v analyzovan�m souboru. Jin� knihovna, kter� tak� m��e b�t standardn� vyu�ita v procesu vytv��en� tabulky symbol�, je knihovna libgcc.a. My se ale budeme zab�vat v�lu�n� knihovnou libc, proto�e elementy knihovny libgcc.a rozpozn�me v dal�� ��sti, porovn�n�m s p��kladov�m zkompilovan�m programem.

Knihovnu libc.a ulo��me do adres��e ~/analysis/libc_components/

Co d�lat, kdy� nem�me informace, kter� by n�m mohly pomoci p�i zji�t�n� verze knihoven vyu�it�ch b�hem kompilace? V t�to situaci m��eme pou��t n�kolik r�zn�ch verz� knihoven i pro n�kolik r�zn�ch distribuc� syst�mu, prov�st n��e uveden� kroky procesu vytv��en� tabulky symbol� a zhodnotit z�skan� v�sledky .

[04] Rozpakujeme objekty knihovny

# ar x libc.a

[05] Kontrolujeme, zda analyzovan� program obsahuje k�d jednotliv�ch objektu knihovny

# search_static netc ~/analysis/libc_components > obj_file

V tomto kroku je t�eba si v�imnout koliz�, kter� by se mohly objevit b�hem prov�d�n� kontroly. Nalezen� kolize se nach�zej� v koncov� ��sti souboru obj_file. Jak� praktick� v�znam a jak� vliv maj� kolize na anal�zu? Bez anal�zy k�d� jednotliv�ch funkc�, pro kter� kolize nastaly, se ned� jednozna�n� ��ct, kter� z funkc� ve skute�nosti byla v programu vyu�ita. P��klad odhalen� kolize:

# Possible conflict below requiring manual resolution:
# ----------------------------------------------------
# /analysis/libc_components/getsrvbynm.o - match at 0x08057580 (0x000000ea bytes)
# /analysis/libc_components/getsrvbypt.o - match at 0x08057580 (0x000000ea bytes)

[06] Generujeme seznam nalezen�ch symbolick�ch odkaz� z jednotliv�ch objekt� knihovny

# gensymbols obj_file > symbols_db

V�sledkem �innosti skriptu je seznam symbol� sou�asn� s adresami, na kter�ch m��eme naj�t jejich k�d.

[07] Disasemblujeme analyzovan� program

# gendump netc > out1

[08] Odstran�me k�d nalezen�ch funkc� knihovny ze souboru out1

# decomp_strip obj_file < out1 > out2

[09] Abychom si anal�zu usnadnili, p�id�v�me n�zvy hledan�ch funkc� k m�stum, ze kter�ch byly vyvol�ny.

# decomp_insert_symbols symbols_db < out2 > out3

[10] Pro zv�t�en� �itelnosti k�du v m�stech odkaz� na �et�zce znak� vlo��me jejich obsah

# decomp_xref_data netc < out3 > out4

Pro vytvo�en� obsahu tabulky symbol� m��eme tak� vyu��t n�stroje z bal��kufenris.

Dal�� kroky:

[a] Otev�eme skript pro editaci getfprints
[b] Do parametru TRYLIBS zap��eme cesty nebo jm�na knihoven, ze kter�ch chceme vytvo�it datab�zi signatur

# getfprints

[c] Zm�n�me jm�no v�sledn�ho souboru na libovoln� jm�no souboru signatur

# mv NEW-fnprints.dat fnprints.dat

[d] Pou�ijeme program dress k vytvo�en� odstran�n�ch symbol�

# dress -F ./fnprints.dat jmeno_programu > seznam_vytvo�en�ch symbol�
nebo
# dress -F ./fnprints.dat jmeno_programu jmeno_programu_s_pridanym_seznamem_symbolu

Zji��ov�n� funkc� p�idan�ch kompil�torem

Pokud je zn�ma verze kompil�toru pou�it�ho pro kompilaci analyzovan�ho programu (a my ji zn�me) nebo si tuto informaci m��eme domyslet, m��eme ud�lat zkou�ku zji�t�n� lokalizace funkc� dodan�ch kompil�torem (podobn� efekt by chom m�li z�skat vyu�it�m knihovny libgcc.a v procesu vytv��en� tabukly symbol�). Pro proveden� t�to �innosti vyu�ijeme porovn�n� p��kladov�ho programu zkompilovan�ho stejn�m kompil�torem jako analyzovan� soubor.

[11] Vytv���me uk�zkov� program sample.c

int main(int argc, char **argv[])
{
return 0;
}

[12] Kompilujeme p��kladov� program

# gcc -static -o sample sample.c

[13] Porovn�v�me elementy zkompilovan�ho programu s k�dem analyzovan�ho souboru – out4

Porovn�n�m se povedlo ur�it adresy n�sleduj�c�ch funkc�:

Funkce _start() - Adresa = 08048100


Funkce call_gmon_start() - Adresa = 08048124


Funkce __do_global_dtors_aux() - Adresa = 08048150


Funkce frame_dummy() - Adresa = 080481b0


Adresu funkce _start() z�sk�me tak� p�e�ten�m obsahu entrypointu hlavi�ky ELF


Zji�t�n� lokalizace funkce main()

[14] Porovn�n�m struktury funkce _start() z p��kladov�ho programu sample s k�dem t�to funkce nalezen� v analyzovan�m souboru nal�z�me lokaci funkce main()

08048100: xor %ebp,%ebp
08048102: pop %esi
08048103: mov %esp,%ecx
08048105: and $0xfffffff0,%esp
08048108: push %eax
08048109: push %esp
0804810a: push %edx
0804810b: push $0x804aa90
08048110: push $0x804aa30
08048115: push %ecx
08048116: push %esi
08048117: push $0x804994f
0804811c: call 0x0804a3b0 <__libc_start_main>
08048121: hlt

Zji�t�n� u�ivatelsk�ch funkc�

[15] Zji��ujeme funkce u�ivatele (pro p�esnost -- funkce, kter� nebyly rozpozn�ny jako objekty knihovny)

# grep 'call 0x' out4 | grep -v '<' > user_f.out

[16] Proto�e se v analyzovan�m k�du mnoho volan�ch funkc� opakuje, pokus�me se z�skat pouze unik�tn� adresy funkc�

# grep 'call 0x' out4 | grep -v '<' | awk '{print $3}' | sort -u

0x0804812d
0x080481bd
0x08048204
0x080482a5
0x08048303
0x0804834b
0x080483b5
0x080483fd
0x080486b8
0x080488ab
0x08048951
0x080489b3
0x08048a3b
0x08048d9d
0x08049235
0x08049311
0x0804950b
0x0804aed0
0x0804bf70
0x0804bf90
0x08057370
0x08057580

Jak je vid�t, ��st z�skan�ch adres v na�em k�du b�t nemus�out4. Jejich nep��tomnost vypl�v� z existence koliz� signat�r funkc�, kter� v kroku [8] byly odstran�ny.

Samotn� anal�za �innosti programu

[17] V dal��ch kroc�ch, za��naj�c od funkce main() mus�me prov�st anal�zu p�ed�v�n� kontroly mezi funkcemi u�ivatele a jimi realizovan�ch �innost�. V tomto kroku mus�me z�skat odpov�di na ot�zky typu: jakou �lohu plnil analyzovan� objekt v syst�mu a jak� mechanizmy vyu��v�. Pro samotnou interpretaci �innost� realizovan�ch jednotliv�mi funkcemi se vy�aduje znalost jazyka Assembler, minim�ln� na z�kladn� �rovni.

Funkce main()
0x0804812d
0x080481bd
0x08048204
0x080482a5
0x08048303
0x0804834b
0x080483b5
0x080483fd
0x080486b8
0x080488ab
0x08048951
0x080489b3
0x08048a3b
0x08048d9d
0x08049235
0x08049311
0x0804950b