Monday, September 28, 2015

Examining Linux Process Memory, Part 1

Hey everyone.  This is the first part in a two part series where we will briefly examine reading process memory in Linux.  I was inspired by a tool that reads credit card track data out of process memory in Windows.  After I saw that tool, I wondered to myself how hard it would be to do something similar in Linux, but with Python.  In this part, we will talk about how we can access memory in Linux.  In the second part, we will look at a script that does similar work to the Powershell script linked above.

You might be wondering what an examination of memory structures in Linux has to do with network security.  I believe that you cannot twist a system to do what you want unless you know how it works.  If we want to look at memory in Linux to discover useful artifacts (like credit card numbers, social security numbers, whatever), then we have to be familiar with how one could read the memory of an arbitrary process.

Remember the everything on a *nix system is represented by a file: the files on your hard drive, your printer, and even your memory.  The keyword is represented.  The kernel creates a number of virtual filesystems to abstract lower level parts of your system so that software that needs to interface with various parts of the system has a standard way to do so.  These virtual filesystems allow the software to target a device or aspect of the system without worrying about changes in the underlying implementation.  For example, /dev is used to interface with a given hardware device's driver as if it were a file.  If a piece of software needs to interface with /dev/sda (the first SATA hard disk in the system), it does not need to worry about differences in SATA drivers across systems.  It asks for /dev/sda, and the kernel worries about the specific implementation of the operation the software is trying to do.

That is great for devices, but what about memory?  You can access system memory through the /proc filesystem.  You might see this referred to as procfs.


user@localhost:~$ ls -al /proc
total 4
dr-xr-xr-x 94 root             root                           0 Sep  7 10:21 .
drwxr-xr-x 22 root             root                        4096 Sep  2 15:20 ..
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 1
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 10
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 11
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 12
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 13
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 133
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 134
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 135
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 138
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 139
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 14
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 146
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 147
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 149
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 15
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 150
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 163
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 164
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 17
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 18
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 19
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 2
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 20
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 208
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 21
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 22
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 229
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 23
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 24
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 240
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 25
dr-xr-xr-x  9 root             root                           0 Sep 12 06:35 2583
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 26
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 264
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 27
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 278
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 28
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 29
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 3
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 30
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 31
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 32
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 33
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 331
dr-xr-xr-x  9 systemd-timesync systemd-timesync               0 Sep  7 10:21 378
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 38
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 39
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 40
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 5
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 52
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 53
dr-xr-xr-x  9 root             root                           0 Sep 20 06:47 5312
dr-xr-xr-x  9 root             root                           0 Sep 20 06:47 5361
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 54
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 549
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 55
dr-xr-xr-x  9 daemon           daemon                         0 Sep  7 10:21 552
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 56
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 562
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 563
dr-xr-xr-x  9 root             root                           0 Sep 21 06:41 5650
dr-xr-xr-x  9 syslog           syslog                         0 Sep  7 10:21 567
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 57
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 570
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 581
dr-xr-xr-x  9 root             root                           0 Sep 21 17:47 5949
dr-xr-xr-x  9 root             root                           0 Sep 21 17:47 5979
dr-xr-xr-x  9 root             root                           0 Sep 21 17:47 5983
dr-xr-xr-x  9 root             root                           0 Sep 21 17:47 5984
dr-xr-xr-x  9 user             user                           0 Sep 21 17:47 5986
dr-xr-xr-x  9 user             user                           0 Sep 21 17:47 5987
dr-xr-xr-x  9 user             user                           0 Sep 21 17:47 6084
dr-xr-xr-x  9 user             user                           0 Sep 21 17:47 6088
dr-xr-xr-x  9 user             user                           0 Sep 21 17:48 6110
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 62
dr-xr-xr-x  9 messagebus       messagebus                     0 Sep  7 10:21 621
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 636
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 7
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 8
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 82
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 83
dr-xr-xr-x  9 root             root                           0 Sep  7 10:21 9
dr-xr-xr-x  2 root             root                           0 Sep 21 17:48 acpi
-r--r--r--  1 root             root                           0 Sep 21 17:48 buddyinfo
dr-xr-xr-x  4 root             root                           0 Sep 21 17:48 bus
-r--r--r--  1 root             root                           0 Sep 21 17:48 cgroups
-r--r--r--  1 root             root                           0 Sep 21 17:48 cmdline
-r--r--r--  1 root             root                           0 Sep 21 17:48 consoles
-r--r--r--  1 root             root                           0 Sep 21 17:48 cpuinfo
-r--r--r--  1 root             root                           0 Sep 21 17:48 crypto
-r--r--r--  1 root             root                           0 Sep 21 17:48 devices
-r--r--r--  1 root             root                           0 Sep 21 17:48 diskstats
-r--r--r--  1 root             root                           0 Sep 21 17:48 dma
dr-xr-xr-x  2 root             root                           0 Sep 21 17:48 driver
-r--r--r--  1 root             root                           0 Sep 21 17:48 execdomains
-r--r--r--  1 root             root                           0 Sep 21 17:48 fb
-r--r--r--  1 root             root                           0 Sep 21 17:48 filesystems
dr-xr-xr-x  5 root             root                           0 Sep 21 17:48 fs
-r--r--r--  1 root             root                           0 Sep 21 17:48 interrupts
-r--r--r--  1 root             root                           0 Sep 21 17:48 iomem
-r--r--r--  1 root             root                           0 Sep 21 17:48 ioports
dr-xr-xr-x 55 root             root                           0 Sep 21 17:48 irq
-r--r--r--  1 root             root                           0 Sep 21 17:48 kallsyms
-r--------  1 root             root             140737477877760 Sep 21 17:48 kcore
-r--r--r--  1 root             root                           0 Sep 21 17:48 keys
-r--r--r--  1 root             root                           0 Sep 21 17:48 key-users
-r--------  1 root             root                           0 Sep  7 10:21 kmsg
-r--------  1 root             root                           0 Sep 21 17:48 kpagecount
-r--------  1 root             root                           0 Sep 21 17:48 kpageflags
-r--r--r--  1 root             root                           0 Sep 21 17:48 loadavg
-r--r--r--  1 root             root                           0 Sep 21 17:48 locks
-r--r--r--  1 root             root                           0 Sep 21 17:48 mdstat
-r--r--r--  1 root             root                           0 Sep 21 17:48 meminfo
-r--r--r--  1 root             root                           0 Sep 21 17:48 misc
-r--r--r--  1 root             root                           0 Sep 21 17:48 modules
lrwxrwxrwx  1 root             root                          11 Sep 21 17:48 mounts -> self/mounts
dr-xr-xr-x  3 root             root                           0 Sep 21 17:48 mpt
-rw-r--r--  1 root             root                           0 Sep 21 17:48 mtrr
lrwxrwxrwx  1 root             root                           8 Sep 21 17:48 net -> self/net
-r--r--r--  1 root             root                           0 Sep 21 17:48 pagetypeinfo
-r--r--r--  1 root             root                           0 Sep 21 17:48 partitions
-r--r--r--  1 root             root                           0 Sep 21 17:48 sched_debug
-r--r--r--  1 root             root                           0 Sep 21 17:48 schedstat
dr-xr-xr-x  4 root             root                           0 Sep 21 17:48 scsi
lrwxrwxrwx  1 root             root                           0 Sep  7 10:21 self -> 6110
-r--------  1 root             root                           0 Sep 21 17:48 slabinfo
-r--r--r--  1 root             root                           0 Sep 21 17:48 softirqs
-r--r--r--  1 root             root                           0 Sep 21 17:48 stat
-r--r--r--  1 root             root                           0 Sep  7 10:21 swaps
dr-xr-xr-x  1 root             root                           0 Sep  7 10:21 sys
--w-------  1 root             root                           0 Sep 21 17:48 sysrq-trigger
dr-xr-xr-x  2 root             root                           0 Sep 21 17:48 sysvipc
lrwxrwxrwx  1 root             root                           0 Sep  7 10:21 thread-self -> 6110/task/6110
-r--r--r--  1 root             root                           0 Sep 21 17:48 timer_list
-rw-r--r--  1 root             root                           0 Sep 21 17:48 timer_stats
dr-xr-xr-x  4 root             root                           0 Sep 21 17:48 tty
-r--r--r--  1 root             root                           0 Sep 21 17:48 uptime
-r--r--r--  1 root             root                           0 Sep 21 17:48 version
-r--r--r--  1 root             root                           0 Sep 21 17:48 version_signature
-r--------  1 root             root                           0 Sep 21 17:48 vmallocinfo
-r--r--r--  1 root             root                           0 Sep 21 17:48 vmstat
-r--r--r--  1 root             root                           0 Sep 21 17:48 zoneinfo


There are a lot of entries in there, but let's talk about some of the highlights:
  • /proc/<a  number>: Each of the procfs entries that are just numbers each represent the process memory of that PID (process identifier).  We will talk about this more in depth later.
  • /proc/mounts: This is a list of the filesystems mounted on the system.  The command 'mount' with no arguments is essentially the same as 'cat /proc/mounts'
  • /proc/kcore: You might be looking at this one and wonder why it is "taking up" 140,737,477,877,760 bytes (roughly 128TiB).  kcore is not taking up that much space.  Rather, it is a representation of the total amount of virtual memory that the kernel can allocate.  This system is a 64-bit system, so in theory, it could address 2^64 bytes of memory, but modern 64-bit x86 CPUs only use the lower 48 bits of a memory address (see the AMD docs on x86-64 here on page 168 of the PDF, 120 of the document).  In practice, that gives us 2^47 bytes we can address.  2^47 bytes is roughly 128TiB.  I was curious about this myself, so I looked it up.
  • /proc/cpuinfo: cat /proc/cpuinfo will tell you all kinds of info about your CPU including cache size, model, speed, and capabilities (like SSE, AES-NI, and others).
 As you may have noticed, you can cat various members of procfs and get lots of interesting information.  Let's take a look at the memory for a given process.  In another session, I launched a nano process.  Let's find its PID using ps:


user@localhost:~$ ps -aef | grep nano
user      6157  6088  0 18:20 pts/0    00:00:00 nano -w
user      6626  6207  0 18:31 pts/1    00:00:00 grep --color=auto nano

So our nano process has a PID of 6157 (the 6088 PID is the PID of the parent process - the process that our nano process spawned from).  Let's see what is in the procfs for PID 6157:


user@localhost:~$ ls -al /proc/6157
total 0
dr-xr-xr-x  9 user user 0 Sep 21 18:21 .
dr-xr-xr-x 98 root root 0 Sep  7 10:21 ..
dr-xr-xr-x  2 user user 0 Sep 21 18:21 attr
-rw-r--r--  1 user user 0 Sep 21 18:21 autogroup
-r--------  1 user user 0 Sep 21 18:21 auxv
-r--r--r--  1 user user 0 Sep 21 18:21 cgroup
--w-------  1 user user 0 Sep 21 18:21 clear_refs
-r--r--r--  1 user user 0 Sep 21 18:21 cmdline
-rw-r--r--  1 user user 0 Sep 21 18:21 comm
-rw-r--r--  1 user user 0 Sep 21 18:21 coredump_filter
-r--r--r--  1 user user 0 Sep 21 18:21 cpuset
lrwxrwxrwx  1 user user 0 Sep 21 18:21 cwd -> /home/user
-r--------  1 user user 0 Sep 21 18:21 environ
lrwxrwxrwx  1 user user 0 Sep 21 18:21 exe -> /bin/nano
dr-x------  2 user user 0 Sep 21 18:21 fd
dr-x------  2 user user 0 Sep 21 18:21 fdinfo
-rw-r--r--  1 user user 0 Sep 21 18:21 gid_map
-r--------  1 user user 0 Sep 21 18:21 io
-r--r--r--  1 user user 0 Sep 21 18:21 limits
-rw-r--r--  1 user user 0 Sep 21 18:21 loginuid
dr-x------  2 user user 0 Sep 21 18:21 map_files
-r--r--r--  1 user user 0 Sep 21 18:21 maps
-rw-------  1 user user 0 Sep 21 18:21 mem
-r--r--r--  1 user user 0 Sep 21 18:21 mountinfo
-r--r--r--  1 user user 0 Sep 21 18:21 mounts
-r--------  1 user user 0 Sep 21 18:21 mountstats
dr-xr-xr-x  6 user user 0 Sep 21 18:21 net
dr-x--x--x  2 user user 0 Sep 21 18:21 ns
-r--r--r--  1 user user 0 Sep 21 18:21 numa_maps
-rw-r--r--  1 user user 0 Sep 21 18:21 oom_adj
-r--r--r--  1 user user 0 Sep 21 18:21 oom_score
-rw-r--r--  1 user user 0 Sep 21 18:21 oom_score_adj
-r--------  1 user user 0 Sep 21 18:21 pagemap
-r--------  1 user user 0 Sep 21 18:21 personality
-rw-r--r--  1 user user 0 Sep 21 18:21 projid_map
lrwxrwxrwx  1 user user 0 Sep 21 18:21 root -> /
-rw-r--r--  1 user user 0 Sep 21 18:21 sched
-r--r--r--  1 user user 0 Sep 21 18:21 schedstat
-r--r--r--  1 user user 0 Sep 21 18:21 sessionid
-rw-r--r--  1 user user 0 Sep 21 18:21 setgroups
-r--r--r--  1 user user 0 Sep 21 18:21 smaps
-r--------  1 user user 0 Sep 21 18:21 stack
-r--r--r--  1 user user 0 Sep 21 18:21 stat
-r--r--r--  1 user user 0 Sep 21 18:21 statm
-r--r--r--  1 user user 0 Sep 21 18:21 status
-r--------  1 user user 0 Sep 21 18:21 syscall
dr-xr-xr-x  3 user user 0 Sep 21 18:21 task
-r--r--r--  1 user user 0 Sep 21 18:21 timers
-rw-r--r--  1 user user 0 Sep 21 18:21 uid_map
-r--r--r--  1 user user 0 Sep 21 18:21 wchan


There are lots of interesting things in here.  For example, we can see a symlink to the current working directory (cwd), the executable itself (exe), and the command line arguments used to launch the program (cmdline).  They are all zero bytes, because each of these "files" live in memory.  If we cat out cmdline for example, we see nano-w which matches what we saw in the ps output.  For examining the actual memory of the process, we will focus on mem and maps.  If you want to see what each of these means, there is a good article here.  Mem is the memory that this process is using, and maps describes the libraries and various memory sections used by the process.  We cannot cat the memory out directly (there would be a lot of bytes that we might not care about), but let's take a look at the maps:


user@localhost:~$ cat /proc/6157/maps
00400000-0042e000 r-xp 00000000 fc:00 659332                             /bin/nano
0062d000-0062e000 r--p 0002d000 fc:00 659332                             /bin/nano
0062e000-0062f000 rw-p 0002e000 fc:00 659332                             /bin/nano
0148e000-01580000 rw-p 00000000 00:00 0                                  [heap]
7f09babc3000-7f09bae8c000 r--p 00000000 fc:00 137021                     /usr/lib/locale/locale-archive
7f09bae8c000-7f09bae8f000 r-xp 00000000 fc:00 786954                     /lib/x86_64-linux-gnu/libdl-2.21.so
7f09bae8f000-7f09bb08e000 ---p 00003000 fc:00 786954                     /lib/x86_64-linux-gnu/libdl-2.21.so
7f09bb08e000-7f09bb08f000 r--p 00002000 fc:00 786954                     /lib/x86_64-linux-gnu/libdl-2.21.so
7f09bb08f000-7f09bb090000 rw-p 00003000 fc:00 786954                     /lib/x86_64-linux-gnu/libdl-2.21.so
7f09bb090000-7f09bb250000 r-xp 00000000 fc:00 786942                     /lib/x86_64-linux-gnu/libc-2.21.so
7f09bb250000-7f09bb450000 ---p 001c0000 fc:00 786942                     /lib/x86_64-linux-gnu/libc-2.21.so
7f09bb450000-7f09bb454000 r--p 001c0000 fc:00 786942                     /lib/x86_64-linux-gnu/libc-2.21.so
7f09bb454000-7f09bb456000 rw-p 001c4000 fc:00 786942                     /lib/x86_64-linux-gnu/libc-2.21.so
7f09bb456000-7f09bb45a000 rw-p 00000000 00:00 0
7f09bb45a000-7f09bb47f000 r-xp 00000000 fc:00 787045                     /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f09bb47f000-7f09bb67e000 ---p 00025000 fc:00 787045                     /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f09bb67e000-7f09bb682000 r--p 00024000 fc:00 787045                     /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f09bb682000-7f09bb683000 rw-p 00028000 fc:00 787045                     /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f09bb683000-7f09bb6b6000 r-xp 00000000 fc:00 786991                     /lib/x86_64-linux-gnu/libncursesw.so.5.9
7f09bb6b6000-7f09bb8b6000 ---p 00033000 fc:00 786991                     /lib/x86_64-linux-gnu/libncursesw.so.5.9
7f09bb8b6000-7f09bb8b7000 r--p 00033000 fc:00 786991                     /lib/x86_64-linux-gnu/libncursesw.so.5.9
7f09bb8b7000-7f09bb8b8000 rw-p 00034000 fc:00 786991                     /lib/x86_64-linux-gnu/libncursesw.so.5.9
7f09bb8b8000-7f09bb8dc000 r-xp 00000000 fc:00 786918                     /lib/x86_64-linux-gnu/ld-2.21.so
7f09bbac8000-7f09bbacf000 r--s 00000000 fc:00 133547                     /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f09bbacf000-7f09bbad3000 rw-p 00000000 00:00 0
7f09bbad9000-7f09bbadb000 rw-p 00000000 00:00 0
7f09bbadb000-7f09bbadc000 r--p 00023000 fc:00 786918                     /lib/x86_64-linux-gnu/ld-2.21.so
7f09bbadc000-7f09bbadd000 rw-p 00024000 fc:00 786918                     /lib/x86_64-linux-gnu/ld-2.21.so
7f09bbadd000-7f09bbade000 rw-p 00000000 00:00 0
7ffc68c28000-7ffc68c49000 rw-p 00000000 00:00 0                          [stack]
7ffc68d66000-7ffc68d68000 r--p 00000000 00:00 0                          [vvar]
7ffc68d68000-7ffc68d6a000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


As we expected, we can see the various libraries that nano loads (like libc and libncurses).  We can also see where the stack and heap live.  If we have typed anything into the nano session, we will see it in the heap.  This is because nano cannot pre-allocate space for a free-form buffer (like the one needed to capture arbitrary text from the user), so it uses the heap to dynamically allocate memory.

Let's take a look at one of the lines and figure out what it means:

0148e000-01580000 rw-p 00000000 00:00 0                                  [heap]


The first section (0148e000-01580000) contains the start and end of the memory segment.  The second column (rw-p in this case) contains the permissions on that segment of memory.  These are similar to filesystem permissions in *nix.  The permissions in this case mean the memory is readable, writable, and private (meaning that only this process can access it).  The final permission is executable (x).  Notice that in the maps above, writable and executable are not enabled together on any of the mapped regions.  This is to help prevent attacks like buffer overflows.  In short, buffer overflows take advantage of a vulnerability where an attack overwrites the return address of a function with the address to their shellcode.  If that shellcode is in a space in memory that is marked as executable, the shellcode will be executed and the attacker gains control over the execution of the program.  The third field is the offset which tell us the offset in the file (the rightmost column) that is loaded into memory.  The fourth field is the device.  It is broken into two parts: the major and minor device field, respectively.  This is only applicable for files.  The fifth column is the inode on the disk of the file.  The final field is the path to the file loaded into memory or special regions (like heap and stack).  More info is available in the man page for proc (man proc).

Now that we know how the memory in the process is laid out, we should be able to target specific artifacts in memory as long as we can generalize them.  For example, we can generalize what a credit card number looks like (a 16 digit number in a specific format) or an SSN (9 numeric digits, in groups of 3 digits, 2 digits, and 4 digits).

Before we dive into that, we have to be aware of something.  In some distros, protections in the kernel have been enabled by default that do not allow one process (call it A) to access the memory of another process (call it B).  The only exception is if A called B (in other words, A has to be the parent of B).  This allows for debugging, but prevents a process from being able to attach to any other process to read its memory.  This is true even if A and B are owned by the same user.  This is different than how things work in Windows.  In Windows, a process running as a user can access the memory of another process running as that user.  That is what allows the tool I linked to in the beginning of the post to work.  This can be dangerous because if your browser gets exploited, it could read the memory of another process where you might have sensitive info.

You can check if your kernel is enforcing this rule by checking the contents of /proc/sys/kernel/yama/ptrace_scope.  Ptrace is a system call on *nix systems that allows a process to control another (which is why it is useful for debugging)You can use cat to check this.  If it is 1, then your kernel is enforcing this rule.  There are two ways to get around this.  Run the process that is examining memory as root, or disable the rule (set ptrace_scope to 0).  We will run our process as root which would make this a bit harder to weaponize, because you would have to get root in order to make our script work.  If the value of ptrace_scope is 2, that means that only users with administrative rights can invoke ptrace.  If the value of ptrace_scope is 3, attaching to processes using ptrace is completely disabled.  Get more info here.

For our purposes, we will be looking at dynamically allocated sections of memory (the heap and the stack).  From my testing, it appears that you do not need to use ptrace to examine those sections of memory.  You just need to be root when doing it (even for your own processes) and you need to know where to look.  Luckily, the memory maps we discussed above do just that.

Next time we will see if we can find some interesting things in memory with what we talked about in this post.  What are your thoughts so far?  Please let me know.  Thanks for reading!

No comments:

Post a Comment