Изменение адреса в шеллкоде во время выполнения
Моя цель - создать шелл-код, который вызывает 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
, что абсолютно.