使用mmap在共享内存中执行shellcode

8

我正在尝试将程序代码放置并执行到共享内存区域。初始化和分配共享内存以及将shellcode复制到“新”内存中的操作都按预期进行,但是一旦我尝试执行它,它就无法正常工作。有人有什么想法可能是问题所在吗?

我认为write(1, 0x6000d8, 13) = -1 EFAULT(Bad address)可能是错误?这可能是什么原因引起的?

我包含了代码和stract错误输出。 C代码基于Adam Rosenfield此问题中的答案。

C语言代码

#include <string.h>
#include <sys/mman.h>

// My own shellcode, obtained through objdump
// works on its own (a hello world-program)
const char shellcode[] = "\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\x00\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05";

int main(int argc, char **argv)
{
    void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);

    memcpy(mem, shellcode, sizeof(shellcode));

    mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);

    int (*func)();
    func = (int (*)())mem;
    (int)(*func)();

    munmap(mem, sizeof(shellcode));

    return 0;
}

Strace Log

execve("./memory", ["./memory"], [/* 17 vars */]) = 0
brk(NULL) = 0x557b5e17e000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb8ba434000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=92611, ...}) = 0
mmap(NULL, 92611, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fb8ba41d000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\5\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1856752, ...}) = 0
mmap(NULL, 3959200, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fb8b9e4c000
mprotect(0x7fb8ba009000, 2097152, PROT_NONE) = 0
mmap(0x7fb8ba209000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7fb8ba209000
mmap(0x7fb8ba20f000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fb8ba20f000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb8ba41b000
arch_prctl(ARCH_SET_FS, 0x7fb8ba41b700) = 0
mprotect(0x7fb8ba209000, 16384, PROT_READ) = 0
mprotect(0x557b5dd04000, 4096, PROT_READ) = 0
mprotect(0x7fb8ba437000, 4096, PROT_READ) = 0
munmap(0x7fb8ba41d000, 92611)           = 0
mmap(NULL, 40, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7fb8ba433000
mprotect(0x7fb8ba433000, 40, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
write(1, 0x6000d8, 13) = -1 EFAULT (Bad address)
exit(0) = ?
+++ exited with 0 +++
Shellcode的来源
section .data
    msg db      "hello, world!"

section .text
    global _start
_start:
    mov     rax, 1
    mov     rdi, 1
    mov     rsi, msg
    mov     rdx, 13
    syscall
    mov    rax, 60
    mov    rdi, 0
    syscall

看起来你的 shellcode 工作了一些。 值 \xd8\x00\x60\x00 看起来像是传递给 write() 的无效地址 0x6000d8 - Andrew Henle
@AndrewHenle 所以问题可能是Shell代码,对吧? Shell代码“使用”的地址错了? - Marvin
1
你有shell代码的源代码吗?如果有,请发布它。 - LPs
当然,@LPs,我刚刚把它添加到我的原始帖子中了! - Marvin
看起来当 shell 代码被复制时,存储在 .data 段中的 "hello, world!" 字符串是不可达的。此外,你的 shell 代码数组应该在某个地方包含 "hello, world!" 字符串,类似于 \x68\x65\x6c\x6c\x6f.... - LPs
1个回答

1
将建议的重复代码应用到您的代码中
当您注入此 shell 代码时,您不知道 message 中有什么内容:
mov     rsi, msg

在注入的进程中,它可以是任何东西,但不会是 "Hello world!\r\n",因为它在 .data 部分。
section .data
    msg db      "hello, world!"

当你只转储了 .text 段时。

你可以看到,你的 shell 代码中没有 "Hello world!\r\n"\x68\x65\x6c\x6c\x6f....


感谢 @LPs,确实是这种情况。我将 mov rsi, msg 改为 pop rsi,效果非常好。 - Marvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接