Приведение строки символов как функции

Я пытаюсь научиться выполнять шелл-код изнутри программы, но у меня не получается запустить даже самый простой код. Следующий код просто должен выйти из терминала при его запуске:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80";

int main() {
int (*func)();
func = (int (*)())exitcode;
(int)(*func)();
return 0;
}

Но все, что я получаю, — это ошибка. GDB говорит, что это происходит, когда программа обращается к ячейке памяти с кодом выхода [at (int) (* func) (); ], но я не уверен, почему это вызывает проблемы. Я использую 64-битную ОС Linux Mint. Любая помощь с благодарностью.

5

Решение

Современные операционные системы используют защиту памяти. Страницы памяти имеют права доступа, как и файлы: читаемые, записываемые, исполняемые. Ваш сегмент данных вашей программы, как правило, находится на неисполняемой странице, и попытка его выполнения приводит к segfault.

Если вы хотите выполнить динамически записанный двоичный код из вашей программы на Linux, вы сначала должны отобразить страницу, используя mmap() что вы можете написать, затем разместить свой код там, а затем изменить его на только для чтения, исполняемый файл с помощью mprotect(), Тогда вы можете прыгнуть туда.

Вы могли бы, например, прочитайте эту статью для деталей.

РЕДАКТИРОВАТЬЕсли речь идет о нарушениях безопасности, обратите внимание, что в наши дни стек обычно тоже не исполняется … так что все эти старые «учебники по взлому» больше не будут работать. Если вы заинтересованы в новых методах, читайте о возвратно-ориентированное программирование.

6

Другие решения

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

#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80";

int main(int argc, char **argv)
{
void *buf;

/* copy code to executable buffer */
buf = mmap (0,sizeof(exitcode),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, exitcode, sizeof(code));

/* run code */
int i = ((int (*) (void))buf)();
printf("OK. returned: %d", i);
return 0;
}
4

Ваш шеллкод:

mov    $0x1,%al
xor    %ebx,%ebx
int    $0x80

Есть две проблемы:

  1. Syscall 0x1 — это sys_write на 64-битной (но на 32-битной — sys_exit)
  2. Вы должны назначить% rax, а не% al. % rax будет содержать остатки в старших битах.
0

У меня была эта проблема, и я много искал, чтобы ее решить.

Вы должны использовать этот код для компиляции кода C (чтобы отключить защиту стека и сделать его исполняемым):

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

Проверено в Кали 32/64 бит. Нет больше сегфо

Удачи

0
По вопросам рекламы [email protected]