Переполнение буфера в шеллкоде -SegFault

Я пытаюсь запустить этот шеллкод, но у меня постоянно возникает ошибка сегментации

/* call_shellcode.c */
/*A program that creates a file containing code for launching shell*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char code[] =
   "\x31\xc0" /* Line 1: xorl %eax,%eax */
   "\x50" /* Line 2: pushl %eax */
   "\x68""//sh" /* Line 3: pushl $0x68732f2f */
   "\x68""/bin" /* Line 4: pushl $0x6e69622f */
   "\x89\xe3" /* Line 5: movl %esp,%ebx */
   "\x50" /* Line 6: pushl %eax */
   "\x53" /* Line 7: pushl %ebx */
   "\x89\xe1" /* Line 8: movl %esp,%ecx */
   "\x99" /* Line 9: cdq */
   "\xb0\x0b" /* Line 10: movb $0x0b,%al */
   "\xcd\x80" /* Line 11: int $0x80 */
   ;
int main(int argc, char **argv)
{
   char buf[sizeof(code)];
   strcpy(buf, code);
   ((void(*)( ))buf)( );
}

Я компилирую это с помощью:

 gcc -z execstack -o call_shellcode call_shellcode.c

а также

 gcc -fno-stack-protector -z execstack -o call_shellcode call_shellcode.c

Но я продолжаю получать ошибки сегментации

Кроме того, я использую 64-битную систему Linux (Ubuntu)

3 ответа

Решение

Вы используете 32-битный ассемблерный код в системе x86-64. Итак, это ваша проблема, вы должны создать свой шелл-код для систем x86-64.

Например

  400078:   48 31 c0                xor    rax,rax
  40007b:   48 bf 2f 2f 62 69 6e    movabs rdi,0x68732f6e69622f2f
  400082:   2f 73 68 
  400085:   48 31 f6                xor    rsi,rsi
  400088:   56                      push   rsi
  400089:   57                      push   rdi
  40008a:   48 89 e7                mov    rdi,rsp
  40008d:   48 31 d2                xor    rdx,rdx
  400090:   b0 3b                   mov    al,0x3b
  400092:   0f 05                   syscall 

Одно из главных отличий в 32-битной сборке - использование системных вызовов. В этой ссылке Linux Syscalls x86-64 вы можете увидеть, какие регистры вам нужны для вызова sys_execve

int execve (const char * filename, char * const argv [], char * const envp []);

  • const char * имя файла -> rdi
  • char * const argv [] -> rsi
  • char * const envp [] -> rdx

Например

  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>

  const char code[] = "\x48\x31\xc0\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\x31\xf6\x56\x57\x48\x89\xe7\x48\x31\xd2\xb0\x3b\x0f\x05";
  int main(int argc, char **argv)
  {
       char buf[sizeof(code)];
       strcpy(buf, code);
       ((void(*)( ))buf)( );
  }

Компиляция и тестирование.

$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
$ ./shellcode 
$ uname -a
 Linux foobar 4.4.0-97-generic #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

code не имеет завершающего нулевого байта, поэтому вы не можете использовать strcpy() скопировать это. использование memcpy(),

memcpy(buf, code, sizeof(code));

Как упоминалось в комментарии, у вас есть шелл-код для 32-битного Linux, но вы пытаетесь запустить его в 64-битной системе. Это, вероятно, объясняет ошибку после исправления.

Вы забываете -m32флаг для компиляции 32-битного двоичного файла в 64-битной системе. Похоже, это то, что вам нужно:

      gcc -m32 -z execstack -o call_shellcode call_shellcode.c

Чтобы иметь возможность компилировать 32-битные двоичные файлы в 64-битной системе, вам нужны доступные 32-битные библиотеки. В системах на базе Ubuntu вы можете установить их через:

      sudo apt-get install gcc-multilib

См.: https://www.homeworkforyou.com/static_media/uploadedfiles/bufoverflow.pdf .

Другие вопросы по тегам