I previously released a Python module, fuzzybit, that can be used to inspect the bit-level entropy of an observed history of values.

I am now open-sourcing some example code I wrote for examining the section load address entropy. The example code can be found in the examples/vmmap_entropy directory of the fuzzybit source.

The example code has the following files:

  • calc_vmmap_entropy.py: Python script that runs a script a given number of iterations to examine entropy
  • entropy-test.gdb: GDB commands that will cause a program to break, print section mappings, and exit (requires PEDA)
  • get_vmmap_values.sh: Runs given binary under GDB and prints memory mappings

Running the bash script prints out memory mappings:

$ ./get_vmmap_values.sh /bin/ls
0x00400000         0x0041a000         r-xp  /bin/ls
0x00619000         0x0061a000         r--p  /bin/ls
0x0061a000         0x0061b000         rw-p  /bin/ls
0x0061b000         0x0061c000         rw-p  mapped
0x02074000         0x02095000         rw-p  [heap]
0x00007f7e0065d000 0x00007f7e00661000 r-xp  /lib/x86_64-linux-gnu/libattr.so.1.1.0
0x00007f7e00661000 0x00007f7e00860000 ---p  /lib/x86_64-linux-gnu/libattr.so.1.1.0
0x00007f7e00860000 0x00007f7e00861000 r--p  /lib/x86_64-linux-gnu/libattr.so.1.1.0
0x00007f7e00861000 0x00007f7e00862000 rw-p  /lib/x86_64-linux-gnu/libattr.so.1.1.0
0x00007f7e00862000 0x00007f7e00865000 r-xp  /lib/x86_64-linux-gnu/libdl-2.19.so
0x00007f7e00865000 0x00007f7e00a64000 ---p  /lib/x86_64-linux-gnu/libdl-2.19.so
0x00007f7e00a64000 0x00007f7e00a65000 r--p  /lib/x86_64-linux-gnu/libdl-2.19.so
0x00007f7e00a65000 0x00007f7e00a66000 rw-p  /lib/x86_64-linux-gnu/libdl-2.19.so
0x00007f7e00a66000 0x00007f7e00aa3000 r-xp  /lib/x86_64-linux-gnu/libpcre.so.3.13.1
0x00007f7e00aa3000 0x00007f7e00ca2000 ---p  /lib/x86_64-linux-gnu/libpcre.so.3.13.1
0x00007f7e00ca2000 0x00007f7e00ca3000 r--p  /lib/x86_64-linux-gnu/libpcre.so.3.13.1
0x00007f7e00ca3000 0x00007f7e00ca4000 rw-p  /lib/x86_64-linux-gnu/libpcre.so.3.13.1
0x00007f7e00ca4000 0x00007f7e00e5e000 r-xp  /lib/x86_64-linux-gnu/libc-2.19.so
0x00007f7e00e5e000 0x00007f7e0105e000 ---p  /lib/x86_64-linux-gnu/libc-2.19.so
0x00007f7e0105e000 0x00007f7e01062000 r--p  /lib/x86_64-linux-gnu/libc-2.19.so
0x00007f7e01062000 0x00007f7e01064000 rw-p  /lib/x86_64-linux-gnu/libc-2.19.so
0x00007f7e01064000 0x00007f7e01069000 rw-p  mapped
0x00007f7e01069000 0x00007f7e01070000 r-xp  /lib/x86_64-linux-gnu/libacl.so.1.1.0
0x00007f7e01070000 0x00007f7e0126f000 ---p  /lib/x86_64-linux-gnu/libacl.so.1.1.0
0x00007f7e0126f000 0x00007f7e01270000 r--p  /lib/x86_64-linux-gnu/libacl.so.1.1.0
0x00007f7e01270000 0x00007f7e01271000 rw-p  /lib/x86_64-linux-gnu/libacl.so.1.1.0
0x00007f7e01271000 0x00007f7e01291000 r-xp  /lib/x86_64-linux-gnu/libselinux.so.1
0x00007f7e01291000 0x00007f7e01490000 ---p  /lib/x86_64-linux-gnu/libselinux.so.1
0x00007f7e01490000 0x00007f7e01491000 r--p  /lib/x86_64-linux-gnu/libselinux.so.1
0x00007f7e01491000 0x00007f7e01492000 rw-p  /lib/x86_64-linux-gnu/libselinux.so.1
0x00007f7e01492000 0x00007f7e01494000 rw-p  mapped
0x00007f7e01494000 0x00007f7e014b7000 r-xp  /lib/x86_64-linux-gnu/ld-2.19.so
0x00007f7e0167e000 0x00007f7e01683000 rw-p  mapped
0x00007f7e016b4000 0x00007f7e016b6000 rw-p  mapped
0x00007f7e016b6000 0x00007f7e016b7000 r--p  /lib/x86_64-linux-gnu/ld-2.19.so
0x00007f7e016b7000 0x00007f7e016b8000 rw-p  /lib/x86_64-linux-gnu/ld-2.19.so
0x00007f7e016b8000 0x00007f7e016b9000 rw-p  mapped
0x00007ffcf33ed000 0x00007ffcf340e000 rw-p  [stack]
0x00007ffcf3507000 0x00007ffcf3509000 r-xp  [vdso]
0xffffffffff600000 0xffffffffff601000 r-xp  [vsyscall]

The Python script takes in the number of iterations and a command that prints the mappings in the format shown above. The script prints the entropy of the start and end addresses. All of the bits of the addresses are shown (most significant bits first). The entropy (sum of unknown bits) is shown in the line underneath. For each bit position, the values 0/1 are concrete (this bit was always observed to have this value) and * means that both 0 and 1 values have been observed.

Here’s an example of the entropy of /bin/ls on Ubuntu 14.04 amd64:

$ ./calc_vmmap_entropy.py -i 10 -b 64 ./get_vmmap_values.sh /bin/ls
0000000000000000000000000000000000000000010000000000000000000000 -> 0000000000000000000000000000000000000000010000011010000000000000  r-xp /bin/ls
    entropy: 0, 0 bits
0000000000000000000000000000000000000000011000011001000000000000 -> 0000000000000000000000000000000000000000011000011010000000000000  r--p /bin/ls
    entropy: 0, 0 bits
0000000000000000000000000000000000000000011000011010000000000000 -> 0000000000000000000000000000000000000000011000011011000000000000  rw-p /bin/ls
    entropy: 0, 0 bits
0000000000000000000000000000000000000000011000011011000000000000 -> 0000000000000000000000000000000000000000011000011100000000000000  rw-p mapped
    entropy: 0, 0 bits
00000000000000000000000000000000000000**************000000000000 -> 00000000000000000000000000000000000000**************000000000000  rw-p [heap]
    entropy: 14, 14 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libattr.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libattr.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libattr.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libattr.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libdl-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libdl-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libdl-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libdl-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libpcre.so.3.13.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libpcre.so.3.13.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libpcre.so.3.13.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libpcre.so.3.13.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libc-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libc-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libc-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libc-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p mapped
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libacl.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libacl.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libacl.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libacl.so.1.1.0
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/libselinux.so.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  ---p /lib/x86_64-linux-gnu/libselinux.so.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/libselinux.so.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/libselinux.so.1
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p mapped
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r-xp /lib/x86_64-linux-gnu/ld-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p mapped
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p mapped
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  r--p /lib/x86_64-linux-gnu/ld-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p /lib/x86_64-linux-gnu/ld-2.19.so
    entropy: 28, 28 bits
000000000000000001111111****************************000000000000 -> 000000000000000001111111****************************000000000000  rw-p mapped
    entropy: 28, 28 bits
000000000000000001111111111111**********************000000000000 -> 000000000000000001111111111111**********************000000000000  rw-p [stack]
    entropy: 22, 22 bits
000000000000000001111111111111*************1********000000000000 -> 000000000000000001111111111111*************1********000000000000  r-xp [vdso]
    entropy: 21, 21 bits
1111111111111111111111111111111111111111011000000000000000000000 -> 1111111111111111111111111111111111111111011000000001000000000000  r-xp [vsyscall]
    entropy: 0, 0 bits

Notice how the locations of sections from /bin/ls and [vsyscall] are not randomized at all. Also, at best, the other sections only have 28 bits of entropy, but the heap only has 14 bits of entropy.