Изменение адреса в шеллкоде во время выполнения

Моя цель - создать шелл-код, который вызывает WinExec и запускает notepad.exe. Код голых костей (хотя на самом деле окружен некоторыми другимиgcc произведенная сборка):

push 0x00646170
push 0x65746F6E 

push 5

lea eax, [esp + 0x4]
push eax

call 0x76E137C0
add esp, 32

Он помещает в стек "блокнот \0", затем 5, затем адрес "notepad" строка, затем, наконец, вызывает 0x76E137C0. 0x76E137C0 это адрес WinExec кажется, что он находится в, когда ASLR отключен на моем компьютере (32-разрядная виртуальная машина Windows 10).

Я беру этот код, собирая его с помощью gcc (просто gcc shell.c -o shell.exe), тогда objdumpэто. Как только я нахожу инструкции, я беру показанные в них байты:

40141e:       68 70 61 64 00          push   $0x646170
401423:       68 6e 6f 74 65          push   $0x65746f6e
401428:       6a 05                   push   $0x5
40142a:       8d 44 24 04             lea    0x4(%esp),%eax
40142e:       50                      push   %eax
40142f:       e8 8c 23 a1 76          call   76e137c0 <.debug_str+0x76a027c0>
401434:       83 c4 20                add    $0x20,%esp

Затем я превращаю это в строку байтов и пытаюсь выполнить:

#include <windows.h>
#include <winbase.h>

int main() {

    char* shellcode =
       "\x68\x70\x61\x64\x00\x68\x6e\x6f\x74\x65\x6a\x05\x8d\x44\x24\x04\x50\xe8\xbc\x37\xe1\x76\x83\xc4\x20";

    ((void(*)())shellcode)();

    return 0;
}

Проблема в том, что если я затем скомпилирую указанную выше простую программу на C и запустю ее, ничего не произойдет. Если я открою его в Immunity и step, я вижу, что инструкции были сохранены, за исключением адреса:

Адрес находится в неправильном модуле и, похоже, частично выполняет функцию. Если я уйду и попаду вcall, У меня нарушение прав доступа. Однако если я перезапускаю и в Immunity заменяюcall 77218816 с участием call 0x76E137C0, затем продолжайте, он работает нормально, и появляется блокнот.

Я не могу сказать, почему адрес меняется, хотя ничего другого не изменилось. Кто-нибудь видит, что я делаю не так?



Вся начальная сборка

    .file   "shell.c"
    .intel_syntax noprefix
    .text
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
    .align 4
LC0:
    .ascii "notepad\0"
    .text
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    lea ecx, [esp+4]

    and esp, -16
    push    DWORD PTR [ecx-4]
    push    ebp

    mov ebp, esp
    push    ecx

    push 0x00646170
    push 0x65746F6E 
    
    push 5
    
    lea eax, [esp + 0x4]
    push eax
    
    call 0x76E137C0
    add esp, 32
    
    sub esp, 8
    mov eax, 0
    mov ecx, DWORD PTR [ebp-4]

    leave

    lea esp, [ecx-4]

    ret

1 ответ

Решение

С помощью callкак это относится к EIP. Вы запускаете свой шелл-код не по тому же адресу, для которого вы его скомпилировали, поэтому он не можетcallиз себя вот так. Для быстрого и грязного обходного пути вы можете сделатьmov eax, 0x76E137C0 а потом call eax, что абсолютно.

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