[01] Za pomoc� narz�dzia file uzyskujemy podstawowe informacje o analizowanym pliku
# file netc
netc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, statically linked, stripped
Jak wida�, analizowany plik zosta� skompilowany statycznie i przeszed� proces strippingu.
[02] Wyszukujemy w pliku interesuj�ce �a�cuchy znak�w
# strings -a netc > strings.out
Analizuj�c otrzyman� zawarto�� pliku odnajdziemy nast�puj�ce informacje, kt�re b�d� pomocne w dalszych dzia�aniach:
Innym sposobem na odszukanie interesuj�cych �a�cuch�w znak�w mo�e by� przeszukanie zawarto�ci
wybranych sekcji analizowanego pliku. Na przyk�ad informacje o systemie i wersji kompilatora, kt�ra
zosta�a u�yta do kompilacji pliku, standardowo przechowywane s� w sekcji .comment. Zawarto�� wskazanej sekcji pliku mo�emy odczyta� stosuj�c polecenie: # objdump -j .comment -s nazwa_programu > comment.out lub # objdump -h nazwa_programu > sections.out i podejrzenie dowolnym edytorem lub przegl�dark� zawarto�ci pliku pod wskazanym offsetem. |
[03] Wyszukujemy i pobieramy z Internetu biblioteki, kt�re mog�y by� u�yte w trakcie kompilacji
Z wyniku dzia�ania polecenia strings w kroku [02] wiemy, �e plik zosta� skompilowany w systemie Mandrake Linux 10.0
przy zastosowaniu kompilatora GCC 3.3.2. W naszym przypadku ograniczymy si� do pr�by odtworzenia
symboli zwi�zanych z bibliotek� libc, pochodz�c� z systemu Mandrake 10.0. Ze wzgl�du na przeznaczenie biblioteki libc
mo�na z du�ym prawdopodobie�stwem za�o�y� jej wykorzystanie w analizowanym pliku. Inn� bibliotek�, kt�r� r�wnie�
mo�na by�oby standardowo wykorzysta� w procesie odtwarzania tablicy symboli, jest biblioteka libgcc.a.
My jednak ograniczymy si� wy��cznie do biblioteki libc, poniewa� elementy biblioteki libgcc.a rozpoznamy w dalszej
cz�ci, poprzez por�wnanie z przyk�adowo skompilowanym programem.
Bibliotek� libc.a zapisujemy w katalogu ~/analysis/libc_components/
Co zrobi�, je�li nie posiadamy informacji, kt�re mog�yby nam pom�c w ustaleniu wersji bibliotek zastosowanych w trakcie kompilacji? W tej sytuacji mo�na pobra� kilka r�nych wersji bibliotek nawet dla kilku r�nych dystrybucji systemu, wykona� poni�sze kroki procesu odtwarzania tablicy symboli oraz oceni� otrzymane wyniki pod wzgl�dem skuteczno�ci i ilo�ci trafie�. |
[04] Rozpakowujemy obiekty biblioteki
# ar x libc.a
[05] Sprawdzamy, czy w analizowanym programie zawarty jest kod poszczeg�lnych obiekt�w biblioteki
# search_static netc ~/analysis/libc_components > obj_file
W tym kroku nale�y r�wnie� zwr�ci� uwag� na kolizje, kt�re mog�y si� pojawi� w trakcie dokonanej weryfikacji.
Wykryte kolizje znajduj� si� w ko�cowej cz�ci pliku obj_file. Jakie znaczenie
praktyczne i jaki wp�yw na analiz� maj� kolizje? Takie, �e bez szczeg�owej analizy kodu funkcji, dla kt�rych
wyst�pi�y kolizje nie daje si� jednoznacznie okre�li�, kt�ra z funkcji w rzeczywisto�ci zosta�a w programie
zastosowana.
Przyk�ad wykrytej kolizji:
# 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] Generujemy list� odnalezionych odniesie� symbolicznych z poszczeg�lnych obiekt�w biblioteki
# gensymbols obj_file > symbols_db
Wynikiem dzia�ania skryptu jest lista symboli wraz z adresami, pod kt�rymi mo�na znale�� ich kod.
[07] Przeprowadzamy dessassemblacj� analizowanego programu
# gendump netc > out1
[08] Usuwamy kod odnalezionych funkcji biblioteki z pliku out1
# decomp_strip obj_file < out1 > out2
[09] Dla u�atwienia analizy dodajemy nazwy odnalezionych funkcji w miejsca ich wywo�a�
# decomp_insert_symbols symbols_db < out2 > out3
[10] Dla zwi�kszenia czytelno�ci kodu w miejsca odniesie� do �a�cuch�w znak�w wstawimy ich tre��
# decomp_xref_data netc < out3 > out4
Do odtworzenia zawarto�ci tablicy symboli mo�na r�wnie� zastosowa� narz�dzia z pakietu fenris.
Kolejne kroki: [a] Otwieramy do edycji skrypt getfprints [a] W parametrze TRYLIBS wpisujemy �cie�ki oraz nazwy bibliotek, z kt�rych chcemy utworzy� baz� sygnatur # getfprints [b] Zmieniamy nazw� pliku wynikowego na domy�ln� nazw� pliku sygnatur # mv NEW-fnprints.dat fnprints.dat [c] Wykorzystuj�c program dress odtwarzamy usuni�te symbole # dress -F ./fnprints.dat nazwa_programu > lista_odtworzonych symboli lub # dress -F ./fnprints.dat nazwa_programu nazwa_programu_z_dodana_lista_symboli |
Je�eli znana jest wersja kompilatora zastosowanego do kompilacji analizowanego programu (a my j� znamy) lub
mo�emy si� domy�la� tej informacji, mo�na podj�� pr�b� okre�lenia lokalizacji funkcji dodanych przez kompilator
(podobny efekt powinni�my uzyska� wykorzystuj�c bibliotek� libgcc.a w procesie odtwarzania tablicy symboli).
Do przeprowadzenia tego dzia�ania wykorzystamy por�wnanie przyk�adowego programu skompilowanego tym samym
kompilatorem co analizowany plik.
[11] Tworzymy przyk�adowy program sample.c
int main(int argc, char **argv[])
{
return 0;
}
[12] Kompilujemy przyk�adowy program
# gcc —static —o sample sample.c
[13] Por�wnujemy elementy skompilowanego programu z kodem analizowanego pliku - out4
[14] Por�wnuj�c budow� funkcji _start() z przyk�adowego programu sample z kodem tej funkcji
odnalezionej w analizowanym pliku ustalamy lokalizacj� funkcji 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
[15] Ustalamy funkcje u�ytkownika (dla �cis�o�ci - funkcje, kt�re nie zosta�y rozpoznane jako obiekty biblioteki)
# grep 'call 0x' out4 | grep -v '<' > user_f.out
[16] Poniewa� w analizowanym kodzie wiele wywo�ywanych funkcji si� powtarza, spr�bujemy uzyska� wy��cznie
unikalne adresy funkcji
# 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 si� okazuje, cz�� z uzyskanych adres�w mo�e nie istnie� w naszym kodzie out4.
Ich brak wynika z istnienia kolizji sygnatur funkcji, kt�re w kroku [8] zosta�y usuni�te.
[17] W kolejnych krokach, zaczynaj�c od funkcji main() powinni�my dokona� analizy przep�ywu
kontroli pomi�dzy funkcjami u�ytkownika oraz realizowanych przez nich dzia�a�. Przechodz�c ten krok
powinni�my uzyska� odpowied� na pytania typu: jak� rol� pe�ni� analizowany obiekt w systemie oraz jakie
mechanizmy wykorzystuje. Do w�a�ciwej interpretacji dzia�a� realizowanych przez poszczeg�lne funkcje
wymagana jest znajomo�� j�zyka Assembler prznajmniej w stopniu podstawowym.
Funkcja main()
0x0804812d
0x080481bd
0x08048204
0x080482a5
0x08048303
0x0804834b
0x080483b5
0x080483fd
0x080486b8
0x080488ab
0x08048951
0x080489b3
0x08048a3b
0x08048d9d
0x08049235
0x08049311
0x0804950b