Less known, but frequently used Solaris feature: Address space layout randomisation

One of the features introduced with 11.1 is the Address Space Layout Randomization (ASLR) . And when you work with 11.1 you are already using it. So it’s a less known, but frequently used feature: less known in the point that it exists, less known in the point of the methods to control it, frequently used as it’s activated per default for selected binaries (and many were selected)

Address Space Layout Randomization?

Simply said? The basic idea behind ASLR that it’s harder to make assumptions about the address space layout when the layout is randomised. Such assumptions are necessary when you want to use certain attack vectors. As the Wikipedia explains:

Address space layout randomization (ASLR) is a computer security method which involves randomly arranging the positions of key data areas, usually including the base of the executable and position of libraries, heap, and stack, in a process's address space.
[..]
Address space randomization hinders some types of security attacks by making it more difficult for an attacker to predict target addresses. For example, attackers trying to execute return-to-libc attacks must locate the code to be executed, while other attackers trying to execute shellcode injected on the stack have to find the stack first. In both cases, the system obscures related memory-addresses from the attackers. These values have to be guessed, and a mistaken guess is not usually recoverable due to the application crashing.

With Solaris 11.1 ASLR is available in Solaris as well.

How to control it in Solaris

In order to control directly on the command line if a binary uses ALSR or not at the start of the binary, you can use the sxadm exec command. Let us use pmap itself to show the memory layout of the process. We will start with disabled ASLR.

root@solaris:/# sxadm exec -s aslr=disable /usr/bin/pmap self
1914:   /usr/bin/pmap self
1914:   /usr/bin/pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000         40K rw---    [ heap ]
FFFF80FFBDDD0000        216K r-x--  /lib/amd64/libproc.so.1
FFFF80FFBDE16000          8K rw---  /lib/amd64/libproc.so.1
FFFF80FFBF430000       1764K r-x--  /lib/amd64/libc.so.1
FFFF80FFBF5F9000         64K rw---  /lib/amd64/libc.so.1
FFFF80FFBF609000         12K rw---  /lib/amd64/libc.so.1
FFFF80FFBF740000          4K rw---    [ anon ]
FFFF80FFBF750000         24K rwx--    [ anon ]
FFFF80FFBF760000          4K rw---    [ anon ]
FFFF80FFBF770000          4K rw---    [ anon ]
FFFF80FFBF780000          4K rw---    [ anon ]
FFFF80FFBF790000          4K rw---    [ anon ]
FFFF80FFBF792000          4K r--s-    [ anon ]
FFFF80FFBF795000        340K r-x--  /lib/amd64/ld.so.1
FFFF80FFBF7FA000         12K rwx--  /lib/amd64/ld.so.1
FFFF80FFBF7FD000          8K rwx--  /lib/amd64/ld.so.1
FFFF80FFBFFFD000         12K rw---    [ stack ]
         total         2556K

When try this a second time you will see, that the address space layout is absolutely the same.

root@solaris:/# sxadm exec -s aslr=disable /usr/bin/pmap self
1915:   /usr/bin/pmap self
1915:   /usr/bin/pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000         40K rw---    [ heap ]
FFFF80FFBDDD0000        216K r-x--  /lib/amd64/libproc.so.1
FFFF80FFBDE16000          8K rw---  /lib/amd64/libproc.so.1
FFFF80FFBF430000       1764K r-x--  /lib/amd64/libc.so.1
FFFF80FFBF5F9000         64K rw---  /lib/amd64/libc.so.1
FFFF80FFBF609000         12K rw---  /lib/amd64/libc.so.1
FFFF80FFBF740000          4K rw---    [ anon ]
FFFF80FFBF750000         24K rwx--    [ anon ]
FFFF80FFBF760000          4K rw---    [ anon ]
FFFF80FFBF770000          4K rw---    [ anon ]
FFFF80FFBF780000          4K rw---    [ anon ]
FFFF80FFBF790000          4K rw---    [ anon ]
FFFF80FFBF792000          4K r--s-    [ anon ]
FFFF80FFBF795000        340K r-x--  /lib/amd64/ld.so.1
FFFF80FFBF7FA000         12K rwx--  /lib/amd64/ld.so.1
FFFF80FFBF7FD000          8K rwx--  /lib/amd64/ld.so.1
FFFF80FFBFFFD000         12K rw---    [ stack ]
         total         2556K

Now we try the same with enabled ASLR.

root@solaris:/# sxadm exec -s aslr=enable /usr/bin/pmap self
1917:   /usr/bin/pmap self
1917:   /usr/bin/pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000          8K rw---  /usr/bin/pmap
00000005D6666000         36K rw---    [ heap ]
00007FF669C70000        216K r-x--  /lib/amd64/libproc.so.1
00007FF669CB6000          8K rw---  /lib/amd64/libproc.so.1
00007FF669CC0000          4K rw---    [ anon ]
00007FF669CD0000         24K rwx--    [ anon ]
00007FF669CE0000          4K rw---    [ anon ]
00007FF669CF0000       1764K r-x--  /lib/amd64/libc.so.1
00007FF669EB9000         64K rw---  /lib/amd64/libc.so.1
00007FF669EC9000         12K rw---  /lib/amd64/libc.so.1
00007FF669ED0000          4K rw---    [ anon ]
00007FF669EE0000          4K rw---    [ anon ]
00007FF669EF0000          4K rw---    [ anon ]
00007FF669EF2000          4K r--s-    [ anon ]
00007FF669EFC000        340K r-x--  /lib/amd64/ld.so.1
00007FF669F61000         12K rwx--  /lib/amd64/ld.so.1
00007FF669F64000          8K rwx--  /lib/amd64/ld.so.1
FFFF80DDA254F000         16K rw---    [ stack ]
         total         2564K

Okay, a second time again:

root@solaris:/# sxadm exec -s aslr=enable /usr/bin/pmap self
1918:   /usr/bin/pmap self
1918:   /usr/bin/pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000          8K rw---  /usr/bin/pmap
000000065B76D000         36K rw---    [ heap ]
00007FFAACFC0000        216K r-x--  /lib/amd64/libproc.so.1
00007FFAAD006000          8K rw---  /lib/amd64/libproc.so.1
00007FFAAD010000          4K rw---    [ anon ]
00007FFAAD020000         24K rwx--    [ anon ]
00007FFAAD030000          4K rw---    [ anon ]
00007FFAAD040000       1764K r-x--  /lib/amd64/libc.so.1
00007FFAAD209000         64K rw---  /lib/amd64/libc.so.1
00007FFAAD219000         12K rw---  /lib/amd64/libc.so.1
00007FFAAD220000          4K rw---    [ anon ]
00007FFAAD230000          4K rw---    [ anon ]
00007FFAAD240000          4K rw---    [ anon ]
00007FFAAD242000          4K r--s-    [ anon ]
00007FFAAD24D000        340K r-x--  /lib/amd64/ld.so.1
00007FFAAD2B2000         12K rwx--  /lib/amd64/ld.so.1
00007FFAAD2B5000          8K rwx--  /lib/amd64/ld.so.1
FFFF80DE1559E000         12K rw---    [ stack ]

As you have surely noticed, the layout is different now with every run of the application. I told you, that you are already using ASLR. It’s controlled by a setting inside the system. You can check it with sxadm info

root@solaris:/# sxadm info
EXTENSION        STATUS                   CONFIGURATION
aslr             enabled (tagged-files)   system default (default)

Okay, it’s enabled for tagged files. Tagged files? The binaries contain a flag that tells the system to use ASLR or not, when the security extension is enabled for tagged files. You can lookup this flag with elfdump tool.

root@solaris:/# elfdump -d /usr/bin/pmap | grep "ASLR"
      [33]  SUNW_ASLR         0x2                 ENABLE

Currently it’s enabled and thus pmap is using ASLR as long as the general status of the extension is enabled (tagged-files). Now we disable it. When you want such kind of information in the header of a binary, you have to use the elfedit tool.

root@solaris:/# elfedit -e 'dyn:sunw_aslr disable' /usr/bin/pmap

Running the elfdump tool again, you will see the successful change of value:

root@solaris:/# elfdump -d /usr/bin/pmap | grep "ASLR"
      [33]  SUNW_ASLR         0x1                 DISABLE

The next step is to check the result of this change. Please notice that you don’t use the sxadm command.

root@solaris:/# pmap self
1947:   pmap self
1947:   pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000         40K rw---    [ heap ]
FFFF80FFBDDD0000        216K r-x--  /lib/amd64/libproc.so.1
FFFF80FFBDE16000          8K rw---  /lib/amd64/libproc.so.1
FFFF80FFBF430000       1764K r-x--  /lib/amd64/libc.so.1
FFFF80FFBF5F9000         64K rw---  /lib/amd64/libc.so.1
FFFF80FFBF609000         12K rw---  /lib/amd64/libc.so.1
FFFF80FFBF740000          4K rw---    [ anon ]
FFFF80FFBF750000         24K rwx--    [ anon ]
FFFF80FFBF760000          4K rw---    [ anon ]
FFFF80FFBF770000          4K rw---    [ anon ]
FFFF80FFBF780000          4K rw---    [ anon ]
FFFF80FFBF790000          4K rw---    [ anon ]
FFFF80FFBF792000          4K r--s-    [ anon ]
FFFF80FFBF795000        340K r-x--  /lib/amd64/ld.so.1
FFFF80FFBF7FA000         12K rwx--  /lib/amd64/ld.so.1
FFFF80FFBF7FD000          8K rwx--  /lib/amd64/ld.so.1
FFFF80FFBFFFD000         12K rw---    [ stack ]
         total         2556K
root@solaris:/# pmap self
1948:   pmap self
1948:   pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000         40K rw---    [ heap ]
FFFF80FFBDDD0000        216K r-x--  /lib/amd64/libproc.so.1
FFFF80FFBDE16000          8K rw---  /lib/amd64/libproc.so.1
FFFF80FFBF430000       1764K r-x--  /lib/amd64/libc.so.1
FFFF80FFBF5F9000         64K rw---  /lib/amd64/libc.so.1
FFFF80FFBF609000         12K rw---  /lib/amd64/libc.so.1
FFFF80FFBF740000          4K rw---    [ anon ]
FFFF80FFBF750000         24K rwx--    [ anon ]
FFFF80FFBF760000          4K rw---    [ anon ]
FFFF80FFBF770000          4K rw---    [ anon ]
FFFF80FFBF780000          4K rw---    [ anon ]
FFFF80FFBF790000          4K rw---    [ anon ]
FFFF80FFBF792000          4K r--s-    [ anon ]
FFFF80FFBF795000        340K r-x--  /lib/amd64/ld.so.1
FFFF80FFBF7FA000         12K rwx--  /lib/amd64/ld.so.1
FFFF80FFBF7FD000          8K rwx--  /lib/amd64/ld.so.1
FFFF80FFBFFFD000         12K rw---    [ stack ]
         total         2556K

No randomization. Now we change the tag in the binary again:

root@solaris:/# elfedit -e 'dyn:sunw_aslr enable' /usr/bin/pmap

Short check.

root@solaris:/# pmap self
1944:   pmap self
1944:   pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000          8K rw---  /usr/bin/pmap
00000000EFEFE000         36K rw---    [ heap ]
00007FF24F040000        216K r-x--  /lib/amd64/libproc.so.1
00007FF24F086000          8K rw---  /lib/amd64/libproc.so.1
00007FF24F090000          4K rw---    [ anon ]
00007FF24F0A0000         24K rwx--    [ anon ]
00007FF24F0B0000          4K rw---    [ anon ]
00007FF24F0C0000       1764K r-x--  /lib/amd64/libc.so.1
00007FF24F289000         64K rw---  /lib/amd64/libc.so.1
00007FF24F299000         12K rw---  /lib/amd64/libc.so.1
00007FF24F2A0000          4K rw---    [ anon ]
00007FF24F2B0000          4K rw---    [ anon ]
00007FF24F2C0000          4K rw---    [ anon ]
00007FF24F2C2000          4K r--s-    [ anon ]
00007FF24F2D0000        340K r-x--  /lib/amd64/ld.so.1
00007FF24F335000         12K rwx--  /lib/amd64/ld.so.1
00007FF24F338000          8K rwx--  /lib/amd64/ld.so.1
FFFF80CB39092000         12K rw---    [ stack ]
         total         2560K
root@solaris:/# pmap self
1945:   pmap self
1945:   pmap self
0000000000400000         28K r-x--  /usr/bin/pmap
0000000000417000          4K rw---  /usr/bin/pmap
0000000000418000          8K rw---  /usr/bin/pmap
0000000413520000         36K rw---    [ heap ]
00007FF2EE730000        216K r-x--  /lib/amd64/libproc.so.1
00007FF2EE776000          8K rw---  /lib/amd64/libproc.so.1
00007FF2EE780000          4K rw---    [ anon ]
00007FF2EE790000         24K rwx--    [ anon ]
00007FF2EE7A0000          4K rw---    [ anon ]
00007FF2EE7B0000       1764K r-x--  /lib/amd64/libc.so.1
00007FF2EE979000         64K rw---  /lib/amd64/libc.so.1
00007FF2EE989000         12K rw---  /lib/amd64/libc.so.1
00007FF2EE990000          4K rw---    [ anon ]
00007FF2EE9A0000          4K rw---    [ anon ]
00007FF2EE9B0000          4K rw---    [ anon ]
00007FF2EE9B2000          4K r--s-    [ anon ]
00007FF2EE9BF000        340K r-x--  /lib/amd64/ld.so.1
00007FF2EEA24000         12K rwx--  /lib/amd64/ld.so.1
00007FF2EEA27000          8K rwx--  /lib/amd64/ld.so.1
FFFF80EFAD413000         12K rw---    [ stack ]
         total         2560K

As you see, randomization is back.

How to change the default behaviour

The next obvious question is how to change the default behaviour. When you want to change it to “ASLR for all”, then you ca do it this way

root@solaris:/# sxadm enable -c model=all aslr
root@solaris:/# sxadm info
EXTENSION        STATUS                   CONFIGURATION
aslr             enabled (all)            enabled (all)

There is no model=off, you disable it in order to ensure that no

root@solaris:/# sxadm disable aslr
root@solaris:/# sxadm info
EXTENSION        STATUS                   CONFIGURATION
aslr             disabled                 disabled

In oder to set it back to the default state, you use this command:

root@solaris:/# sxadm enable -c model=tagged-files aslr
root@solaris:/# sxadm info
EXTENSION        STATUS                   CONFIGURATION
aslr             enabled (tagged-files)   enabled (tagged-files)

This default is valid for the zone where you have done this configuration.

Do you want to learn more