shellcode 中的地址在执行期间发生变化
Address in shellcode changing during execution
我的目标是创建调用 WinExec
并启动 notepad.exe
的 shellcode。最简单的代码是(尽管实际上被其他一些 gcc
生产的程序集所包围):
push 0x00646170
push 0x65746F6E
push 5
lea eax, [esp + 0x4]
push eax
call 0x76E137C0
add esp, 32
它将“notepad[=52=]”压入堆栈,然后是 5,然后是 "notepad"
字符串的地址,最后调用 0x76E137C0
。 0x76E137C0
是地址 WinExec
似乎驻留在我的机器上禁用 ASLR 时(32 位 Windows 10 VM)。
我正在使用这段代码,使用 gcc
(简单地 gcc shell.c -o shell.exe
)组装它,然后 objdump
ing 它。找到说明后,我将使用它显示的字节:
40141e: 68 70 61 64 00 push [=11=]x646170
401423: 68 6e 6f 74 65 push [=11=]x65746f6e
401428: 6a 05 push [=11=]x5
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 [=11=]x20,%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 中打开它并执行步骤,我可以看到指令已被保留, 除了地址 :
地址在错误的模块中,似乎是函数的一部分。如果我下台并进入 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[=13=]"
.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
像这样使用 call
是 EIP 相关的。你不是 运行 你的 shellcode 在你编译它的相同地址,所以它不能 call
那样自己。对于快速而肮脏的解决方法,您可以执行 mov eax, 0x76E137C0
,然后执行 call eax
,这是绝对的。
我的目标是创建调用 WinExec
并启动 notepad.exe
的 shellcode。最简单的代码是(尽管实际上被其他一些 gcc
生产的程序集所包围):
push 0x00646170
push 0x65746F6E
push 5
lea eax, [esp + 0x4]
push eax
call 0x76E137C0
add esp, 32
它将“notepad[=52=]”压入堆栈,然后是 5,然后是 "notepad"
字符串的地址,最后调用 0x76E137C0
。 0x76E137C0
是地址 WinExec
似乎驻留在我的机器上禁用 ASLR 时(32 位 Windows 10 VM)。
我正在使用这段代码,使用 gcc
(简单地 gcc shell.c -o shell.exe
)组装它,然后 objdump
ing 它。找到说明后,我将使用它显示的字节:
40141e: 68 70 61 64 00 push [=11=]x646170
401423: 68 6e 6f 74 65 push [=11=]x65746f6e
401428: 6a 05 push [=11=]x5
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 [=11=]x20,%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 中打开它并执行步骤,我可以看到指令已被保留, 除了地址 :
地址在错误的模块中,似乎是函数的一部分。如果我下台并进入 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[=13=]"
.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
像这样使用 call
是 EIP 相关的。你不是 运行 你的 shellcode 在你编译它的相同地址,所以它不能 call
那样自己。对于快速而肮脏的解决方法,您可以执行 mov eax, 0x76E137C0
,然后执行 call eax
,这是绝对的。