Executing shellcode in shared memory with mmap [duplicate]
Asked Answered
E

1

8

I'm trying to place and execute program-code into a shared-memory region. Initializing and allocating the shared memory as well as copying the shellcode into the "new" memory works as intended, but as soon as I try to execute it, it doesn't work. Does anyone have an idea what the problem might be?

I think that write(1, 0x6000d8, 13) = -1 EFAULT (Bad address)might be the error? What might be causing this?

I included the code and the stract error output. The C-code is based on an answer from Adam Rosenfield in this Question.

The C-Code

#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 +++

The source of the 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
Effusive answered 8/5, 2017 at 14:7 Comment(5)
It looks like your shellcode somewhat worked. The value \xd8\x00\x60\x00 looks like the invalid address 0x6000d8 that was passed to write().Ichinomiya
@AndrewHenle So the problem might be the shell code, right? The address that the shellcode "uses" is wrong?Effusive
Have you got the source code of the shell code? If yes post it.Pourpoint
Sure @LPs, I just added it to my original post!Effusive
It smells that "hello, world!" string, stored in .data segment, is not reachable when shell code was copied. Moreover your shell code array should have the "hello, world!" string somewhere. Something like \x68\x65\x6c\x6c\x6f....Pourpoint
P
1

To apply the proposed duplicate to your code

When you inject this shell code, you don't know what is at message:

mov     rsi, msg

in the injected process, it can be anything but it will not be "Hello world!\r\n" since it is in the .data section

section .data
    msg db      "hello, world!"

while you dumped only the .text section.

You can see that your shell code doesn't have "Hello world!\r\n" (\x68\x65\x6c\x6c\x6f....)

Pourpoint answered 8/5, 2017 at 14:41 Comment(1)
Thanks @LPs, this was indeed the case. I changed mov rsi, msg to pop rsi and it worked like a charm.Effusive

© 2022 - 2024 — McMap. All rights reserved.