Сегфолт шеллкод в главном C

Вопрос или проблема

Я пытаюсь создать главный файл вот так:

char main[] = "\xeb\x0d\x6a\x01\x58\x48\x89\xc7\x5e\x6a\x0c\x5a\x0f\x05\xff\xe8\xee\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x57\x6f\x72\x6c\x64\x21"; // опкод для Hello world в asm

Я скомпилировал свой код с помощью:

$ gcc -g3 -o shellcode shellcode.c 

Но я всегда получаю Segmentation fault (core dumped)

Используя GDB, я вижу, что первая инструкция выполняется правильно, но следующие шаги – нет.

pwndbg> b * main
Точка останова 1 на 0x4020
pwndbg> r
────────────────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]─────────────────────────────────────────────────────
 ► 0x555555558020 <main>         jmp    main+15                     <main+15>
    ↓
   0x55555555802f <main+15>      call   main+2                      <main+2>

   0x555555558034 <main+20>      insb   byte ptr [rdi], dx
   0x555555558037 <main+23>      insb   byte ptr [rdi], dx
   0x555555558038 <main+24>      outsd  dx, dword ptr [rsi]
   0x555555558039 <main+25>      sub    al, 0x57
   0x55555555803b <main+27>      outsd  dx, dword ptr [rsi]
   0x55555555803c <main+28>      jb     0x5555555580aa              <0x5555555580aa>

   0x55555555803e <main+30>      and    dword ptr fs:[rax], eax
   0x555555558041 <completed>    add    byte ptr [rax], al
   0x555555558043                add    byte ptr [rax], al
pwndbg> disass
Сброс кода ассемблера для функции main:
=> 0x0000555555558020 <+0>:     jmp    0x55555555802f <main+15>
   0x0000555555558022 <+2>:     push   0x1
   0x0000555555558024 <+4>:     pop    rax
   0x0000555555558025 <+5>:     mov    rdi,rax
   0x0000555555558028 <+8>:     pop    rsi
   0x0000555555558029 <+9>:     push   0xc
   0x000055555555802b <+11>:    pop    rdx
   0x000055555555802c <+12>:    syscall
   0x000055555555802e <+14>:    (bad)
   0x000055555555802f <+15>:    call   0x555555558022 <main+2>
   0x0000555555558034 <+20>:    rex.W
   0x0000555555558035 <+21>:    gs ins BYTE PTR es:[rdi],dx
   0x0000555555558037 <+23>:    ins    BYTE PTR es:[rdi],dx
   0x0000555555558038 <+24>:    outs   dx,DWORD PTR ds:[rsi]
   0x0000555555558039 <+25>:    sub    al,0x57
   0x000055555555803b <+27>:    outs   dx,DWORD PTR ds:[rsi]
   0x000055555555803c <+28>:    jb     0x5555555580aa
   0x000055555555803e <+30>:    and    DWORD PTR fs:[rax],eax
pwndbg> ni
  0x555555558020 <main>         jmp    main+15                     <main+15>
    ↓
 ► 0x55555555802f <main+15>      call   main+2                      <main+2>
        rdi: 1
        rsi: 0x7fffffffdff8 —▸ 0x7fffffffe26d ◂— '/shellcode'
        rdx: 0x7fffffffe008 —▸ 0x7fffffffe2ba ◂— 'SHELL=/bin/bash'
        rcx: 0x555555557df8 (__do_global_dtors_aux_fini_array_entry) —▸ 0x5555555550e0 (__do_global_dtors_aux) ◂— endbr64

   0x555555558034 <main+20>      insb   byte ptr [rdi], dx
   0x555555558037 <main+23>      insb   byte ptr [rdi], dx
   0x555555558038 <main+24>      outsd  dx, dword ptr [rsi]
   0x555555558039 <main+25>      sub    al, 0x57
   0x55555555803b <main+27>      outsd  dx, dword ptr [rsi]
   0x55555555803c <main+28>      jb     0x5555555580aa              <0x5555555580aa>

   0x55555555803e <main+30>      and    dword ptr fs:[rax], eax
   0x555555558041 <completed>    add    byte ptr [rax], al
   0x555555558043                add    byte ptr [rax], al
pwndbg> ni

Программа получила сигнал SIGSEGV, ошибка сегментации.
 0x555555558020 <main>         jmp    main+15                     <main+15>

 ► 0x55555555802f <main+15>      call   main+2                      <main+2>
        rdi: 1
        rsi: 0x7fffffffdff8 —▸ 0x7fffffffe26d ◂— '/shellcode'
        rdx: 0x7fffffffe008 —▸ 0x7fffffffe2ba ◂— 'SHELL=/bin/bash'
        rcx: 0x555555557df8 (__do_global_dtors_aux_fini_array_entry) —▸ 0x5555555550e0 (__do_global_dtors_aux) ◂— endbr64

   0x555555558034 <main+20>      insb   byte ptr [rdi], dx
   0x555555558037 <main+23>      insb   byte ptr [rdi], dx
   0x555555558038 <main+24>      outsd  dx, dword ptr [rsi]
   0x555555558039 <main+25>      sub    al, 0x57
   0x55555555803b <main+27>      outsd  dx, dword ptr [rsi]
   0x55555555803c <main+28>      jb     0x5555555580aa              <0x5555555580aa>

   0x55555555803e <main+30>      and    dword ptr fs:[rax], eax
   0x555555558041 <completed>    add    byte ptr [rax], al
   0x555555558043                add    byte ptr [rax], al

Как видно, первая инструкция выполняется, потому что мы переходим на 0x55555555802f.
Я пробовал использовать только инструкции nop, но та же проблема продолжает повторяться.

Так что кто-то может помочь мне? Спасибо

Ответ или решение

Для решения вашей проблемы с кодом shellcode в языке C и ошибкой сегментации (segmentation fault), необходимо проанализировать несколько ключевых аспектов, связанных с компиляцией и выполнением кода.

1. Понимание Shellcode

Shellcode – это небольшой фрагмент кода, предназначенный для выполнения как часть уязвимости в системе, обычно в контексте поставленного задания или теста на проникновение. В данном случае ваш shellcode должен выводить фразу "Hello, World!" в Unix-подобной системе.

Ваш текущий код:

char main[] = "\xeb\x0d\x6a\x01\x58\x48\x89\xc7\x5e\x6a\x0c\x5a\x0f\x05\xff\xe8\xee\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x57\x6f\x72\x6c\x64\x21"; 

2. Ошибка Сегментации

Ошибки сегментации возникают, когда программа пытается получить доступ к памяти, к которой она не имеет разрешения. В вашем случае проблема может заключаться в том, что вы пытаетесь выполнить массив main[] как исполняемый код, тогда как он фактически находится в сегменте данных, который обычно не является исполняемым.

3. Исполняемый код в C

Для того чтобы код был исполнимым, он должен находиться в области памяти, которую ОС помечает как исполняемую. Это может быть сделано с помощью системных вызовов или выделения памяти с правами на выполнение. В C это можно сделать следующим образом:

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

unsigned char code[] = 
"\xeb\x0d\x6a\x01\x58\x48\x89\xc7\x5e\x6a\x0c\x5a\x0f\x05\xff\xe8\xee\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x57\x6f\x72\x6c\x64\x21";

int main() {
    // Выделяем память и устанавливаем ее как исполняемую
    void *exec = mmap(0, sizeof(code), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (exec == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // Копируем ваш shellcode в выделенную память
    memcpy(exec, code, sizeof(code));

    // Выполняем исполняемый код
    ((void (*)())exec)();

    return 0;
}

4. Объяснение кода

  • mmap: Этот системный вызов выделяет страницу памяти с правами на чтение, запись и выполнение.
  • memcpy: Копирует ваш shellcode в выделенную область памяти.
  • *`((void ()())exec)()`**: Приводит адрес выделенной памяти к типу функции и вызывает её.

5. Компиляция и запуск

Скомпилируйте код с помощью следующей команды:

gcc -o shellcode shellcode.c

При запуске, вы должны увидеть "Hello, World!" без возникновения ошибок сегментации.

Заключение

Использование правильных прав доступа к памяти и понимание ее структуры является ключевым моментом при работе с shellcode в C. Следуя вышеприведенным шагам, вы сможете успешно запустить ваш код без ошибок сегментации. Вам необходимо быть внимательным к тому, чтобы не пытаться запускать код, который хранится в сегментах данных, так как это может привести к ошибкам.

Оцените материал
Добавить комментарий

Капча загружается...