首页 > 解决方案 > shellcode中的地址在执行过程中发生变化

问题描述

我的目标是创建调用WinExec和启动的 shellcode notepad.exe。最基本的代码是(尽管实际上被其他一些gcc生成的程序集包围):

push 0x00646170
push 0x65746F6E 

push 5

lea eax, [esp + 0x4]
push eax

call 0x76E137C0
add esp, 32

它将“notepad\0”压入堆栈,然后是 5,然后是"notepad"字符串的地址,最后调用0x76E137C0. 0x76E137C0当我的机器(A 32 位 Windows 10 VM)上禁用 ASLR 时,该地址WinExec似乎位于。

我正在使用此代码,使用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 中打开它并执行步骤,我可以看到指令被保留,除了地址:

免疫调试器屏幕截图

该地址位于错误的模块中,并且似乎是函数的一部分。如果我下台并进入call,我会遇到访问冲突。但是,如果我重新启动,并在 Immunity 中将 替换为call 77218816call 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

标签: cassemblyx86gnu-assemblershellcode

解决方案


像这样使用call是相对于 EIP 的。你没有在你编译它的同一个地址运行你的 shellcode,所以它不能call像那样脱离它本身。对于快速而肮脏的解决方法,您可以执行mov eax, 0x76E137C0and then call eax,这是绝对的。


推荐阅读