Сборка версии кода C для запуска оболочки - PullRequest
0 голосов
/ 09 ноября 2018

При назначении переполнения буфера я получил файл C (call_shellcode.c), который содержит версию сборки следующего кода C, который выполняется для открытия оболочки:

#include <stdio.h>
#include <unistd.h>
int main(){
    char *name[2];
    name[0] = "/bin/sh";
    name[1] = NULL;
    execve(name[0], name, NULL);
}

Код в файле call_shellcode.c:

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

const char code[] =
  "\x31\xc0"             /* xorl    %eax,%eax              */
  "\x50"                 /* pushl   %eax                   */
  "\x68""//sh"           /* pushl   $0x68732f2f            */
  "\x68""/bin"           /* pushl   $0x6e69622f            */
  "\x89\xe3"             /* movl    %esp,%ebx              */
  "\x50"                 /* pushl   %eax                   */
  "\x53"                 /* pushl   %ebx                   */
  "\x89\xe1"             /* movl    %esp,%ecx              */
  "\x99"                 /* cdql                           */
  "\xb0\x0b"             /* movb    $0x0b,%al              */
  "\xcd\x80"             /* int     $0x80                  */
;

int main(int argc, char **argv)
{
   char buf[sizeof(code)];
   strcpy(buf, code);
   ((void(*)( ))buf)( );
} 

Я скомпилировал это командой:

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

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

1 Ответ

0 голосов
/ 09 ноября 2018

Это 32-битный машинный код x86, который использует 32-битный int 0x80 ABI.

Предполагая, что вы работаете в обычном дистрибутиве Linux x86-64, вы скомпилировали его в 64-битный исполняемый файл, поэтомуэти push imm32 инструкции декодируются как pushq, а также RSP находится за пределами младших 32 бит виртуального адресного пространства.Таким образом, int 0x80 вернется с eax=-EFAULT, и выполнение продолжится в мусор, что приведет к segfault.

Используйте strace или GDB, чтобы увидеть это (хотя strace неправильно декодирует int 0x80 в 64-битной версииисполняемые файлы, он будет правильно отображать возвращаемое значение).См. Что произойдет, если вы используете 32-битный int 0x80 Linux ABI в 64-битном коде?

Используйте gcc -m32 -z execstack .. для создания 32-битного исполняемого файла, гдеэтот машинный код будет работать.

...