Меры безопасности Linux против выполнения шеллкода - PullRequest
2 голосов
/ 15 сентября 2011

Я изучаю основы компьютерной безопасности и пытаюсь выполнить какой-то шелл-код, который я написал. Я следовал инструкциям, приведенным здесь

http://dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf

http://webcache.googleusercontent.com/search?q=cache:O3uJcNhsksAJ:dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf+own+shellcode&cd=1&hl=nl&ct=clnk&gl=nl

$ cat pause.s
xor %eax,%eax
mov $29,%al     
int $0x80       
$ as -o pause.o pause.s
$ ld -o pause pause.o
ld: warning: cannot find entry symbol _start; defaulting to <<some address here>>
$ ./pause 
^C
$ objdump -d ./pause
pause:     file format elf64-x86_64
Disassembly of section .text:
      08048054 <.text>:
      8048054: 31 c0     xor    %eax,%eax
      8048056: b0 1d     mov    $0x1d,%al
      8048058: cd 80     int    $0x8
$

Поскольку я запустил программу паузы, я просто скопировал вывод objdump в файл c.

test.c:

int main()
{
    char s[] = "\x31\xc0\xb0\x1d\xcd\x80";
    (*(void(*)())s)();
}

Но это порождает ошибку. Теперь это может быть связано только с мерами безопасности Arch Linux (?). Так как я могу заставить это работать?

Ответы [ 2 ]

7 голосов
/ 15 сентября 2011

Страница, в которой находится s, не сопоставлена ​​с разрешениями на выполнение.Поскольку вы используете x86_64, у вас определенно есть поддержка NX в аппаратном обеспечении.По умолчанию в наши дни код и данные располагаются на очень отдельных страницах, а данные не имеют разрешения на выполнение.

Вы можете обойти это с помощью mmap() или mprotect() для выделения или изменения страниц для получения разрешения PROT_EXEC.

0 голосов
/ 26 января 2013

Вы также можете использовать #define для определения своего шелл-кода. Таким образом, препроцессор вставит код непосредственно в основной

  #define SHELLCODE "\x31\xc0\xb0\x1d\xcd\x80"
  int main()
  {
     (*(void(*)())SHELLCODE)();
  }

Более старый стиль написания шеллкода не работает на более новых системах из-за мер безопасности. Вам также, вероятно, придется скомпилировать с отключенной защитой стека:

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

Вот полностью рабочий пример, использующий системный вызов exit, который я тестировал на ядре 3.2.0.3 x86_64:

 #include<stdio.h>

 #define SHELLCODE "\x48\xc7\xc0\x3c\x00\x00\x00\x48\xc7\xc7\xe7\x03\x00\x00\x0f\05"

  main() 
  {
  int (*function)();

   // cast shellcode as a function
   function = (int(*)())SHELLCODE;

   // execute shellcode function
   (int)(*function)();
   return 0;
   }

В шелл-коде используются 64-битные регистры, поэтому он не будет работать на 32-битной машине. Чтобы убедиться, что код работает, вы можете проверить его с помощью strace:

strace shellcode
execve("./shellcode", ["shellcode"], [/* 38 vars */]) = 0
....
munmap(0x7ffff7fd5000, 144436)          = 0
_exit(999)        <---- we passed 999 to exit, our shellcode works! 
...