Quickly move an executable between systems with ELF Statifier

1663

Author: Ben Martin

Shared libraries that are dynamically linked make more efficient use of disk space than those that are statically linked, and more importantly allow you to perform security updates in a more efficient manner, but executables compiled against a particular version of a dynamic library expect that version of the shared library to be available on the machine they run on. If you are running machines with both Fedora 9 and openSUSE 11, the versions of some shared libraries are likely to be slightly different, and if you copy an executable between the machines, the file might fail to execute because of these version differences. With ELF Statifier you can create a statically linked version of an executable, so the executable includes the shared libraries instead of seeking them at run time. A staticly linked executable is much more likely to run on a different Linux distribution or a different version of the same distribution.

Of course, to do this you sacrifice some disk space, because the statically linked executable includes a copy of the shared libraries that it needs, but in these days of terabyte disks the space consideration is less important than the security one. Consider what happens if your executables are dynamically linked to a shared library, say libfoo, and there is a security update to libfoo. When your applications are dynamically linked you can just update the shared copy of libfoo and your applications will no longer be vulnerable to the security issue in the older libfoo. If on the other hand you have a statically linked executable, it will still include and use its own private copy of the old libfoo. You’ll have to recreate the statically linked executable to get the newer libfoo and security update.

Still, there are times when you want to take a daemon you compiled on a Fedora machine and run it on your openSUSE machine without having to recompile it and all its dependencies. Sometimes you just want it to execute now and can rebuild it later if desired. Of course, the machine you copy the executable from and the one on which you want to run it must have the same architecture.

ELF Statifier is packaged as a 1-Click install for openSUSE 10.3 but not for Ubuntu Hardy or Fedora. I’ll use version 1.6.14 of ELF Statifier and build it from source on a Fedora 9 x86 machine. ELF Statifier does not use autotools, so you compile by simply invoking make. Compilation and installation is shown below.

$ tar xzvf statifier-1.6.14.tar.gz $ cd ./statifier-* $ make $ sudo make install

As an example of how to use the utility, I’ll create a statically linked version of the ls binary in the commands shown below. First I create a personal copy of the dynamically linked executable and inspect it to see what it dynamically links to. You run statifier with the path to the dynamically linked executable as the first argument and the path where you want to create the statically linked executable as the second argument. Notice that the ldd command reports that no dynamically linked libraries are required by ls-static. The next command shows that the binary size has grown significantly for the static version of ls.

$ mkdir test $ cd ./test $ cp -a /bin/ls ls-dynamic $ ls -lh -rwxr-xr-x 1 ben ben 112K 2008-08-01 04:05 ls-dynamic $ ldd ls-dynamic linux-gate.so.1 => (0x00110000) librt.so.1 => /lib/librt.so.1 (0x00a3a000) libselinux.so.1 => /lib/libselinux.so.1 (0x00a06000) libacl.so.1 => /lib/libacl.so.1 (0x00d8a000) libc.so.6 => /lib/libc.so.6 (0x0084e000) libpthread.so.0 => /lib/libpthread.so.0 (0x009eb000) /lib/ld-linux.so.2 (0x0082e000) libdl.so.2 => /lib/libdl.so.2 (0x009e4000) libattr.so.1 => /lib/libattr.so.1 (0x0606d000) $ statifier ls-dynamic ls-static $ ldd ls-static not a dynamic executable $ ls -lh ls-static -rwxr-x--- 1 ben ben 2.0M 2008-10-03 12:05 ls-static $ ls-static /tmp ... $ ls-static -lh Segmentation fault

As you can see above, the statified ls crashes when you run it with the -l option. If you get segmentation faults when running your statified executables you should disable stack randomization and recreate the statified executable. The stack and address space randomization feature of the Linux kernel makes the locations used for the stack and other important parts of an executable change every time it is executed. Randomizing things each time you run a binary hinders attacks such as the return-to-libc attack because the location of libc functions changes all the time.

You are giving away some security by changing the randomize_va_space parameter as shown below. The change to randomize_va_space affects not only attacks on the executables themselves but also exploit attempts that rely on buffer overflows to compromise the system. Without randomization, both attacks become more straightforward. If you set randomize_va_space to zero as shown below and recreate the ls-static binary, things should work as expected. You’ll have to leave the stack randomization feature disabled in order to execute the statified executable.

# cd /proc/sys/kernel # cat randomize_va_space 2 # echo -n 0 >| randomize_va_space # cat randomize_va_space 0

There are a few other tricks up statifier’s sleeve: you can set or unset environment variables for the statified executable, and include additional libraries (LD_PRELOAD libraries) into the static executable. Being able to set additional environment variables for a static executable is useful when the binary you are statifying relies on finding additional resources like configuration files. If the binary allows you to tell it where to find its resources through environment variables, you can include these settings directly into the statified executable.

The ability to include preloaded shared libraries into the statified binary (LD_PRELOADing) is probably a less commonly used feature. One use is including additional functionality such as making the statically linked executable “trashcan friendly” by default, perhaps using delsafe, but without needing to install any additional software on the machine that is running the statically linked executable.

Security measures that randomize the address space of binaries might interfere with ELF Statifier and cause it not to work. But when you just want to move the execution of an application to another Linux machine, ELF Statifier might get you up and running without the hassle of a recompile.

Categories:

  • System Administration
  • Tools & Utilities