Skip to content

Instantly share code, notes, and snippets.

@hugsy
Last active June 18, 2020 22:29
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hugsy/8703018 to your computer and use it in GitHub Desktop.
Save hugsy/8703018 to your computer and use it in GitHub Desktop.
Using new syscalls to bypass ptrace-protected process and read/write arbitrary memory.

Even though well known methods exist to bypass ptrace deactivation on a process when spawning (fake ptrace() preloading, breakpoint on ptrace(), etc... ), it is trickier when process is already protected.

Thankfully Linux 3.2+ was generous enough to provide read/write capabilities to another process with 2 new system calls: sys_process_vm_readv and sys_process_vm_writev. (see https://github.com/torvalds/linux/blob/master/arch/x86/syscalls/syscall_64.tbl#L319)

Manual says:

These system calls transfer data between the address space of the calling process ("the local process") and the process identified by pid ("the remote process"). The data moves directly between the address spaces of the two processes, without passing through kernel space.

A running process protected like this:

if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
   perror("[-] is traced\n");
   return 1;
}

can hence still have its memory read :

struct iovec local[1], remote[1];
local->iov_base = mybuf;
local->iov_len = size_to_read;
remote->iov_base = (void *) strtoll(argv[2], NULL, 16);
remote->iov_len = to_read;
int nread = process_vm_readv(target_pid, local, 1, remote, 1, 0);

Similar call to process_vm_writev will tamper remote process memory.

Even though it is not possible to read/write in process memory that don't have the same level of privilege (unless given CAP_SYS_PTRACE capability), it is a very reliable way to leak or inject data.

By @hugsy (https://twitter.com/_hugsy_)

Last update: 23/12/2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment