on
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.