Asm Referat (RE)
Transkrypt
Asm Referat (RE)
Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Asembler. Wykorzystanie Asemblera w kontekście RE (czyli do czego może przydać się najbardziej abstrakcyjny język programowania) Informacje wstępne (obowiązkowe) - referat na zajęcia z czegoś tam 1. Kto stworzył język asemblera? && Kiedy (w jakich latach) powstał język asemblera? Pierwszym asemblerem był skonstruowany przez Konrada Zuse w 1945 r. układ elektromechaniczny przygotowania taśmy perforowanej z programem dla maszyny Z4 Planfertigungsteil , który umożliwiał wprowadzanie oraz odczyt rozkazów i adresów w sposób zrozumiały dla człowieka. (źródło: wikipedia.pl) 1 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 2. Jaki jest cel Asemblera? - język komunikacji z procesorem - wykorzystanie w kodzie o krytycznej wydajności (real-time systems), software pisany w języku asmeblera jest o wiele szybszy niż ten, pisany w HLL (High-Level-Language) - ma umożliwić działanie kodu bez systemu operacyjnego - bezpośrednia komunikacja ze sprzętem (sterowniki) - wykorzystanie rozkazów procesora niedostępnych w HLL - pisanie wirusów, bootloaderow, kernelow- reverse engineering ? uzyskiwanie nowego kodu i zmiana funkcjonalności programu przy pomocy inżynierii wstecznej - tworzenie oprogramowania o podstawowym znaczeniu dla działania sprzętu komputerowego - program w asemblerze zapewnia bardzo mały rozmiar pliku wynikowego - stwarza możliwość pisania takich programów, których nie da się napisać w innych językach - możliwość pisania nowych języków programowania 3. Jakie języki poprzedzały Asemblera w rozwoju? Języki 1st generacji, czyli języki maszynowe (języki procesorów). Instrukcje zapisywane były w postaci liczb binarnych, np: Przykładowy kod programu: 2 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 111010100000000000001111111111111111100010011101100000000010100000001 Dopiero potem pojawiły się języki 2nd generacji - języki symboliczne, asemblery. Języki niskiego poziomu, pod względem składni tożsame z maszynowymi, z tą różnicą że zamiast liczb używa się tu łatwiejszych do zapamiętania mnemoników. Przykładowy kod programu: {codecitation} jmp ffff:0 mov ax, bx add ax, 1 {/codecitation} 4. Czy język asemblera przetrwa, czy istnieje jego "następca"? - ?programowanie w asemblerze nie zniknie i ma przed sobą świetlaną przyszłość? (cytat) (Why? JMP 2 ; look at point 2 once again) - Następca? Następstwo w kontekście Asemblera może dotyczyć ewentualnie asemblerow (N ASM , TASM , MASM , FASM , 3 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 GASM , ..). NASM (Linux) przykładowy kod(y): {codecitation} section .text global _start _start: mov edx,len mov ecx,msg mov ebx,1 mov eax,4 ; system call number (sys_write, in sys/syscall.h) int 0x80 mov eax,1 ; system call number (sys_exit) int 0x80 ; call kernel section .data msg db 'Hello, world!',0xa ;our dear string len equ $ - msg ;length of our dear string {/codecitation} Istotna różnica między dwoma źródłami ? konwencja wywoływania funkcji w przypadku pierwszego źródła: __fastcall a w przypadku drugim, argumenty odkładane są kolejno (od prawej->do lewej) na stos zgodnie z konwencją __cdecl. W kontekscie RE warto wiedzieć, jaka konwencja towarzyszy danej funkcji podczas wywołania. Jeśli zapomnimy uprzątnąć stosu w przypadku cdecl, system ?nie trafi? w adres powrotu w ramce stosu i program się ?wysypie?. {codecitation} call _syscall ;call kernel add esp,12 ;clean stack (3 arguments * 4) {/codecitation} Dopiero teraz program przeskoczy 3 ? czterobajtowe argumenty funkcji by zgodnie z budową ramki stosu (stack frame) ustawić się na adresie powrotu i wykonac RET ? ?powrót? do miejsca skad będzie kontynuować działanie programu. __fastcall {codecitation} mov edx,len ;message length mov ecx,msg ;message to write 4 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 mov ebx,1 ;file descriptor {/codecitation} __cdecl {codecitation} push dword len ;message length push dword msg ;message to write push dword 1 ;file descriptor {/codecitation} To nie jedyne konwencje stosowane przez programistów. Jeśli interesuje nas napisanie np. patcha do programu i potrzebujemy wiedzieć co nie co o funkcji, warto zajrzeć do przykładowego kodu w debuggerze, wejść w wywołanie funkcji (?trace into?) i zobaczyć jaką instrukcją się ona kończy. Jeśli funkcja kończy się instrukcją RETN to na pewno mamy do czynienia z konwencją __cdecl. (Ewentualnie kompilator Borlanda stosujący konwencję __fastcall również kończy funkcję instrukcją RETN ale odkłada argumenty w kolejności odwrotnej do __cdecl). Będzie nam to potrzebne, jeśli np. będziemy chcieli wkleić w sekcję .rdata fragment naszego kodu napisanego w Asemblerze. MNEMONIKI && Opcode(s): 5 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Mikroprocesory współczesnych komputerów rozumieją tylko jeden język programowania binarny kod maszynowy (ang. binary machine code). W pamięci komputera zapisywane są rozkazy dla procesora w postaci binarnej, czyli przy pomocy bitów. Procesor odczytuje te kody, dekoduje na odpowiednie polecenia i wykonuje operacje - w ten właśnie sposób realizowany jest program. Polecenia binarne mogą wyglądać np. tak: 11010010100010101001010101010111 01010101011110100101111010101110 11101001001011101010101001011110 00011010100111001000101111010011 10100100100010010010111000101010 6 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Czasy programowania komputerów w binarnym kodzie maszynowym bezpowrotnie skończyły się na początku lat 50-tych ubiegłego wieku. Chociaż procesory wciąż rozumieją tylko swój kod binarnych poleceń, to ludzie programują je w językach bardziej zrozumiałych dla siebie. Pierwszym takim językiem był Asembler - binarne kody instrukcji procesora są w nim reprezentowane przez nazwy symboliczne, które odzwierciedlają wykonywaną przez procesor operację. Na przykład zamiast kodu binarnego (po lewej stronie) programista zapisuje symboliczne nazwy operacji (po prawej stronie): 11010010100010101001010101010111 ? MOV AX,va 01010101011110100101111010101110 ? ADD AX,vb 11101001001011101010101001011110 ? MUL vc 00011010100111001000101111010011 ? ADD AX,vd 10100100100010010010111000101010 ? MOV ve,AX 7 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Informacja na temat instrukcji JMP dostepna w I-necie: {codecitation}Opcode JMP CPU: i8086+ Type Of Instruction: User Instruction: JMP address Physical Forms: 0EBh op8 JMP SHORT op8 - short jump. Allows jumping 128 bytes forward or backwards from next instruction. (Limited to same segment) 0E9h op16 JMP NEAR op16 - near jump. Relative jump from next instruction. (Limited to same segment) 0E9h op32 JMP NEAR op32 0FFh mem32 - near jump with address specified in memory. [Incomplete] 8 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Affected Flags: None, unless taskswitching. +++++++++++++++++++++++ Clocks: JMP short: 2 JMP near: 3 JMP far: 5 {/codecitation} Co jest tu interesującego w kontekście znajomości Asemblera i RE? Jeśli w debugerze otworzymy jakiś program do analizy i znajdziemy w nim np. taką instrukcję: 9 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 To widać już, że nawet jeśli nie ma 3rd kolumny to wiemy, ze pod adresem 0040127C w pamięci procesu widnieje instrukcja skoku JMP: 0Ebh. Przyda nam się to potem. Do czego jeszcze przydać się może umiejętność znajdowania wartości opcodes, wiedza na temat budowy ramki stosu w asemblerze albo informacja czym jest wskaźnik do funkcji w środowisku HLL? RE umozliwia ingerencje w działanie programu dzięki znajomości i wykorzystaniu Asemblera. Można zmienić rozkład jazdy programu, kiedy np. uszkodzi mu się w pewnym momencie frame stack i rozkarze ?powrócić? do specjalnie przygotowanego przez nas fragmentu programu w pamięci napisanego przy pomocy Asemblera. Przykład programowego wyjścia z użyciem bezpośredniego wywołania systemowego: {codecitation} /*shellcodetest.c*/ char code[] = "bytecode will go here!"; 10 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 int main(int argc, char **argv) { int (*func)(); // deklaracja wkaźnika na funkcję func = (int (*)()) code; // przypisanie wskaznikowi adresu funkcji (int)(*func)(); // wywolanie funkcji } {/codecitation} Kompilacja: {codecitation} ;exit.asm [SECTION .text] global _start _start: 11 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 xor eax, eax mov al, 1 ;exit is syscall 1 ;exit is syscall 1 xor ebx,ebx ;zero out ebx int 0x80 {/codecitation} Deasemblacja: {codecitation} exiter: file format elf32-i386 Disassembly of section .text: 08048080 <_start>: 8048080: b0 01 mov $0x1,%al 8048082: 31 db xor %ebx,%ebx 8048084: cd 80 int $0x80 {/codecitation} 12 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 !!! b0 01 31 db cd 80 !!! Interesująca nas funkcja ma następującą postać: {codecitation} char code[] = "xb0x01x31xdbxcdx80"; {/codecitation} Można wrzucić na stos funkcji odpowiedni parametr, który spowoduje ?przekierowanie? do podobnego kodu w pamięci, który może mieć dowolną postać i zrobić dla nas dowolne rzeczy zgodne z przywilejami danego użytkownika np. root?a. Każde wywołanie funkcji powoduje utworzenie nowej ramki stosu o następującej budowie (należy pamiętać, że lista uporządkowana jest w kolejności malejących adresów): ? parametry funkcji, ? adres powrotu funkcji, ! ! ! ? wskaźnik ramki, ? ramka procedur obsługi wyjątków, ? lokalnie zadeklarowane zmienne i bufory, ? rejestry zachowane przez funkcję wywołaną. 13 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Co to jest Hexedytor i do czego się może przydać? - program przeznaczony do edycji plików binarnych. Jego nazwa pochodzi od tego, iż zawartość edytowanego pliku jest wyświetlana bajt po bajcie w systemie szestnastkowym. Ale najpierw o diasemblerze. Diasembler (np. IDA) pozwala podobnie jak debuger obejrzeć kod programu w formie instrukcji asemblera. Od debuggera różni się w sumie tym, że nie pozwala na wykonywania programu instrukcja po instrukcji. Po lewej stronie (kolor blue) widać instrukcję załadowaną pod dany adres w pamięci. Nastepnie widoczna jest sama instrukcja, oraz po najechaniu na loc_ troche informacji o miejscu w 14 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 programie do którego program skoczy jeśli spełni warunek. O co chodzi z warunkami o tym na końcu. Wiedza na temat asemblera to wiedza na temat komputera. Wiemy też zatem, ze instrukcje asemblera to po prostu bajty załadowane do pamięci z pliku. Wiemy też, że możemy podejrzeć ten plik w Hexedytorze. Wiemy zatem, że możemy zmodyfikować w tym edytotrze kod i dostosować go do naszych potrzeb. Do tego min przydaje się Asembler. Poszukam podświetlonej instrukcji w pliku wykonywalnym programu. Jak może wyglądać? Na start sprawdzam opcode dla instrukcji JZ: {codecitation} 74 cb JZ rel8 7+m,3 Jump short if 0 (ZF=1) {/codecitation} I szukam? 15 / 16 Asm Referat (RE) Wpisany przez Administrator niedziela, 05 września 2010 18:48 Znając ramki wpisać opcodes EB i zamiast mogę JZedytować zrobi kodu mi się kod bezwarunkowy i zmienićwcałkiem JMP. działanie programu. Mogę zamiast 74 Charakterystyczne elementy przydatne analizie: Prolog stosu: Testy, skoki : Odkladanie elementow na stos / calls P rzygotowanie skoku do oep (Original Entry Point) w przypadku kompresji np. UPX {codecitation} 005533B0 75 JNZ SHORT PROGRAM.005533BA B8 MOV EAX,1 005533B7 C2 0C00 RETN 0C 005533B2 68 E405000 PUSH PROGRAM.0050F0E4 ;kodzić original oep 005533BA RETN {/codecitation} O w kontekście co chodziło Asemblera? z01000000 tymi warunkami przy skokach i= dlaczego jest to kolejna rzecz warta zauważenia Rejestr flag procesora Rejestr Ustawienie operacji Budowa zbudowany. nazywanych flag arytmetycznej, rejestru wartości statusu flagami danej rejestr porównania, zależy flagi lub statusu znacznikami, zależy od modelu niekiedy -np. wewnętrzny od programowego, opisujących trybu może pracy być rejestr także iNIC.. procesora, kontrolujących w według procesorach, ustawiana którego wyniku zstan składająca dany ostatnio procesora. procesor programu. wykonanej się zwjest Przykładowe flagi rejestru statusu Z -(lub wynik operacji był zerem jeśli bit S N) -ostatniej wynik ostatniej operacji był dodatni (S) lub ujemny (N, od ang. negative) bitów C -powrót (więc przykładowo przeniesienie, do 254 aexecu więc dodamy wynik 5) ostatniej operacji jest większy niż dostępnych ? V nastąpiło przepełnienie rejestru nieparzysta P flaga pokazująca czy liczba bitów w wyniku ostatniej operacji jest parzysta czy (źródło wikipedia.pl) Z wyniku wykonywania porównań, numerowi miejsca flagami ostatniej w zaszyfrowanemu programie np. skoków. numerów operacji o to, gdzie że To licencyjnych programu instrukcja min poinformujesz w one je JNZ rejestr zapal determinują. programów. będzie usera zero zero flag miała o1koder pozytywnej Jeśli Flagi nie Jeśli sens zostanie numer te zero ustawiane ilampki nie weryfikacji. wpisany flag zostanie ?zapalony? == są 1 przez często wówczas opuszczona ?iliczba usera to wnie. są przypadku równy min jeśli do Podsumowanie ? czyli o czym było: 1. podstawowe, oswojenie miały Diasembler jakąś zparzystości, wartość Asemblerem. źródlo i?08 Debugger praktyczną. wiedzy ? Nie na wspomniana trzeba temat umieć języka IDA doskonale asemblera, oraz debugger znacznie np. w Asemblerze, OllyDbg ułatwiają - poziomu rozumienie narzędzia żeby te programy i warunki 2. Rejestr flag koder musi wiedzieć co się kiedy te się świecą lub 3. gdzie rejestru Elementy ustawić eax, charakterystyczne być tzw. może breakpoint, w którymś żeby kodu zwiedza rejestrów np. w analizie nie zgubić zdoła ?flag. jakiejś odczytać lub wartości Reverse kod licencyjny zwróconej Engineer programu. przez musi funkcję wiedzieć do 4. umieszczania program Shellcode i chodzi wykonać && ich ramka w własny pamięci stosu kod procesu ? w znajomość kontekście oraz znajomość asemblera innego użytkownika ramki do pisania stosu własnych np. pozwala administratora np. funkcji zkompromitować iskocz systemu. 5. jeśli Konwencje zprocesora, funkcji wywołania się nie funkcji uda? ? właśnie niezbędna szkoda, koderowi że ASM?a przy pisaniu patcha, co 6. nawet Hexedytor cały ceremoniał ? wrzucasz rejestracji. exec?a iNo Save masz as.. go jak idzieje po na sprawie. łopatelni, jeśli wiesz gdzie co to ominiesz Bibliografia: h ttp://en.wikipedia.org/wiki/X86_calling_conventions#Caller_clean-up http://asm.sourceforge.net/intro/hello.html http://home.elka.pw.edu.pl/~mnazarew/downloads/ochrona-stosu.html http://edu.i-lo.tarnow.pl/inf/utils/001_2008/0105.php http://www.vividmachines.com/shellcode/shellcode.html http://pdos.csail.mit.edu/6.828/2005/readings/i386/Jcc.htm 16 / 16