Get a Pentest and security assessment of your IT network.

Cyber Security

GDB Attach After Privilege Drop

TL;DR

Attaching GDB to a process after it has dropped privileges requires careful setup. This guide explains how to do this, focusing on using a shared memory region for communication and setting up the correct permissions.

Steps

  1. Shared Memory Setup in the Target Process (Before Privilege Drop)
    • Allocate a shared memory region. This will be used to signal GDB when it’s safe to attach.
    • Create a named semaphore or file lock associated with the shared memory. This prevents race conditions during attachment.
    • Write a known value (e.g., 0x42424242) into the shared memory region as an initial signal.
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>>
    
    int main() {
      const char *shmem_name = "/tmp/my_shared_memory";
      size_t shmem_size = 4096; // Example size
      int fd = shm_open(shmem_name, O_CREAT | O_RDWR, 0666);
      if (fd == -1) { perror("shm_open failed"); return 1; }
      ftruncate(fd, shmem_size); // Set size
      void *shmem = mmap(NULL, shmem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
      if (shmem == MAP_FAILED) { perror("mmap failed"); return 1; }
      *((int *)shmem) = 0x42424242; // Initial signal
      printf("Shared memory created at %pn", shmem);
      // ... rest of your program, including privilege drop ...
    }
    
  2. Privilege Drop
  3. Perform the privilege drop using methods like setuid(), seteuid(), or by switching to a less privileged user. Ensure this happens *after* setting up the shared memory.

  4. GDB Script Setup (On the Debugging Machine)
    • Create a GDB script that waits for the signal in the shared memory region before attaching.
    • The script should also handle potential race conditions by using a semaphore or file lock.
    # gdb script (wait_for_attach.gdb)
    set $shmem_name = "/tmp/my_shared_memory"
    set $shmem_size = 4096
    
    while true {
      file /proc/[pid]/mem # Replace [pid] with the target process's PID
      p *((int *)$shmem_name)
      if ($result == 0x42424242) {
        break
      }
      sleep 1
    }
    attach [pid]
    
  5. Attach with GDB
    • Run GDB on the target process, loading the script:
    gdb -x wait_for_attach.gdb [target_process]
  6. Verify Attachment
  7. Once attached, verify that you can inspect the process’s memory and state within GDB.

  8. Cleanup (Important)
    • After debugging, detach from the process.
    • Unmap the shared memory region in the target process.
    • Remove the named semaphore or file lock.
    • Close and unlink the shared memory segment.

Important Considerations

  • Permissions: Ensure the user running GDB has read/write access to the shared memory region.
  • Race Conditions: The semaphore or file lock is crucial to prevent GDB from attaching before the shared memory is initialized.
  • PID Stability: If the target process’s PID changes, you will need to update the GDB script accordingly.
  • Security: Shared memory can be a security risk if not handled carefully. Limit access and ensure proper cleanup.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation